xref: /kvm-unit-tests/x86/msr.c (revision 762b94763db4d8093e53e19c697bf061f93b1f97)
1 /* msr tests */
2 
3 #include "libcflat.h"
4 #include "processor.h"
5 
6 struct msr_info {
7     int index;
8     char *name;
9     struct tc {
10         int valid;
11         unsigned long long value;
12         unsigned long long expected;
13     } val_pairs[20];
14 };
15 
16 
17 #define addr_64 0x0000123456789abcULL
18 
19 struct msr_info msr_info[] =
20 {
21     { .index = 0x0000001b, .name = "MSR_IA32_APICBASE",
22       .val_pairs = {
23             { .valid = 1, .value = 0x0000000056789900, .expected = 0x0000000056789900},
24             { .valid = 1, .value = 0x0000000056789D01, .expected = 0x0000000056789D01},
25         }
26     },
27     { .index = 0x00000174, .name = "IA32_SYSENTER_CS",
28       .val_pairs = {{ .valid = 1, .value = 0x1234, .expected = 0x1234}}
29     },
30     { .index = 0x00000175, .name = "MSR_IA32_SYSENTER_ESP",
31       .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}}
32     },
33     { .index = 0x00000176, .name = "IA32_SYSENTER_EIP",
34       .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}}
35     },
36     { .index = 0x000001a0, .name = "MSR_IA32_MISC_ENABLE",
37       // reserved: 1:2, 4:6, 8:10, 13:15, 17, 19:21, 24:33, 35:63
38       .val_pairs = {{ .valid = 1, .value = 0x400c51889, .expected = 0x400c51889}}
39     },
40     { .index = 0x00000277, .name = "MSR_IA32_CR_PAT",
41       .val_pairs = {{ .valid = 1, .value = 0x07070707, .expected = 0x07070707}}
42     },
43     { .index = 0xc0000100, .name = "MSR_FS_BASE",
44       .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}}
45     },
46     { .index = 0xc0000101, .name = "MSR_GS_BASE",
47       .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}}
48     },
49     { .index = 0xc0000102, .name = "MSR_KERNEL_GS_BASE",
50       .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}}
51     },
52 #ifdef __x86_64__
53     { .index = 0xc0000080, .name = "MSR_EFER",
54       .val_pairs = {{ .valid = 1, .value = 0xD00, .expected = 0xD00}}
55     },
56 #endif
57     { .index = 0xc0000082, .name = "MSR_LSTAR",
58       .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}}
59     },
60     { .index = 0xc0000083, .name = "MSR_CSTAR",
61       .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}}
62     },
63     { .index = 0xc0000084, .name = "MSR_SYSCALL_MASK",
64       .val_pairs = {{ .valid = 1, .value = 0xffffffff, .expected = 0xffffffff}}
65     },
66 
67 //    MSR_IA32_DEBUGCTLMSR needs svm feature LBRV
68 //    MSR_VM_HSAVE_PA only AMD host
69 };
70 
71 static int find_msr_info(int msr_index)
72 {
73     int i;
74     for (i = 0; i < sizeof(msr_info)/sizeof(msr_info[0]) ; i++) {
75         if (msr_info[i].index == msr_index) {
76             return i;
77         }
78     }
79     return -1;
80 }
81 
82 
83 int nr_passed, nr_tests;
84 
85 static void report(const char *name, int passed)
86 {
87 	++nr_tests;
88 	if (passed)
89 		++nr_passed;
90 	printf("%s: %s\n", name, passed ? "PASS" : "FAIL");
91 }
92 
93 static void test_msr_rw(int msr_index, unsigned long long input, unsigned long long expected)
94 {
95     unsigned long long r = 0;
96     int index;
97     char *sptr;
98     if ((index = find_msr_info(msr_index)) != -1) {
99         sptr = msr_info[index].name;
100     } else {
101         printf("couldn't find name for msr # 0x%x, skipping\n", msr_index);
102         return;
103     }
104     wrmsr(msr_index, input);
105     r = rdmsr(msr_index);
106     if (expected != r) {
107         printf("testing %s: output = 0x%x:0x%x expected = 0x%x:0x%x\n", sptr, r >> 32, r, expected >> 32, expected);
108     }
109     report(sptr, expected == r);
110 }
111 
112 int main(int ac, char **av)
113 {
114     int i, j;
115     for (i = 0 ; i < sizeof(msr_info) / sizeof(msr_info[0]); i++) {
116         for (j = 0; j < sizeof(msr_info[i].val_pairs) / sizeof(msr_info[i].val_pairs[0]); j++) {
117             if (msr_info[i].val_pairs[j].valid) {
118                 test_msr_rw(msr_info[i].index, msr_info[i].val_pairs[j].value, msr_info[i].val_pairs[j].expected);
119             } else {
120                 break;
121             }
122         }
123     }
124 
125     printf("%d tests, %d failures\n", nr_tests, nr_tests - nr_passed);
126 
127     return nr_passed == nr_tests ? 0 : 1;
128 }
129 
130