Merge remote-tracking branch 'spi/for-5.14' into spi-next
[linux-2.6-microblaze.git] / tools / testing / selftests / kvm / x86_64 / get_msr_index_features.c
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_or_exit();
41
42         old_res = kvm_num_index_msrs(kvm_fd, 0);
43         TEST_ASSERT(old_res != 0, "Expecting nmsrs to be > 0");
44
45         if (old_res != 1) {
46                 res = kvm_num_index_msrs(kvm_fd, 1);
47                 TEST_ASSERT(res > 1, "Expecting nmsrs to be > 1");
48                 TEST_ASSERT(res == old_res, "Expecting nmsrs to be identical");
49         }
50
51         list = malloc(sizeof(*list) + old_res * sizeof(list->indices[0]));
52         list->nmsrs = old_res;
53         r = ioctl(kvm_fd, KVM_GET_MSR_INDEX_LIST, list);
54
55         TEST_ASSERT(r == 0,
56                     "Unexpected result from KVM_GET_MSR_FEATURE_INDEX_LIST, r: %i",
57                     r);
58         TEST_ASSERT(list->nmsrs == old_res, "Expecting nmsrs to be identical");
59         free(list);
60
61         close(kvm_fd);
62 }
63
64 static int kvm_num_feature_msrs(int kvm_fd, int nmsrs)
65 {
66         struct kvm_msr_list *list;
67         int r;
68
69         list = malloc(sizeof(*list) + nmsrs * sizeof(list->indices[0]));
70         list->nmsrs = nmsrs;
71         r = ioctl(kvm_fd, KVM_GET_MSR_FEATURE_INDEX_LIST, list);
72         TEST_ASSERT(r == -1 && errno == E2BIG,
73                 "Unexpected result from KVM_GET_MSR_FEATURE_INDEX_LIST probe, r: %i",
74                                 r);
75
76         r = list->nmsrs;
77         free(list);
78         return r;
79 }
80
81 struct kvm_msr_list *kvm_get_msr_feature_list(int kvm_fd, int nmsrs)
82 {
83         struct kvm_msr_list *list;
84         int r;
85
86         list = malloc(sizeof(*list) + nmsrs * sizeof(list->indices[0]));
87         list->nmsrs = nmsrs;
88         r = ioctl(kvm_fd, KVM_GET_MSR_FEATURE_INDEX_LIST, list);
89
90         TEST_ASSERT(r == 0,
91                 "Unexpected result from KVM_GET_MSR_FEATURE_INDEX_LIST, r: %i",
92                 r);
93
94         return list;
95 }
96
97 static void test_get_msr_feature(void)
98 {
99         int res, old_res, i, kvm_fd;
100         struct kvm_msr_list *feature_list;
101
102         kvm_fd = open_kvm_dev_path_or_exit();
103
104         old_res = kvm_num_feature_msrs(kvm_fd, 0);
105         TEST_ASSERT(old_res != 0, "Expecting nmsrs to be > 0");
106
107         if (old_res != 1) {
108                 res = kvm_num_feature_msrs(kvm_fd, 1);
109                 TEST_ASSERT(res > 1, "Expecting nmsrs to be > 1");
110                 TEST_ASSERT(res == old_res, "Expecting nmsrs to be identical");
111         }
112
113         feature_list = kvm_get_msr_feature_list(kvm_fd, old_res);
114         TEST_ASSERT(old_res == feature_list->nmsrs,
115                                 "Unmatching number of msr indexes");
116
117         for (i = 0; i < feature_list->nmsrs; i++)
118                 kvm_get_feature_msr(feature_list->indices[i]);
119
120         free(feature_list);
121         close(kvm_fd);
122 }
123
124 int main(int argc, char *argv[])
125 {
126         if (kvm_check_cap(KVM_CAP_GET_MSR_FEATURES))
127                 test_get_msr_feature();
128
129         test_get_msr_index();
130 }