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