KVM: selftests: Print a message if /dev/kvm is missing
authorDavid Matlack <dmatlack@google.com>
Tue, 11 May 2021 20:21:20 +0000 (20:21 +0000)
committerPaolo Bonzini <pbonzini@redhat.com>
Thu, 27 May 2021 11:45:55 +0000 (07:45 -0400)
If a KVM selftest is run on a machine without /dev/kvm, it will exit
silently. Make it easy to tell what's happening by printing an error
message.

Opportunistically consolidate all codepaths that open /dev/kvm into a
single function so they all print the same message.

This slightly changes the semantics of vm_is_unrestricted_guest() by
changing a TEST_ASSERT() to exit(KSFT_SKIP). However
vm_is_unrestricted_guest() is only called in one place
(x86_64/mmio_warning_test.c) and that is to determine if the test should
be skipped or not.

Signed-off-by: David Matlack <dmatlack@google.com>
Message-Id: <20210511202120.1371800-1-dmatlack@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
tools/testing/selftests/kvm/include/kvm_util.h
tools/testing/selftests/kvm/lib/kvm_util.c
tools/testing/selftests/kvm/lib/x86_64/processor.c
tools/testing/selftests/kvm/x86_64/get_msr_index_features.c

index 2e0d253..5d9b35d 100644 (file)
@@ -77,6 +77,7 @@ struct vm_guest_mode_params {
 };
 extern const struct vm_guest_mode_params vm_guest_mode_params[];
 
+int open_kvm_dev_path_or_exit(void);
 int kvm_check_cap(long cap);
 int vm_enable_cap(struct kvm_vm *vm, struct kvm_enable_cap *cap);
 int vcpu_enable_cap(struct kvm_vm *vm, uint32_t vcpu_id,
index f4484e1..d00e49b 100644 (file)
@@ -32,6 +32,34 @@ static void *align(void *x, size_t size)
 }
 
 /*
+ * Open KVM_DEV_PATH if available, otherwise exit the entire program.
+ *
+ * Input Args:
+ *   flags - The flags to pass when opening KVM_DEV_PATH.
+ *
+ * Return:
+ *   The opened file descriptor of /dev/kvm.
+ */
+static int _open_kvm_dev_path_or_exit(int flags)
+{
+       int fd;
+
+       fd = open(KVM_DEV_PATH, flags);
+       if (fd < 0) {
+               print_skip("%s not available, is KVM loaded? (errno: %d)",
+                          KVM_DEV_PATH, errno);
+               exit(KSFT_SKIP);
+       }
+
+       return fd;
+}
+
+int open_kvm_dev_path_or_exit(void)
+{
+       return _open_kvm_dev_path_or_exit(O_RDONLY);
+}
+
+/*
  * Capability
  *
  * Input Args:
@@ -52,10 +80,7 @@ int kvm_check_cap(long cap)
        int ret;
        int kvm_fd;
 
-       kvm_fd = open(KVM_DEV_PATH, O_RDONLY);
-       if (kvm_fd < 0)
-               exit(KSFT_SKIP);
-
+       kvm_fd = open_kvm_dev_path_or_exit();
        ret = ioctl(kvm_fd, KVM_CHECK_EXTENSION, cap);
        TEST_ASSERT(ret != -1, "KVM_CHECK_EXTENSION IOCTL failed,\n"
                "  rc: %i errno: %i", ret, errno);
@@ -128,9 +153,7 @@ void vm_enable_dirty_ring(struct kvm_vm *vm, uint32_t ring_size)
 
 static void vm_open(struct kvm_vm *vm, int perm)
 {
-       vm->kvm_fd = open(KVM_DEV_PATH, perm);
-       if (vm->kvm_fd < 0)
-               exit(KSFT_SKIP);
+       vm->kvm_fd = _open_kvm_dev_path_or_exit(perm);
 
        if (!kvm_check_cap(KVM_CAP_IMMEDIATE_EXIT)) {
                print_skip("immediate_exit not available");
@@ -996,9 +1019,7 @@ static int vcpu_mmap_sz(void)
 {
        int dev_fd, ret;
 
-       dev_fd = open(KVM_DEV_PATH, O_RDONLY);
-       if (dev_fd < 0)
-               exit(KSFT_SKIP);
+       dev_fd = open_kvm_dev_path_or_exit();
 
        ret = ioctl(dev_fd, KVM_GET_VCPU_MMAP_SIZE, NULL);
        TEST_ASSERT(ret >= sizeof(struct kvm_run),
@@ -2091,10 +2112,7 @@ bool vm_is_unrestricted_guest(struct kvm_vm *vm)
 
        if (vm == NULL) {
                /* Ensure that the KVM vendor-specific module is loaded. */
