1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Test that KVM_GET_MSR_INDEX_LIST and 4 * KVM_GET_MSR_FEATURE_INDEX_LIST work as intended 5 * 6 * Copyright (C) 2020, Red Hat, Inc. 7 */ 8 #include <fcntl.h> 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <string.h> 12 #include <sys/ioctl.h> 13 14 #include "test_util.h" 15 #include "kvm_util.h" 16 #include "processor.h" 17 18 static int kvm_num_index_msrs(int kvm_fd, int nmsrs) 19 { 20 struct kvm_msr_list *list; 21 int r; 22 23 list = malloc(sizeof(*list) + nmsrs * sizeof(list->indices[0])); 24 list->nmsrs = nmsrs; 25 r = ioctl(kvm_fd, KVM_GET_MSR_INDEX_LIST, list); 26 TEST_ASSERT(r == -1 && errno == E2BIG, 27 "Unexpected result from KVM_GET_MSR_INDEX_LIST probe, r: %i", 28 r); 29 30 r = list->nmsrs; 31 free(list); 32 return r; 33 } 34 35 static void test_get_msr_index(void) 36 { 37 int old_res, res, kvm_fd, r; 38 struct kvm_msr_list *list; 39 40 kvm_fd = open(KVM_DEV_PATH, O_RDONLY); 41 if (kvm_fd < 0) 42 exit(KSFT_SKIP); 43 44 old_res = kvm_num_index_msrs(kvm_fd, 0); 45 TEST_ASSERT(old_res != 0, "Expecting nmsrs to be > 0"); 46 47 if (old_res != 1) { 48 res = kvm_num_index_msrs(kvm_fd, 1); 49 TEST_ASSERT(res > 1, "Expecting nmsrs to be > 1"); 50 TEST_ASSERT(res == old_res, "Expecting nmsrs to be identical"); 51 } 52 53 list = malloc(sizeof(*list) + old_res * sizeof(list->indices[0])); 54 list->nmsrs = old_res; 55 r = ioctl(kvm_fd, KVM_GET_MSR_INDEX_LIST, list); 56 57 TEST_ASSERT(r == 0, 58 "Unexpected result from KVM_GET_MSR_FEATURE_INDEX_LIST, r: %i", 59 r); 60 TEST_ASSERT(list->nmsrs == old_res, "Expecting nmsrs to be identical"); 61 free(list); 62 63 close(kvm_fd); 64 } 65 66 static int kvm_num_feature_msrs(int kvm_fd, int nmsrs) 67 { 68 struct kvm_msr_list *list; 69 int r; 70 71 list = malloc(sizeof(*list) + nmsrs * sizeof(list->indices[0])); 72 list->nmsrs = nmsrs; 73 r = ioctl(kvm_fd, KVM_GET_MSR_FEATURE_INDEX_LIST, list); 74 TEST_ASSERT(r == -1 && errno == E2BIG, 75 "Unexpected result from KVM_GET_MSR_FEATURE_INDEX_LIST probe, r: %i", 76 r); 77 78 r = list->nmsrs; 79 free(list); 80 return r; 81 } 82 83 struct kvm_msr_list *kvm_get_msr_feature_list(int kvm_fd, int nmsrs) 84 { 85 struct kvm_msr_list *list; 86 int r; 87 88 list = malloc(sizeof(*list) + nmsrs * sizeof(list->indices[0])); 89 list->nmsrs = nmsrs; 90 r = ioctl(kvm_fd, KVM_GET_MSR_FEATURE_INDEX_LIST, list); 91 92 TEST_ASSERT(r == 0, 93 "Unexpected result from KVM_GET_MSR_FEATURE_INDEX_LIST, r: %i", 94 r); 95 96 return list; 97 } 98 99 static void test_get_msr_feature(void) 100 { 101 int res, old_res, i, kvm_fd; 102 struct kvm_msr_list *feature_list; 103 104 kvm_fd = open(KVM_DEV_PATH, O_RDONLY); 105 if (kvm_fd < 0) 106 exit(KSFT_SKIP); 107 108 old_res = kvm_num_feature_msrs(kvm_fd, 0); 109 TEST_ASSERT(old_res != 0, "Expecting nmsrs to be > 0"); 110 111 if (old_res != 1) { 112 res = kvm_num_feature_msrs(kvm_fd, 1); 113 TEST_ASSERT(res > 1, "Expecting nmsrs to be > 1"); 114 TEST_ASSERT(res == old_res, "Expecting nmsrs to be identical"); 115 } 116 117 feature_list = kvm_get_msr_feature_list(kvm_fd, old_res); 118 TEST_ASSERT(old_res == feature_list->nmsrs, 119 "Unmatching number of msr indexes"); 120 121 for (i = 0; i < feature_list->nmsrs; i++) 122 kvm_get_feature_msr(feature_list->indices[i]); 123 124 free(feature_list); 125 close(kvm_fd); 126 } 127 128 int main(int argc, char *argv[]) 129 { 130 if (kvm_check_cap(KVM_CAP_GET_MSR_FEATURES)) 131 test_get_msr_feature(); 132 133 test_get_msr_index(); 134 } 135