1 #include "libcflat.h"
2 #include "apic.h"
3 #include "processor.h"
4 #include "msr.h"
5 #include "x86/vm.h"
6 #include "asm/setup.h"
7
8 #ifdef __x86_64__
9 enum TEST_REGISTER {
10 TEST_REGISTER_GDTR_BASE,
11 TEST_REGISTER_IDTR_BASE,
12 TEST_REGISTER_TR_BASE,
13 TEST_REGISTER_LDT_BASE,
14 TEST_REGISTER_MSR /* upper 32 bits = msr address */
15 };
16
get_test_register_value(u64 test_register)17 static u64 get_test_register_value(u64 test_register)
18 {
19 struct descriptor_table_ptr dt_ptr;
20 u32 msr = test_register >> 32;
21
22 /*
23 * Note: value for LDT and TSS base might not reflect the actual base
24 * that the CPU currently uses, because the (hidden) base value can't be
25 * directly read.
26 */
27 switch ((u32)test_register) {
28 case TEST_REGISTER_GDTR_BASE:
29 sgdt(&dt_ptr);
30 return dt_ptr.base;
31 case TEST_REGISTER_IDTR_BASE:
32 sidt(&dt_ptr);
33 return dt_ptr.base;
34 case TEST_REGISTER_TR_BASE:
35 return get_gdt_entry_base(get_tss_descr());
36 case TEST_REGISTER_LDT_BASE:
37 return get_gdt_entry_base(get_ldt_descr());
38 case TEST_REGISTER_MSR:
39 return rdmsr(msr);
40 default:
41 assert(0);
42 return 0;
43 }
44 }
45
46 enum SET_REGISTER_MODE {
47 SET_REGISTER_MODE_UNSAFE,
48 SET_REGISTER_MODE_SAFE,
49 SET_REGISTER_MODE_FEP,
50 };
51
set_test_register_value(u64 test_register,int test_mode,u64 value)52 static bool set_test_register_value(u64 test_register, int test_mode, u64 value)
53 {
54 struct descriptor_table_ptr dt_ptr;
55 u32 msr = test_register >> 32;
56 u16 sel;
57
58 switch ((u32)test_register) {
59 case TEST_REGISTER_GDTR_BASE:
60 sgdt(&dt_ptr);
61 dt_ptr.base = value;
62
63 switch (test_mode) {
64 case SET_REGISTER_MODE_UNSAFE:
65 lgdt(&dt_ptr);
66 return true;
67 case SET_REGISTER_MODE_SAFE:
68 return lgdt_safe(&dt_ptr) == 0;
69 case SET_REGISTER_MODE_FEP:
70 return lgdt_fep_safe(&dt_ptr) == 0;
71 }
72 case TEST_REGISTER_IDTR_BASE:
73 sidt(&dt_ptr);
74 dt_ptr.base = value;
75
76 switch (test_mode) {
77 case SET_REGISTER_MODE_UNSAFE:
78 lidt(&dt_ptr);
79 return true;
80 case SET_REGISTER_MODE_SAFE:
81 return lidt_safe(&dt_ptr) == 0;
82 case SET_REGISTER_MODE_FEP:
83 return lidt_fep_safe(&dt_ptr) == 0;
84 }
85 case TEST_REGISTER_TR_BASE:
86 sel = str();
87 set_gdt_entry_base(sel, value);
88 clear_tss_busy(sel);
89
90 switch (test_mode) {
91 case SET_REGISTER_MODE_UNSAFE:
92 ltr(sel);
93 return true;
94 case SET_REGISTER_MODE_SAFE:
95 return ltr_safe(sel) == 0;
96 case SET_REGISTER_MODE_FEP:
97 return ltr_fep_safe(sel) == 0;
98 }
99
100 case TEST_REGISTER_LDT_BASE:
101 sel = sldt();
102 set_gdt_entry_base(sel, value);
103
104 switch (test_mode) {
105 case SET_REGISTER_MODE_UNSAFE:
106 lldt(sel);
107 return true;
108 case SET_REGISTER_MODE_SAFE:
109 return lldt_safe(sel) == 0;
110 case SET_REGISTER_MODE_FEP:
111 return lldt_fep_safe(sel) == 0;
112 }
113 case TEST_REGISTER_MSR:
114 switch (test_mode) {
115 case SET_REGISTER_MODE_UNSAFE:
116 wrmsr(msr, value);
117 return true;
118 case SET_REGISTER_MODE_SAFE:
119 return wrmsr_safe(msr, value) == 0;
120 case SET_REGISTER_MODE_FEP:
121 return wrmsr_fep_safe(msr, value) == 0;
122 }
123 default:
124 assert(false);
125 return 0;
126 }
127 }
128
test_register_write(const char * register_name,u64 test_register,bool force_emulation,u64 test_value,bool expect_success)129 static void test_register_write(const char *register_name, u64 test_register,
130 bool force_emulation, u64 test_value,
131 bool expect_success)
132 {
133 int test_mode = (force_emulation ? SET_REGISTER_MODE_FEP : SET_REGISTER_MODE_SAFE);
134 u64 old_value, expected_value;
135 bool success;
136
137 old_value = get_test_register_value(test_register);
138 expected_value = expect_success ? test_value : old_value;
139
140 /*
141 * TODO: A successful write to the MSR_GS_BASE corrupts it, and that
142 * breaks the wrmsr_safe macro (it uses GS for per-CPU data).
143 */
144 if ((test_register >> 32) == MSR_GS_BASE && expect_success)
145 test_mode = SET_REGISTER_MODE_UNSAFE;
146
147 /* Write the test value*/
148 success = set_test_register_value(test_register, test_mode, test_value);
149 report(success == expect_success,
150 "Write to %s with value %lx did %s%s as expected",
151 register_name, test_value,
152 success == expect_success ? "" : "NOT ",
153 (expect_success ? "succeed" : "fail"));
154
155 /*
156 * Check that the value was really written. Don't test TR and LDTR,
157 * because it's not possible to read them directly.
158 */
159 if (success == expect_success &&
160 test_register != TEST_REGISTER_TR_BASE &&
161 test_register != TEST_REGISTER_LDT_BASE) {
162 u64 new_value = get_test_register_value(test_register);
163
164 report(new_value == expected_value,
165 "%s set to %lx as expected (actual value %lx)",
166 register_name, expected_value, new_value);
167 }
168
169
170 /*
171 * Restore the old value directly without safety wrapper, to avoid test
172 * crashes related to temporary clobbered GDT/IDT/etc bases.
173 */
174 set_test_register_value(test_register, SET_REGISTER_MODE_UNSAFE, old_value);
175 }
176
test_register(const char * register_name,u64 test_register,bool force_emulation)177 static void test_register(const char *register_name, u64 test_register,
178 bool force_emulation)
179 {
180 /* Canonical 48 bit value should always succeed */
181 test_register_write(register_name, test_register, force_emulation,
182 CANONICAL_48_VAL, true);
183
184 /* 57-canonical value will work on CPUs that *support* LA57 */
185 test_register_write(register_name, test_register, force_emulation,
186 CANONICAL_57_VAL, this_cpu_has(X86_FEATURE_LA57));
187
188 /* Non 57 canonical value should never work */
189 test_register_write(register_name, test_register, force_emulation,
190 NONCANONICAL, false);
191 }
192
193
194 #define TEST_REGISTER(name, force_emulation) \
195 test_register(#name, TEST_REGISTER_ ##name, force_emulation)
196
197 #define __TEST_MSR(msr_name, address, force_emulation) \
198 test_register(msr_name, ((u64)TEST_REGISTER_MSR | \
199 ((u64)(address) << 32)), force_emulation)
200
201 #define TEST_MSR(msr_name, force_emulation) \
202 __TEST_MSR(#msr_name, msr_name, force_emulation)
203
__test_invpcid(u64 test_value,bool expect_success)204 static void __test_invpcid(u64 test_value, bool expect_success)
205 {
206 struct invpcid_desc desc;
207
208 memset(&desc, 0, sizeof(desc));
209 bool success;
210
211 desc.addr = test_value;
212 desc.pcid = 10; /* Arbitrary number*/
213
214 success = invpcid_safe(0, &desc) == 0;
215
216 report(success == expect_success,
217 "Tested invpcid type 0 with 0x%lx value - %s",
218 test_value, success ? "success" : "failure");
219 }
220
test_invpcid(void)221 static void test_invpcid(void)
222 {
223 /*
224 * Note that this test tests the kvm's behavior only when ept=0.
225 * Otherwise invpcid is not intercepted.
226 *
227 * Also KVM's x86 emulator doesn't support invpcid, thus testing invpcid
228 * with FEP is pointless.
229 */
230 assert(write_cr4_safe(read_cr4() | X86_CR4_PCIDE) == 0);
231
232 __test_invpcid(CANONICAL_48_VAL, true);
233 __test_invpcid(CANONICAL_57_VAL, this_cpu_has(X86_FEATURE_LA57));
234 __test_invpcid(NONCANONICAL, false);
235 }
236
__test_canonical_checks(bool force_emulation)237 static void __test_canonical_checks(bool force_emulation)
238 {
239 printf("\nRunning canonical test %s forced emulation:\n",
240 force_emulation ? "with" : "without");
241
242 /* Direct DT addresses */
243 TEST_REGISTER(GDTR_BASE, force_emulation);
244 TEST_REGISTER(IDTR_BASE, force_emulation);
245
246 /* Indirect DT addresses */
247 TEST_REGISTER(TR_BASE, force_emulation);
248 TEST_REGISTER(LDT_BASE, force_emulation);
249
250 /* x86_64 extended segment bases */
251 TEST_MSR(MSR_FS_BASE, force_emulation);
252 TEST_MSR(MSR_GS_BASE, force_emulation);
253 TEST_MSR(MSR_KERNEL_GS_BASE, force_emulation);
254
255 /*
256 * SYSENTER ESP/EIP MSRs have canonical checks only on Intel, because
257 * only on Intel these instructions were extended to 64 bit.
258 *
259 * KVM emulation however ignores canonical checks for these MSRs, even
260 * on Intel, to support cross-vendor migration. This includes nested
261 * virtualization.
262 *
263 * Thus, the checks only work when run on bare metal, without forced
264 * emulation. Unfortunately, there is no foolproof way to detect bare
265 * metal from within this test. E.g. checking HYPERVISOR in CPUID is
266 * useless because that only detects if _this_ code is running in a VM,
267 * it doesn't detect if the "host" is itself a VM.
268 *
269 * TODO: Enable testing of SYSENTER MSRs on bare metal.
270 */
271 if (false && is_intel() && !force_emulation) {
272 TEST_MSR(MSR_IA32_SYSENTER_ESP, force_emulation);
273 TEST_MSR(MSR_IA32_SYSENTER_EIP, force_emulation);
274 } else {
275 report_skip("skipping MSR_IA32_SYSENTER_ESP/MSR_IA32_SYSENTER_EIP %s",
276 (is_intel() ? "due to known errata in KVM" : "due to AMD host"));
277 }
278
279 /* SYSCALL target MSRs */
280 TEST_MSR(MSR_CSTAR, force_emulation);
281 TEST_MSR(MSR_LSTAR, force_emulation);
282
283 /* PEBS DS area */
284 if (this_cpu_has(X86_FEATURE_DS))
285 TEST_MSR(MSR_IA32_DS_AREA, force_emulation);
286 else
287 report_skip("Skipping MSR_IA32_DS_AREA - PEBS not supported");
288
289 /* PT filter ranges */
290 if (this_cpu_has(X86_FEATURE_INTEL_PT)) {
291 int n_ranges = cpuid_indexed(0x14, 0x1).a & 0x7;
292 int i;
293
294 for (i = 0 ; i < n_ranges ; i++) {
295 wrmsr(MSR_IA32_RTIT_CTL, (1ull << (RTIT_CTL_ADDR0_OFFSET+i*4)));
296 __TEST_MSR("MSR_IA32_RTIT_ADDR_A",
297 MSR_IA32_RTIT_ADDR0_A + i*2, force_emulation);
298 __TEST_MSR("MSR_IA32_RTIT_ADDR_B",
299 MSR_IA32_RTIT_ADDR0_B + i*2, force_emulation);
300 }
301 } else {
302 report_skip("Skipping MSR_IA32_RTIT_ADDR* - Intel PT is not supported");
303 }
304
305 /* Test that INVPCID type 0 #GPs correctly */
306 if (this_cpu_has(X86_FEATURE_INVPCID))
307 test_invpcid();
308 else
309 report_skip("Skipping INVPCID - not supported");
310 }
311
test_canonical_checks(void)312 static void test_canonical_checks(void)
313 {
314 __test_canonical_checks(false);
315
316 if (is_fep_available())
317 __test_canonical_checks(true);
318 else
319 report_skip("Force emulation prefix not enabled");
320 }
321 #endif
322
main(int ac,char ** av)323 int main(int ac, char **av)
324 {
325 int vector = write_cr4_safe(read_cr4() | X86_CR4_LA57);
326 bool is_64bit = rdmsr(MSR_EFER) & EFER_LMA;
327 int expected = !is_64bit && this_cpu_has(X86_FEATURE_LA57) ? 0 : GP_VECTOR;
328
329 report(vector == expected, "%s when CR4.LA57 %ssupported (in %u-bit mode)",
330 expected ? "#GP" : "No fault",
331 this_cpu_has(X86_FEATURE_LA57) ? "un" : "", is_64bit ? 64 : 32);
332
333 #ifdef __x86_64__
334 /* set dummy LDTR pointer */
335 set_gdt_entry(FIRST_SPARE_SEL, 0xffaabb, 0xffff, 0x82, 0);
336 lldt(FIRST_SPARE_SEL);
337
338 test_canonical_checks();
339
340 if (is_64bit && this_cpu_has(X86_FEATURE_LA57)) {
341 printf("Switching to 5 level paging mode and rerunning canonical tests.\n");
342 setup_5level_page_table();
343 }
344 #endif
345
346 return report_summary();
347 }
348