-               f = fopen(KVM_DEV_PATH, "r");
-               TEST_ASSERT(f != NULL, "Error in opening KVM dev file: %d",
-                           errno);
-               fclose(f);
+               close(open_kvm_dev_path_or_exit());
        }
 
        f = fopen("/sys/module/kvm_intel/parameters/unrestricted_guest", "r");
index a8906e6..efe2350 100644 (file)
@@ -657,9 +657,7 @@ struct kvm_cpuid2 *kvm_get_supported_cpuid(void)
                return cpuid;
 
        cpuid = allocate_kvm_cpuid2();
-       kvm_fd = open(KVM_DEV_PATH, O_RDONLY);
-       if (kvm_fd < 0)
-               exit(KSFT_SKIP);
+       kvm_fd = open_kvm_dev_path_or_exit();
 
        ret = ioctl(kvm_fd, KVM_GET_SUPPORTED_CPUID, cpuid);
        TEST_ASSERT(ret == 0, "KVM_GET_SUPPORTED_CPUID failed %d %d\n",
@@ -691,9 +689,7 @@ uint64_t kvm_get_feature_msr(uint64_t msr_index)
 
        buffer.header.nmsrs = 1;
        buffer.entry.index = msr_index;
-       kvm_fd = open(KVM_DEV_PATH, O_RDONLY);
-       if (kvm_fd < 0)
-               exit(KSFT_SKIP);
+       kvm_fd = open_kvm_dev_path_or_exit();
 
        r = ioctl(kvm_fd, KVM_GET_MSRS, &buffer.header);
        TEST_ASSERT(r == 1, "KVM_GET_MSRS IOCTL failed,\n"
@@ -986,9 +982,7 @@ struct kvm_msr_list *kvm_get_msr_index_list(void)
        struct kvm_msr_list *list;
        int nmsrs, r, kvm_fd;
 
-       kvm_fd = open(KVM_DEV_PATH, O_RDONLY);
-       if (kvm_fd < 0)
-               exit(KSFT_SKIP);
+       kvm_fd = open_kvm_dev_path_or_exit();
 
        nmsrs = kvm_get_num_msrs_fd(kvm_fd);
        list = malloc(sizeof(*list) + nmsrs * sizeof(list->indices[0]));
@@ -1312,9 +1306,7 @@ struct kvm_cpuid2 *kvm_get_supported_hv_cpuid(void)
                return cpuid;
 
        cpuid = allocate_kvm_cpuid2();
-       kvm_fd = open(KVM_DEV_PATH, O_RDONLY);
-       if (kvm_fd < 0)
-               exit(KSFT_SKIP);
+       kvm_fd = open_kvm_dev_path_or_exit();
 
        ret = ioctl(kvm_fd, KVM_GET_SUPPORTED_HV_CPUID, cpuid);
        TEST_ASSERT(ret == 0, "KVM_GET_SUPPORTED_HV_CPUID failed %d %d\n",
index cb953df..8aed0db 100644 (file)
@@ -37,9 +37,7 @@ static void test_get_msr_index(void)
        int old_res, res, kvm_fd, r;
        struct kvm_msr_list *list;
 
-       kvm_fd = open(KVM_DEV_PATH, O_RDONLY);
-       if (kvm_fd < 0)
-               exit(KSFT_SKIP);
+       kvm_fd = open_kvm_dev_path_or_exit();
 
        old_res = kvm_num_index_msrs(kvm_fd, 0);
        TEST_ASSERT(old_res != 0, "Expecting nmsrs to be > 0");
@@ -101,9 +99,7 @@ static void test_get_msr_feature(void)
        int res, old_res, i, kvm_fd;
        struct kvm_msr_list *feature_list;
 
-       kvm_fd = open(KVM_DEV_PATH, O_RDONLY);
-       if (kvm_fd < 0)
-               exit(KSFT_SKIP);
+       kvm_fd = open_kvm_dev_path_or_exit();
 
        old_res = kvm_num_feature_msrs(kvm_fd, 0);
        TEST_ASSERT(old_res != 0, "Expecting nmsrs to be > 0");