xref: /kvm-unit-tests/x86/svm_tests.c (revision 08200397e62c7512acb5194155b2a12b21fe9322)
1 #include "svm.h"
2 #include "libcflat.h"
3 #include "processor.h"
4 #include "desc.h"
5 #include "msr.h"
6 #include "vm.h"
7 #include "smp.h"
8 #include "types.h"
9 #include "alloc_page.h"
10 #include "isr.h"
11 #include "apic.h"
12 #include "delay.h"
13 #include "x86/usermode.h"
14 
15 #define SVM_EXIT_MAX_DR_INTERCEPT 0x3f
16 
17 #define LATENCY_RUNS 1000000
18 
19 u64 tsc_start;
20 u64 tsc_end;
21 
22 u64 vmrun_sum, vmexit_sum;
23 u64 vmsave_sum, vmload_sum;
24 u64 stgi_sum, clgi_sum;
25 u64 latvmrun_max;
26 u64 latvmrun_min;
27 u64 latvmexit_max;
28 u64 latvmexit_min;
29 u64 latvmload_max;
30 u64 latvmload_min;
31 u64 latvmsave_max;
32 u64 latvmsave_min;
33 u64 latstgi_max;
34 u64 latstgi_min;
35 u64 latclgi_max;
36 u64 latclgi_min;
37 u64 runs;
38 
39 static void null_test(struct svm_test *test)
40 {
41 }
42 
43 static bool null_check(struct svm_test *test)
44 {
45 	return vmcb->control.exit_code == SVM_EXIT_VMMCALL;
46 }
47 
48 static void prepare_no_vmrun_int(struct svm_test *test)
49 {
50 	vmcb->control.intercept &= ~(1ULL << INTERCEPT_VMRUN);
51 }
52 
53 static bool check_no_vmrun_int(struct svm_test *test)
54 {
55 	return vmcb->control.exit_code == SVM_EXIT_ERR;
56 }
57 
58 static void test_vmrun(struct svm_test *test)
59 {
60 	asm volatile ("vmrun %0" : : "a"(virt_to_phys(vmcb)));
61 }
62 
63 static bool check_vmrun(struct svm_test *test)
64 {
65 	return vmcb->control.exit_code == SVM_EXIT_VMRUN;
66 }
67 
68 static void prepare_rsm_intercept(struct svm_test *test)
69 {
70 	default_prepare(test);
71 	vmcb->control.intercept |= 1 << INTERCEPT_RSM;
72 	vmcb->control.intercept_exceptions |= (1ULL << UD_VECTOR);
73 }
74 
75 static void test_rsm_intercept(struct svm_test *test)
76 {
77 	asm volatile ("rsm" : : : "memory");
78 }
79 
80 static bool check_rsm_intercept(struct svm_test *test)
81 {
82 	return get_test_stage(test) == 2;
83 }
84 
85 static bool finished_rsm_intercept(struct svm_test *test)
86 {
87 	switch (get_test_stage(test)) {
88 	case 0:
89 		if (vmcb->control.exit_code != SVM_EXIT_RSM) {
90 			report_fail("VMEXIT not due to rsm. Exit reason 0x%x",
91 				    vmcb->control.exit_code);
92 			return true;
93 		}
94 		vmcb->control.intercept &= ~(1 << INTERCEPT_RSM);
95 		inc_test_stage(test);
96 		break;
97 
98 	case 1:
99 		if (vmcb->control.exit_code != SVM_EXIT_EXCP_BASE + UD_VECTOR) {
100 			report_fail("VMEXIT not due to #UD. Exit reason 0x%x",
101 				    vmcb->control.exit_code);
102 			return true;
103 		}
104 		vmcb->save.rip += 2;
105 		inc_test_stage(test);
106 		break;
107 
108 	default:
109 		return true;
110 	}
111 	return get_test_stage(test) == 2;
112 }
113 
114 static void prepare_cr3_intercept(struct svm_test *test)
115 {
116 	default_prepare(test);
117 	vmcb->control.intercept_cr_read |= 1 << 3;
118 }
119 
120 static void test_cr3_intercept(struct svm_test *test)
121 {
122 	asm volatile ("mov %%cr3, %0" : "=r"(test->scratch) : : "memory");
123 }
124 
125 static bool check_cr3_intercept(struct svm_test *test)
126 {
127 	return vmcb->control.exit_code == SVM_EXIT_READ_CR3;
128 }
129 
130 static bool check_cr3_nointercept(struct svm_test *test)
131 {
132 	return null_check(test) && test->scratch == read_cr3();
133 }
134 
135 static void corrupt_cr3_intercept_bypass(void *_test)
136 {
137 	struct svm_test *test = _test;
138 	extern volatile u32 mmio_insn;
139 
140 	while (!__sync_bool_compare_and_swap(&test->scratch, 1, 2))
141 		pause();
142 	pause();
143 	pause();
144 	pause();
145 	mmio_insn = 0x90d8200f;  // mov %cr3, %rax; nop
146 }
147 
148 static void prepare_cr3_intercept_bypass(struct svm_test *test)
149 {
150 	default_prepare(test);
151 	vmcb->control.intercept_cr_read |= 1 << 3;
152 	on_cpu_async(1, corrupt_cr3_intercept_bypass, test);
153 }
154 
155 static void test_cr3_intercept_bypass(struct svm_test *test)
156 {
157 	ulong a = 0xa0000;
158 
159 	test->scratch = 1;
160 	while (test->scratch != 2)
161 		barrier();
162 
163 	asm volatile ("mmio_insn: mov %0, (%0); nop"
164 		      : "+a"(a) : : "memory");
165 	test->scratch = a;
166 }
167 
168 static void prepare_dr_intercept(struct svm_test *test)
169 {
170 	default_prepare(test);
171 	vmcb->control.intercept_dr_read = 0xff;
172 	vmcb->control.intercept_dr_write = 0xff;
173 }
174 
175 static void test_dr_intercept(struct svm_test *test)
176 {
177 	unsigned int i, failcnt = 0;
178 
179 	/* Loop testing debug register reads */
180 	for (i = 0; i < 8; i++) {
181 
182 		switch (i) {
183 		case 0:
184 			asm volatile ("mov %%dr0, %0" : "=r"(test->scratch) : : "memory");
185 			break;
186 		case 1:
187 			asm volatile ("mov %%dr1, %0" : "=r"(test->scratch) : : "memory");
188 			break;
189 		case 2:
190 			asm volatile ("mov %%dr2, %0" : "=r"(test->scratch) : : "memory");
191 			break;
192 		case 3:
193 			asm volatile ("mov %%dr3, %0" : "=r"(test->scratch) : : "memory");
194 			break;
195 		case 4:
196 			asm volatile ("mov %%dr4, %0" : "=r"(test->scratch) : : "memory");
197 			break;
198 		case 5:
199 			asm volatile ("mov %%dr5, %0" : "=r"(test->scratch) : : "memory");
200 			break;
201 		case 6:
202 			asm volatile ("mov %%dr6, %0" : "=r"(test->scratch) : : "memory");
203 			break;
204 		case 7:
205 			asm volatile ("mov %%dr7, %0" : "=r"(test->scratch) : : "memory");
206 			break;
207 		}
208 
209 		if (test->scratch != i) {
210 			report_fail("dr%u read intercept", i);
211 			failcnt++;
212 		}
213 	}
214 
215 	/* Loop testing debug register writes */
216 	for (i = 0; i < 8; i++) {
217 
218 		switch (i) {
219 		case 0:
220 			asm volatile ("mov %0, %%dr0" : : "r"(test->scratch) : "memory");
221 			break;
222 		case 1:
223 			asm volatile ("mov %0, %%dr1" : : "r"(test->scratch) : "memory");
224 			break;
225 		case 2:
226 			asm volatile ("mov %0, %%dr2" : : "r"(test->scratch) : "memory");
227 			break;
228 		case 3:
229 			asm volatile ("mov %0, %%dr3" : : "r"(test->scratch) : "memory");
230 			break;
231 		case 4:
232 			asm volatile ("mov %0, %%dr4" : : "r"(test->scratch) : "memory");
233 			break;
234 		case 5:
235 			asm volatile ("mov %0, %%dr5" : : "r"(test->scratch) : "memory");
236 			break;
237 		case 6:
238 			asm volatile ("mov %0, %%dr6" : : "r"(test->scratch) : "memory");
239 			break;
240 		case 7:
241 			asm volatile ("mov %0, %%dr7" : : "r"(test->scratch) : "memory");
242 			break;
243 		}
244 
245 		if (test->scratch != i) {
246 			report_fail("dr%u write intercept", i);
247 			failcnt++;
248 		}
249 	}
250 
251 	test->scratch = failcnt;
252 }
253 
254 static bool dr_intercept_finished(struct svm_test *test)
255 {
256 	ulong n = (vmcb->control.exit_code - SVM_EXIT_READ_DR0);
257 
258 	/* Only expect DR intercepts */
259 	if (n > (SVM_EXIT_MAX_DR_INTERCEPT - SVM_EXIT_READ_DR0))
260 		return true;
261 
262 	/*
263 	 * Compute debug register number.
264 	 * Per Appendix C "SVM Intercept Exit Codes" of AMD64 Architecture
265 	 * Programmer's Manual Volume 2 - System Programming:
266 	 * http://support.amd.com/TechDocs/24593.pdf
267 	 * there are 16 VMEXIT codes each for DR read and write.
268 	 */
269 	test->scratch = (n % 16);
270 
271 	/* Jump over MOV instruction */
272 	vmcb->save.rip += 3;
273 
274 	return false;
275 }
276 
277 static bool check_dr_intercept(struct svm_test *test)
278 {
279 	return !test->scratch;
280 }
281 
282 static bool next_rip_supported(void)
283 {
284 	return this_cpu_has(X86_FEATURE_NRIPS);
285 }
286 
287 static void prepare_next_rip(struct svm_test *test)
288 {
289 	vmcb->control.intercept |= (1ULL << INTERCEPT_RDTSC);
290 }
291 
292 
293 static void test_next_rip(struct svm_test *test)
294 {
295 	asm volatile ("rdtsc\n\t"
296 		      ".globl exp_next_rip\n\t"
297 		      "exp_next_rip:\n\t" ::: "eax", "edx");
298 }
299 
300 static bool check_next_rip(struct svm_test *test)
301 {
302 	extern char exp_next_rip;
303 	unsigned long address = (unsigned long)&exp_next_rip;
304 
305 	return address == vmcb->control.next_rip;
306 }
307 
308 extern u8 *msr_bitmap;
309 
310 static void prepare_msr_intercept(struct svm_test *test)
311 {
312 	default_prepare(test);
313 	vmcb->control.intercept |= (1ULL << INTERCEPT_MSR_PROT);
314 	vmcb->control.intercept_exceptions |= (1ULL << GP_VECTOR);
315 	memset(msr_bitmap, 0xff, MSR_BITMAP_SIZE);
316 }
317 
318 static void test_msr_intercept(struct svm_test *test)
319 {
320 	unsigned long msr_value = 0xef8056791234abcd; /* Arbitrary value */
321 	unsigned long msr_index;
322 
323 	for (msr_index = 0; msr_index <= 0xc0011fff; msr_index++) {
324 		if (msr_index == 0xC0010131 /* MSR_SEV_STATUS */) {
325 			/*
326 			 * Per section 15.34.10 "SEV_STATUS MSR" of AMD64 Architecture
327 			 * Programmer's Manual volume 2 - System Programming:
328 			 * http://support.amd.com/TechDocs/24593.pdf
329 			 * SEV_STATUS MSR (C001_0131) is a non-interceptable MSR.
330 			 */
331 			continue;
332 		}
333 
334 		/* Skips gaps between supported MSR ranges */
335 		if (msr_index == 0x2000)
336 			msr_index = 0xc0000000;
337 		else if (msr_index == 0xc0002000)
338 			msr_index = 0xc0010000;
339 
340 		test->scratch = -1;
341 
342 		rdmsr(msr_index);
343 
344 		/* Check that a read intercept occurred for MSR at msr_index */
345 		if (test->scratch != msr_index)
346 			report_fail("MSR 0x%lx read intercept", msr_index);
347 
348 		/*
349 		 * Poor man approach to generate a value that
350 		 * seems arbitrary each time around the loop.
351 		 */
352 		msr_value += (msr_value << 1);
353 
354 		wrmsr(msr_index, msr_value);
355 
356 		/* Check that a write intercept occurred for MSR with msr_value */
357 		if (test->scratch != msr_value)
358 			report_fail("MSR 0x%lx write intercept", msr_index);
359 	}
360 
361 	test->scratch = -2;
362 }
363 
364 static bool msr_intercept_finished(struct svm_test *test)
365 {
366 	u32 exit_code = vmcb->control.exit_code;
367 	u64 exit_info_1;
368 	u8 *opcode;
369 
370 	if (exit_code == SVM_EXIT_MSR) {
371 		exit_info_1 = vmcb->control.exit_info_1;
372 	} else {
373 		/*
374 		 * If #GP exception occurs instead, check that it was
375 		 * for RDMSR/WRMSR and set exit_info_1 accordingly.
376 		 */
377 
378 		if (exit_code != (SVM_EXIT_EXCP_BASE + GP_VECTOR))
379 			return true;
380 
381 		opcode = (u8 *)vmcb->save.rip;
382 		if (opcode[0] != 0x0f)
383 			return true;
384 
385 		switch (opcode[1]) {
386 		case 0x30: /* WRMSR */
387 			exit_info_1 = 1;
388 			break;
389 		case 0x32: /* RDMSR */
390 			exit_info_1 = 0;
391 			break;
392 		default:
393 			return true;
394 		}
395 
396 		/*
397 		 * Warn that #GP exception occured instead.
398 		 * RCX holds the MSR index.
399 		 */
400 		printf("%s 0x%lx #GP exception\n",
401 		       exit_info_1 ? "WRMSR" : "RDMSR", get_regs().rcx);
402 	}
403 
404 	/* Jump over RDMSR/WRMSR instruction */
405 	vmcb->save.rip += 2;
406 
407 	/*
408 	 * Test whether the intercept was for RDMSR/WRMSR.
409 	 * For RDMSR, test->scratch is set to the MSR index;
410 	 *      RCX holds the MSR index.
411 	 * For WRMSR, test->scratch is set to the MSR value;
412 	 *      RDX holds the upper 32 bits of the MSR value,
413 	 *      while RAX hold its lower 32 bits.
414 	 */
415 	if (exit_info_1)
416 		test->scratch =
417 			((get_regs().rdx << 32) | (vmcb->save.rax & 0xffffffff));
418 	else
419 		test->scratch = get_regs().rcx;
420 
421 	return false;
422 }
423 
424 static bool check_msr_intercept(struct svm_test *test)
425 {
426 	memset(msr_bitmap, 0, MSR_BITMAP_SIZE);
427 	return (test->scratch == -2);
428 }
429 
430 static void prepare_mode_switch(struct svm_test *test)
431 {
432 	vmcb->control.intercept_exceptions |= (1ULL << GP_VECTOR)
433 		|  (1ULL << UD_VECTOR)
434 		|  (1ULL << DF_VECTOR)
435 		|  (1ULL << PF_VECTOR);
436 	test->scratch = 0;
437 }
438 
439 static void test_mode_switch(struct svm_test *test)
440 {
441 	asm volatile("	cli\n"
442 		     "	ljmp *1f\n" /* jump to 32-bit code segment */
443 		     "1:\n"
444 		     "	.long 2f\n"
445 		     "	.long " xstr(KERNEL_CS32) "\n"
446 		     ".code32\n"
447 		     "2:\n"
448 		     "	movl %%cr0, %%eax\n"
449 		     "	btcl  $31, %%eax\n" /* clear PG */
450 		     "	movl %%eax, %%cr0\n"
451 		     "	movl $0xc0000080, %%ecx\n" /* EFER */
452 		     "	rdmsr\n"
453 		     "	btcl $8, %%eax\n" /* clear LME */
454 		     "	wrmsr\n"
455 		     "	movl %%cr4, %%eax\n"
456 		     "	btcl $5, %%eax\n" /* clear PAE */
457 		     "	movl %%eax, %%cr4\n"
458 		     "	movw %[ds16], %%ax\n"
459 		     "	movw %%ax, %%ds\n"
460 		     "	ljmpl %[cs16], $3f\n" /* jump to 16 bit protected-mode */
461 		     ".code16\n"
462 		     "3:\n"
463 		     "	movl %%cr0, %%eax\n"
464 		     "	btcl $0, %%eax\n" /* clear PE  */
465 		     "	movl %%eax, %%cr0\n"
466 		     "	ljmpl $0, $4f\n"   /* jump to real-mode */
467 		     "4:\n"
468 		     "	vmmcall\n"
469 		     "	movl %%cr0, %%eax\n"
470 		     "	btsl $0, %%eax\n" /* set PE  */
471 		     "	movl %%eax, %%cr0\n"
472 		     "	ljmpl %[cs32], $5f\n" /* back to protected mode */
473 		     ".code32\n"
474 		     "5:\n"
475 		     "	movl %%cr4, %%eax\n"
476 		     "	btsl $5, %%eax\n" /* set PAE */
477 		     "	movl %%eax, %%cr4\n"
478 		     "	movl $0xc0000080, %%ecx\n" /* EFER */
479 		     "	rdmsr\n"
480 		     "	btsl $8, %%eax\n" /* set LME */
481 		     "	wrmsr\n"
482 		     "	movl %%cr0, %%eax\n"
483 		     "	btsl  $31, %%eax\n" /* set PG */
484 		     "	movl %%eax, %%cr0\n"
485 		     "	ljmpl %[cs64], $6f\n"    /* back to long mode */
486 		     ".code64\n\t"
487 		     "6:\n"
488 		     "	vmmcall\n"
489 		     :: [cs16] "i"(KERNEL_CS16), [ds16] "i"(KERNEL_DS16),
490 		      [cs32] "i"(KERNEL_CS32), [cs64] "i"(KERNEL_CS64)
491 		     : "rax", "rbx", "rcx", "rdx", "memory");
492 }
493 
494 static bool mode_switch_finished(struct svm_test *test)
495 {
496 	u64 cr0, cr4, efer;
497 
498 	cr0  = vmcb->save.cr0;
499 	cr4  = vmcb->save.cr4;
500 	efer = vmcb->save.efer;
501 
502 	/* Only expect VMMCALL intercepts */
503 	if (vmcb->control.exit_code != SVM_EXIT_VMMCALL)
504 		return true;
505 
506 	/* Jump over VMMCALL instruction */
507 	vmcb->save.rip += 3;
508 
509 	/* Do sanity checks */
510 	switch (test->scratch) {
511 	case 0:
512 		/* Test should be in real mode now - check for this */
513 		if ((cr0  & 0x80000001) || /* CR0.PG, CR0.PE */
514 		    (cr4  & 0x00000020) || /* CR4.PAE */
515 		    (efer & 0x00000500))   /* EFER.LMA, EFER.LME */
516 			return true;
517 		break;
518 	case 2:
519 		/* Test should be back in long-mode now - check for this */
520 		if (((cr0  & 0x80000001) != 0x80000001) || /* CR0.PG, CR0.PE */
521 		    ((cr4  & 0x00000020) != 0x00000020) || /* CR4.PAE */
522 		    ((efer & 0x00000500) != 0x00000500))   /* EFER.LMA, EFER.LME */
523 			return true;
524 		break;
525 	}
526 
527 	/* one step forward */
528 	test->scratch += 1;
529 
530 	return test->scratch == 2;
531 }
532 
533 static bool check_mode_switch(struct svm_test *test)
534 {
535 	return test->scratch == 2;
536 }
537 
538 extern u8 *io_bitmap;
539 
540 static void prepare_ioio(struct svm_test *test)
541 {
542 	vmcb->control.intercept |= (1ULL << INTERCEPT_IOIO_PROT);
543 	test->scratch = 0;
544 	memset(io_bitmap, 0, 8192);
545 	io_bitmap[8192] = 0xFF;
546 }
547 
548 static void test_ioio(struct svm_test *test)
549 {
550 	// stage 0, test IO pass
551 	inb(0x5000);
552 	outb(0x0, 0x5000);
553 	if (get_test_stage(test) != 0)
554 		goto fail;
555 
556 	// test IO width, in/out
557 	io_bitmap[0] = 0xFF;
558 	inc_test_stage(test);
559 	inb(0x0);
560 	if (get_test_stage(test) != 2)
561 		goto fail;
562 
563 	outw(0x0, 0x0);
564 	if (get_test_stage(test) != 3)
565 		goto fail;
566 
567 	inl(0x0);
568 	if (get_test_stage(test) != 4)
569 		goto fail;
570 
571 	// test low/high IO port
572 	io_bitmap[0x5000 / 8] = (1 << (0x5000 % 8));
573 	inb(0x5000);
574 	if (get_test_stage(test) != 5)
575 		goto fail;
576 
577 	io_bitmap[0x9000 / 8] = (1 << (0x9000 % 8));
578 	inw(0x9000);
579 	if (get_test_stage(test) != 6)
580 		goto fail;
581 
582 	// test partial pass
583 	io_bitmap[0x5000 / 8] = (1 << (0x5000 % 8));
584 	inl(0x4FFF);
585 	if (get_test_stage(test) != 7)
586 		goto fail;
587 
588 	// test across pages
589 	inc_test_stage(test);
590 	inl(0x7FFF);
591 	if (get_test_stage(test) != 8)
592 		goto fail;
593 
594 	inc_test_stage(test);
595 	io_bitmap[0x8000 / 8] = 1 << (0x8000 % 8);
596 	inl(0x7FFF);
597 	if (get_test_stage(test) != 10)
598 		goto fail;
599 
600 	io_bitmap[0] = 0;
601 	inl(0xFFFF);
602 	if (get_test_stage(test) != 11)
603 		goto fail;
604 
605 	io_bitmap[0] = 0xFF;
606 	io_bitmap[8192] = 0;
607 	inl(0xFFFF);
608 	inc_test_stage(test);
609 	if (get_test_stage(test) != 12)
610 		goto fail;
611 
612 	return;
613 
614 fail:
615 	report_fail("stage %d", get_test_stage(test));
616 	test->scratch = -1;
617 }
618 
619 static bool ioio_finished(struct svm_test *test)
620 {
621 	unsigned port, size;
622 
623 	/* Only expect IOIO intercepts */
624 	if (vmcb->control.exit_code == SVM_EXIT_VMMCALL)
625 		return true;
626 
627 	if (vmcb->control.exit_code != SVM_EXIT_IOIO)
628 		return true;
629 
630 	/* one step forward */
631 	test->scratch += 1;
632 
633 	port = vmcb->control.exit_info_1 >> 16;
634 	size = (vmcb->control.exit_info_1 >> SVM_IOIO_SIZE_SHIFT) & 7;
635 
636 	while (size--) {
637 		io_bitmap[port / 8] &= ~(1 << (port & 7));
638 		port++;
639 	}
640 
641 	return false;
642 }
643 
644 static bool check_ioio(struct svm_test *test)
645 {
646 	memset(io_bitmap, 0, 8193);
647 	return test->scratch != -1;
648 }
649 
650 static void prepare_asid_zero(struct svm_test *test)
651 {
652 	vmcb->control.asid = 0;
653 }
654 
655 static void test_asid_zero(struct svm_test *test)
656 {
657 	asm volatile ("vmmcall\n\t");
658 }
659 
660 static bool check_asid_zero(struct svm_test *test)
661 {
662 	return vmcb->control.exit_code == SVM_EXIT_ERR;
663 }
664 
665 static void sel_cr0_bug_prepare(struct svm_test *test)
666 {
667 	vmcb->control.intercept |= (1ULL << INTERCEPT_SELECTIVE_CR0);
668 }
669 
670 static bool sel_cr0_bug_finished(struct svm_test *test)
671 {
672 	return true;
673 }
674 
675 static void sel_cr0_bug_test(struct svm_test *test)
676 {
677 	unsigned long cr0;
678 
679 	/* read cr0, clear CD, and write back */
680 	cr0  = read_cr0();
681 	cr0 |= (1UL << 30);
682 	write_cr0(cr0);
683 
684 	/*
685 	 * If we are here the test failed, not sure what to do now because we
686 	 * are not in guest-mode anymore so we can't trigger an intercept.
687 	 * Trigger a tripple-fault for now.
688 	 */
689 	report_fail("sel_cr0 test. Can not recover from this - exiting");
690 	exit(report_summary());
691 }
692 
693 static bool sel_cr0_bug_check(struct svm_test *test)
694 {
695 	return vmcb->control.exit_code == SVM_EXIT_CR0_SEL_WRITE;
696 }
697 
698 #define TSC_ADJUST_VALUE    (1ll << 32)
699 #define TSC_OFFSET_VALUE    (~0ull << 48)
700 static bool ok;
701 
702 static bool tsc_adjust_supported(void)
703 {
704 	return this_cpu_has(X86_FEATURE_TSC_ADJUST);
705 }
706 
707 static void tsc_adjust_prepare(struct svm_test *test)
708 {
709 	default_prepare(test);
710 	vmcb->control.tsc_offset = TSC_OFFSET_VALUE;
711 
712 	wrmsr(MSR_IA32_TSC_ADJUST, -TSC_ADJUST_VALUE);
713 	int64_t adjust = rdmsr(MSR_IA32_TSC_ADJUST);
714 	ok = adjust == -TSC_ADJUST_VALUE;
715 }
716 
717 static void tsc_adjust_test(struct svm_test *test)
718 {
719 	int64_t adjust = rdmsr(MSR_IA32_TSC_ADJUST);
720 	ok &= adjust == -TSC_ADJUST_VALUE;
721 
722 	uint64_t l1_tsc = rdtsc() - TSC_OFFSET_VALUE;
723 	wrmsr(MSR_IA32_TSC, l1_tsc - TSC_ADJUST_VALUE);
724 
725 	adjust = rdmsr(MSR_IA32_TSC_ADJUST);
726 	ok &= adjust <= -2 * TSC_ADJUST_VALUE;
727 
728 	uint64_t l1_tsc_end = rdtsc() - TSC_OFFSET_VALUE;
729 	ok &= (l1_tsc_end + TSC_ADJUST_VALUE - l1_tsc) < TSC_ADJUST_VALUE;
730 
731 	uint64_t l1_tsc_msr = rdmsr(MSR_IA32_TSC) - TSC_OFFSET_VALUE;
732 	ok &= (l1_tsc_msr + TSC_ADJUST_VALUE - l1_tsc) < TSC_ADJUST_VALUE;
733 }
734 
735 static bool tsc_adjust_check(struct svm_test *test)
736 {
737 	int64_t adjust = rdmsr(MSR_IA32_TSC_ADJUST);
738 
739 	wrmsr(MSR_IA32_TSC_ADJUST, 0);
740 	return ok && adjust <= -2 * TSC_ADJUST_VALUE;
741 }
742 
743 
744 static u64 guest_tsc_delay_value;
745 /* number of bits to shift tsc right for stable result */
746 #define TSC_SHIFT 24
747 #define TSC_SCALE_ITERATIONS 10
748 
749 static void svm_tsc_scale_guest(struct svm_test *test)
750 {
751 	u64 start_tsc = rdtsc();
752 
753 	while (rdtsc() - start_tsc < guest_tsc_delay_value)
754 		cpu_relax();
755 }
756 
757 static void svm_tsc_scale_run_testcase(u64 duration,
758 				       double tsc_scale, u64 tsc_offset)
759 {
760 	u64 start_tsc, actual_duration;
761 
762 	guest_tsc_delay_value = (duration << TSC_SHIFT) * tsc_scale;
763 
764 	test_set_guest(svm_tsc_scale_guest);
765 	vmcb->control.tsc_offset = tsc_offset;
766 	wrmsr(MSR_AMD64_TSC_RATIO, (u64)(tsc_scale * (1ULL << 32)));
767 
768 	start_tsc = rdtsc();
769 
770 	if (svm_vmrun() != SVM_EXIT_VMMCALL)
771 		report_fail("unexpected vm exit code 0x%x", vmcb->control.exit_code);
772 
773 	actual_duration = (rdtsc() - start_tsc) >> TSC_SHIFT;
774 
775 	report(duration == actual_duration, "tsc delay (expected: %lu, actual: %lu)",
776 	       duration, actual_duration);
777 }
778 
779 static void svm_tsc_scale_test(void)
780 {
781 	int i;
782 
783 	if (!tsc_scale_supported()) {
784 		report_skip("TSC scale not supported in the guest");
785 		return;
786 	}
787 
788 	report(rdmsr(MSR_AMD64_TSC_RATIO) == TSC_RATIO_DEFAULT,
789 	       "initial TSC scale ratio");
790 
791 	for (i = 0 ; i < TSC_SCALE_ITERATIONS; i++) {
792 
793 		double tsc_scale = (double)(rdrand() % 100 + 1) / 10;
794 		int duration = rdrand() % 50 + 1;
795 		u64 tsc_offset = rdrand();
796 
797 		report_info("duration=%d, tsc_scale=%d, tsc_offset=%ld",
798 			    duration, (int)(tsc_scale * 100), tsc_offset);
799 
800 		svm_tsc_scale_run_testcase(duration, tsc_scale, tsc_offset);
801 	}
802 
803 	svm_tsc_scale_run_testcase(50, 255, rdrand());
804 	svm_tsc_scale_run_testcase(50, 0.0001, rdrand());
805 }
806 
807 static void latency_prepare(struct svm_test *test)
808 {
809 	default_prepare(test);
810 	runs = LATENCY_RUNS;
811 	latvmrun_min = latvmexit_min = -1ULL;
812 	latvmrun_max = latvmexit_max = 0;
813 	vmrun_sum = vmexit_sum = 0;
814 	tsc_start = rdtsc();
815 }
816 
817 static void latency_test(struct svm_test *test)
818 {
819 	u64 cycles;
820 
821 start:
822 	tsc_end = rdtsc();
823 
824 	cycles = tsc_end - tsc_start;
825 
826 	if (cycles > latvmrun_max)
827 		latvmrun_max = cycles;
828 
829 	if (cycles < latvmrun_min)
830 		latvmrun_min = cycles;
831 
832 	vmrun_sum += cycles;
833 
834 	tsc_start = rdtsc();
835 
836 	asm volatile ("vmmcall" : : : "memory");
837 	goto start;
838 }
839 
840 static bool latency_finished(struct svm_test *test)
841 {
842 	u64 cycles;
843 
844 	tsc_end = rdtsc();
845 
846 	cycles = tsc_end - tsc_start;
847 
848 	if (cycles > latvmexit_max)
849 		latvmexit_max = cycles;
850 
851 	if (cycles < latvmexit_min)
852 		latvmexit_min = cycles;
853 
854 	vmexit_sum += cycles;
855 
856 	vmcb->save.rip += 3;
857 
858 	runs -= 1;
859 
860 	tsc_end = rdtsc();
861 
862 	return runs == 0;
863 }
864 
865 static bool latency_finished_clean(struct svm_test *test)
866 {
867 	vmcb->control.clean = VMCB_CLEAN_ALL;
868 	return latency_finished(test);
869 }
870 
871 static bool latency_check(struct svm_test *test)
872 {
873 	printf("    Latency VMRUN : max: %ld min: %ld avg: %ld\n", latvmrun_max,
874 	       latvmrun_min, vmrun_sum / LATENCY_RUNS);
875 	printf("    Latency VMEXIT: max: %ld min: %ld avg: %ld\n", latvmexit_max,
876 	       latvmexit_min, vmexit_sum / LATENCY_RUNS);
877 	return true;
878 }
879 
880 static void lat_svm_insn_prepare(struct svm_test *test)
881 {
882 	default_prepare(test);
883 	runs = LATENCY_RUNS;
884 	latvmload_min = latvmsave_min = latstgi_min = latclgi_min = -1ULL;
885 	latvmload_max = latvmsave_max = latstgi_max = latclgi_max = 0;
886 	vmload_sum = vmsave_sum = stgi_sum = clgi_sum;
887 }
888 
889 static bool lat_svm_insn_finished(struct svm_test *test)
890 {
891 	u64 vmcb_phys = virt_to_phys(vmcb);
892 	u64 cycles;
893 
894 	for ( ; runs != 0; runs--) {
895 		tsc_start = rdtsc();
896 		asm volatile("vmload %0\n\t" : : "a"(vmcb_phys) : "memory");
897 		cycles = rdtsc() - tsc_start;
898 		if (cycles > latvmload_max)
899 			latvmload_max = cycles;
900 		if (cycles < latvmload_min)
901 			latvmload_min = cycles;
902 		vmload_sum += cycles;
903 
904 		tsc_start = rdtsc();
905 		asm volatile("vmsave %0\n\t" : : "a"(vmcb_phys) : "memory");
906 		cycles = rdtsc() - tsc_start;
907 		if (cycles > latvmsave_max)
908 			latvmsave_max = cycles;
909 		if (cycles < latvmsave_min)
910 			latvmsave_min = cycles;
911 		vmsave_sum += cycles;
912 
913 		tsc_start = rdtsc();
914 		asm volatile("stgi\n\t");
915 		cycles = rdtsc() - tsc_start;
916 		if (cycles > latstgi_max)
917 			latstgi_max = cycles;
918 		if (cycles < latstgi_min)
919 			latstgi_min = cycles;
920 		stgi_sum += cycles;
921 
922 		tsc_start = rdtsc();
923 		asm volatile("clgi\n\t");
924 		cycles = rdtsc() - tsc_start;
925 		if (cycles > latclgi_max)
926 			latclgi_max = cycles;
927 		if (cycles < latclgi_min)
928 			latclgi_min = cycles;
929 		clgi_sum += cycles;
930 	}
931 
932 	tsc_end = rdtsc();
933 
934 	return true;
935 }
936 
937 static bool lat_svm_insn_check(struct svm_test *test)
938 {
939 	printf("    Latency VMLOAD: max: %ld min: %ld avg: %ld\n", latvmload_max,
940 	       latvmload_min, vmload_sum / LATENCY_RUNS);
941 	printf("    Latency VMSAVE: max: %ld min: %ld avg: %ld\n", latvmsave_max,
942 	       latvmsave_min, vmsave_sum / LATENCY_RUNS);
943 	printf("    Latency STGI:   max: %ld min: %ld avg: %ld\n", latstgi_max,
944 	       latstgi_min, stgi_sum / LATENCY_RUNS);
945 	printf("    Latency CLGI:   max: %ld min: %ld avg: %ld\n", latclgi_max,
946 	       latclgi_min, clgi_sum / LATENCY_RUNS);
947 	return true;
948 }
949 
950 /*
951  * Report failures from SVM guest code, and on failure, set the stage to -1 and
952  * do VMMCALL to terminate the test (host side must treat -1 as "finished").
953  * TODO: fix the tests that don't play nice with a straight report, e.g. the
954  * V_TPR test fails if report() is invoked.
955  */
956 #define report_svm_guest(cond, test, fmt, args...)	\
957 do {							\
958 	if (!(cond)) {					\
959 		report_fail(fmt, ##args);		\
960 		set_test_stage(test, -1);		\
961 		vmmcall();				\
962 	}						\
963 } while (0)
964 
965 bool pending_event_ipi_fired;
966 bool pending_event_guest_run;
967 
968 static void pending_event_ipi_isr(isr_regs_t *regs)
969 {
970 	pending_event_ipi_fired = true;
971 	eoi();
972 }
973 
974 static void pending_event_prepare(struct svm_test *test)
975 {
976 	int ipi_vector = 0xf1;
977 
978 	default_prepare(test);
979 
980 	pending_event_ipi_fired = false;
981 
982 	handle_irq(ipi_vector, pending_event_ipi_isr);
983 
984 	pending_event_guest_run = false;
985 
986 	vmcb->control.intercept |= (1ULL << INTERCEPT_INTR);
987 	vmcb->control.int_ctl |= V_INTR_MASKING_MASK;
988 
989 	apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL |
990 		       APIC_DM_FIXED | ipi_vector, 0);
991 
992 	set_test_stage(test, 0);
993 }
994 
995 static void pending_event_test(struct svm_test *test)
996 {
997 	pending_event_guest_run = true;
998 }
999 
1000 static bool pending_event_finished(struct svm_test *test)
1001 {
1002 	switch (get_test_stage(test)) {
1003 	case 0:
1004 		if (vmcb->control.exit_code != SVM_EXIT_INTR) {
1005 			report_fail("VMEXIT not due to pending interrupt. Exit reason 0x%x",
1006 				    vmcb->control.exit_code);
1007 			return true;
1008 		}
1009 
1010 		vmcb->control.intercept &= ~(1ULL << INTERCEPT_INTR);
1011 		vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK;
1012 
1013 		if (pending_event_guest_run) {
1014 			report_fail("Guest ran before host received IPI\n");
1015 			return true;
1016 		}
1017 
1018 		irq_enable();
1019 		asm volatile ("nop");
1020 		irq_disable();
1021 
1022 		if (!pending_event_ipi_fired) {
1023 			report_fail("Pending interrupt not dispatched after IRQ enabled\n");
1024 			return true;
1025 		}
1026 		break;
1027 
1028 	case 1:
1029 		if (!pending_event_guest_run) {
1030 			report_fail("Guest did not resume when no interrupt\n");
1031 			return true;
1032 		}
1033 		break;
1034 	}
1035 
1036 	inc_test_stage(test);
1037 
1038 	return get_test_stage(test) == 2;
1039 }
1040 
1041 static bool pending_event_check(struct svm_test *test)
1042 {
1043 	return get_test_stage(test) == 2;
1044 }
1045 
1046 static void pending_event_cli_prepare(struct svm_test *test)
1047 {
1048 	default_prepare(test);
1049 
1050 	pending_event_ipi_fired = false;
1051 
1052 	handle_irq(0xf1, pending_event_ipi_isr);
1053 
1054 	apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL |
1055 		       APIC_DM_FIXED | 0xf1, 0);
1056 
1057 	set_test_stage(test, 0);
1058 }
1059 
1060 static void pending_event_cli_prepare_gif_clear(struct svm_test *test)
1061 {
1062 	asm("cli");
1063 }
1064 
1065 static void pending_event_cli_test(struct svm_test *test)
1066 {
1067 	report_svm_guest(!pending_event_ipi_fired, test,
1068 			 "IRQ should NOT be delivered while IRQs disabled");
1069 
1070 	/* VINTR_MASKING is zero.  This should cause the IPI to fire.  */
1071 	irq_enable();
1072 	asm volatile ("nop");
1073 	irq_disable();
1074 
1075 	report_svm_guest(pending_event_ipi_fired, test,
1076 			 "IRQ should be delivered after enabling IRQs");
1077 	vmmcall();
1078 
1079 	/*
1080 	 * Now VINTR_MASKING=1, but no interrupt is pending so
1081 	 * the VINTR interception should be clear in VMCB02.  Check
1082 	 * that L0 did not leave a stale VINTR in the VMCB.
1083 	 */
1084 	irq_enable();
1085 	asm volatile ("nop");
1086 	irq_disable();
1087 }
1088 
1089 static bool pending_event_cli_finished(struct svm_test *test)
1090 {
1091 	report_svm_guest(vmcb->control.exit_code == SVM_EXIT_VMMCALL, test,
1092 			 "Wanted VMMCALL VM-Exit, got exit reason 0x%x",
1093 			 vmcb->control.exit_code);
1094 
1095 	switch (get_test_stage(test)) {
1096 	case 0:
1097 		vmcb->save.rip += 3;
1098 
1099 		pending_event_ipi_fired = false;
1100 
1101 		vmcb->control.int_ctl |= V_INTR_MASKING_MASK;
1102 
1103 		/* Now entering again with VINTR_MASKING=1.  */
1104 		apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL |
1105 			       APIC_DM_FIXED | 0xf1, 0);
1106 
1107 		break;
1108 
1109 	case 1:
1110 		if (pending_event_ipi_fired == true) {
1111 			report_fail("Interrupt triggered by guest");
1112 			return true;
1113 		}
1114 
1115 		irq_enable();
1116 		asm volatile ("nop");
1117 		irq_disable();
1118 
1119 		if (pending_event_ipi_fired != true) {
1120 			report_fail("Interrupt not triggered by host");
1121 			return true;
1122 		}
1123 
1124 		break;
1125 
1126 	default:
1127 		return true;
1128 	}
1129 
1130 	inc_test_stage(test);
1131 
1132 	return get_test_stage(test) == 2;
1133 }
1134 
1135 static bool pending_event_cli_check(struct svm_test *test)
1136 {
1137 	return get_test_stage(test) == 2;
1138 }
1139 
1140 #define TIMER_VECTOR    222
1141 
1142 static volatile bool timer_fired;
1143 
1144 static void timer_isr(isr_regs_t *regs)
1145 {
1146 	timer_fired = true;
1147 	apic_write(APIC_EOI, 0);
1148 }
1149 
1150 static void interrupt_prepare(struct svm_test *test)
1151 {
1152 	default_prepare(test);
1153 	handle_irq(TIMER_VECTOR, timer_isr);
1154 	timer_fired = false;
1155 	set_test_stage(test, 0);
1156 }
1157 
1158 static void interrupt_test(struct svm_test *test)
1159 {
1160 	long long start, loops;
1161 
1162 	apic_write(APIC_LVTT, TIMER_VECTOR);
1163 	irq_enable();
1164 	apic_write(APIC_TMICT, 1); //Timer Initial Count Register 0x380 one-shot
1165 	for (loops = 0; loops < 10000000 && !timer_fired; loops++)
1166 		asm volatile ("nop");
1167 
1168 	report_svm_guest(timer_fired, test,
1169 			 "direct interrupt while running guest");
1170 
1171 	apic_write(APIC_TMICT, 0);
1172 	irq_disable();
1173 	vmmcall();
1174 
1175 	timer_fired = false;
1176 	apic_write(APIC_TMICT, 1);
1177 	for (loops = 0; loops < 10000000 && !timer_fired; loops++)
1178 		asm volatile ("nop");
1179 
1180 	report_svm_guest(timer_fired, test,
1181 			 "intercepted interrupt while running guest");
1182 
1183 	irq_enable();
1184 	apic_write(APIC_TMICT, 0);
1185 	irq_disable();
1186 
1187 	timer_fired = false;
1188 	start = rdtsc();
1189 	apic_write(APIC_TMICT, 1000000);
1190 	safe_halt();
1191 
1192 	report_svm_guest(timer_fired, test, "direct interrupt + hlt");
1193 	report(rdtsc() - start > 10000, "IRQ arrived after expected delay");
1194 
1195 	apic_write(APIC_TMICT, 0);
1196 	irq_disable();
1197 	vmmcall();
1198 
1199 	timer_fired = false;
1200 	start = rdtsc();
1201 	apic_write(APIC_TMICT, 1000000);
1202 	asm volatile ("hlt");
1203 
1204 	report_svm_guest(timer_fired, test, "intercepted interrupt + hlt");
1205 	report(rdtsc() - start > 10000, "IRQ arrived after expected delay");
1206 
1207 	apic_write(APIC_TMICT, 0);
1208 	irq_disable();
1209 }
1210 
1211 static bool interrupt_finished(struct svm_test *test)
1212 {
1213 	switch (get_test_stage(test)) {
1214 	case 0:
1215 	case 2:
1216 		if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
1217 			report_fail("VMEXIT not due to vmmcall. Exit reason 0x%x",
1218 				    vmcb->control.exit_code);
1219 			return true;
1220 		}
1221 		vmcb->save.rip += 3;
1222 
1223 		vmcb->control.intercept |= (1ULL << INTERCEPT_INTR);
1224 		vmcb->control.int_ctl |= V_INTR_MASKING_MASK;
1225 		break;
1226 
1227 	case 1:
1228 	case 3:
1229 		if (vmcb->control.exit_code != SVM_EXIT_INTR) {
1230 			report_fail("VMEXIT not due to intr intercept. Exit reason 0x%x",
1231 				    vmcb->control.exit_code);
1232 			return true;
1233 		}
1234 
1235 		irq_enable();
1236 		asm volatile ("nop");
1237 		irq_disable();
1238 
1239 		vmcb->control.intercept &= ~(1ULL << INTERCEPT_INTR);
1240 		vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK;
1241 		break;
1242 
1243 	case 4:
1244 		break;
1245 
1246 	default:
1247 		return true;
1248 	}
1249 
1250 	inc_test_stage(test);
1251 
1252 	return get_test_stage(test) == 5;
1253 }
1254 
1255 static bool interrupt_check(struct svm_test *test)
1256 {
1257 	return get_test_stage(test) == 5;
1258 }
1259 
1260 static volatile bool nmi_fired;
1261 
1262 static void nmi_handler(struct ex_regs *regs)
1263 {
1264 	nmi_fired = true;
1265 }
1266 
1267 static void nmi_prepare(struct svm_test *test)
1268 {
1269 	default_prepare(test);
1270 	nmi_fired = false;
1271 	handle_exception(NMI_VECTOR, nmi_handler);
1272 	set_test_stage(test, 0);
1273 }
1274 
1275 static void nmi_test(struct svm_test *test)
1276 {
1277 	apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL | APIC_DM_NMI | APIC_INT_ASSERT, 0);
1278 
1279 	report_svm_guest(nmi_fired, test, "direct NMI while running guest");
1280 
1281 	vmmcall();
1282 
1283 	nmi_fired = false;
1284 
1285 	apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL | APIC_DM_NMI | APIC_INT_ASSERT, 0);
1286 
1287 	report_svm_guest(nmi_fired, test, "intercepted pending NMI delivered to guest");
1288 }
1289 
1290 static bool nmi_finished(struct svm_test *test)
1291 {
1292 	switch (get_test_stage(test)) {
1293 	case 0:
1294 		if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
1295 			report_fail("VMEXIT not due to vmmcall. Exit reason 0x%x",
1296 				    vmcb->control.exit_code);
1297 			return true;
1298 		}
1299 		vmcb->save.rip += 3;
1300 
1301 		vmcb->control.intercept |= (1ULL << INTERCEPT_NMI);
1302 		break;
1303 
1304 	case 1:
1305 		if (vmcb->control.exit_code != SVM_EXIT_NMI) {
1306 			report_fail("VMEXIT not due to NMI intercept. Exit reason 0x%x",
1307 				    vmcb->control.exit_code);
1308 			return true;
1309 		}
1310 
1311 		report_pass("NMI intercept while running guest");
1312 		break;
1313 
1314 	case 2:
1315 		break;
1316 
1317 	default:
1318 		return true;
1319 	}
1320 
1321 	inc_test_stage(test);
1322 
1323 	return get_test_stage(test) == 3;
1324 }
1325 
1326 static bool nmi_check(struct svm_test *test)
1327 {
1328 	return get_test_stage(test) == 3;
1329 }
1330 
1331 #define NMI_DELAY 100000000ULL
1332 
1333 static void nmi_message_thread(void *_test)
1334 {
1335 	struct svm_test *test = _test;
1336 
1337 	while (get_test_stage(test) != 1)
1338 		pause();
1339 
1340 	delay(NMI_DELAY);
1341 
1342 	apic_icr_write(APIC_DEST_PHYSICAL | APIC_DM_NMI | APIC_INT_ASSERT, id_map[0]);
1343 
1344 	while (get_test_stage(test) != 2)
1345 		pause();
1346 
1347 	delay(NMI_DELAY);
1348 
1349 	apic_icr_write(APIC_DEST_PHYSICAL | APIC_DM_NMI | APIC_INT_ASSERT, id_map[0]);
1350 }
1351 
1352 static void nmi_hlt_test(struct svm_test *test)
1353 {
1354 	long long start;
1355 
1356 	on_cpu_async(1, nmi_message_thread, test);
1357 
1358 	start = rdtsc();
1359 
1360 	set_test_stage(test, 1);
1361 
1362 	asm volatile ("hlt");
1363 
1364 	report_svm_guest(nmi_fired, test, "direct NMI + hlt");
1365 	report(rdtsc() - start > NMI_DELAY, "direct NMI after expected delay");
1366 
1367 	nmi_fired = false;
1368 
1369 	vmmcall();
1370 
1371 	start = rdtsc();
1372 
1373 	set_test_stage(test, 2);
1374 
1375 	asm volatile ("hlt");
1376 
1377 	report_svm_guest(nmi_fired, test, "intercepted NMI + hlt");
1378 	report(rdtsc() - start > NMI_DELAY, "intercepted NMI after expected delay");
1379 
1380 	set_test_stage(test, 3);
1381 }
1382 
1383 static bool nmi_hlt_finished(struct svm_test *test)
1384 {
1385 	switch (get_test_stage(test)) {
1386 	case 1:
1387 		if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
1388 			report_fail("VMEXIT not due to vmmcall. Exit reason 0x%x",
1389 				    vmcb->control.exit_code);
1390 			return true;
1391 		}
1392 		vmcb->save.rip += 3;
1393 
1394 		vmcb->control.intercept |= (1ULL << INTERCEPT_NMI);
1395 		break;
1396 
1397 	case 2:
1398 		if (vmcb->control.exit_code != SVM_EXIT_NMI) {
1399 			report_fail("VMEXIT not due to NMI intercept. Exit reason 0x%x",
1400 				    vmcb->control.exit_code);
1401 			return true;
1402 		}
1403 
1404 		report_pass("NMI intercept while running guest");
1405 		break;
1406 
1407 	case 3:
1408 		break;
1409 
1410 	default:
1411 		return true;
1412 	}
1413 
1414 	return get_test_stage(test) == 3;
1415 }
1416 
1417 static bool nmi_hlt_check(struct svm_test *test)
1418 {
1419 	return get_test_stage(test) == 3;
1420 }
1421 
1422 static void vnmi_prepare(struct svm_test *test)
1423 {
1424 	nmi_prepare(test);
1425 
1426 	/*
1427 	 * Disable NMI interception to start.  Enabling vNMI without
1428 	 * intercepting "real" NMIs should result in an ERR VM-Exit.
1429 	 */
1430 	vmcb->control.intercept &= ~(1ULL << INTERCEPT_NMI);
1431 	vmcb->control.int_ctl = V_NMI_ENABLE_MASK;
1432 	vmcb->control.int_vector = NMI_VECTOR;
1433 }
1434 
1435 static void vnmi_test(struct svm_test *test)
1436 {
1437 	report_svm_guest(!nmi_fired, test, "No vNMI before injection");
1438 	vmmcall();
1439 
1440 	report_svm_guest(nmi_fired, test, "vNMI delivered after injection");
1441 	vmmcall();
1442 }
1443 
1444 static bool vnmi_finished(struct svm_test *test)
1445 {
1446 	switch (get_test_stage(test)) {
1447 	case 0:
1448 		if (vmcb->control.exit_code != SVM_EXIT_ERR) {
1449 			report_fail("Wanted ERR VM-Exit, got 0x%x",
1450 				    vmcb->control.exit_code);
1451 			return true;
1452 		}
1453 		report(!nmi_fired, "vNMI enabled but NMI_INTERCEPT unset!");
1454 		vmcb->control.intercept |= (1ULL << INTERCEPT_NMI);
1455 		vmcb->save.rip += 3;
1456 		break;
1457 
1458 	case 1:
1459 		if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
1460 			report_fail("Wanted VMMCALL VM-Exit, got 0x%x",
1461 				    vmcb->control.exit_code);
1462 			return true;
1463 		}
1464 		report(!nmi_fired, "vNMI with vector 2 not injected");
1465 		vmcb->control.int_ctl |= V_NMI_PENDING_MASK;
1466 		vmcb->save.rip += 3;
1467 		break;
1468 
1469 	case 2:
1470 		if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
1471 			report_fail("Wanted VMMCALL VM-Exit, got 0x%x",
1472 				    vmcb->control.exit_code);
1473 			return true;
1474 		}
1475 		if (vmcb->control.int_ctl & V_NMI_BLOCKING_MASK) {
1476 			report_fail("V_NMI_BLOCKING_MASK not cleared on VMEXIT");
1477 			return true;
1478 		}
1479 		report_pass("VNMI serviced");
1480 		vmcb->save.rip += 3;
1481 		break;
1482 
1483 	default:
1484 		return true;
1485 	}
1486 
1487 	inc_test_stage(test);
1488 
1489 	return get_test_stage(test) == 3;
1490 }
1491 
1492 static bool vnmi_check(struct svm_test *test)
1493 {
1494 	return get_test_stage(test) == 3;
1495 }
1496 
1497 static volatile int count_exc = 0;
1498 
1499 static void my_isr(struct ex_regs *r)
1500 {
1501 	count_exc++;
1502 }
1503 
1504 static void exc_inject_prepare(struct svm_test *test)
1505 {
1506 	default_prepare(test);
1507 	handle_exception(DE_VECTOR, my_isr);
1508 	handle_exception(NMI_VECTOR, my_isr);
1509 }
1510 
1511 
1512 static void exc_inject_test(struct svm_test *test)
1513 {
1514 	asm volatile ("vmmcall\n\tvmmcall\n\t");
1515 }
1516 
1517 static bool exc_inject_finished(struct svm_test *test)
1518 {
1519 	switch (get_test_stage(test)) {
1520 	case 0:
1521 		if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
1522 			report_fail("VMEXIT not due to vmmcall. Exit reason 0x%x",
1523 				    vmcb->control.exit_code);
1524 			return true;
1525 		}
1526 		vmcb->save.rip += 3;
1527 		vmcb->control.event_inj = NMI_VECTOR | SVM_EVTINJ_TYPE_EXEPT | SVM_EVTINJ_VALID;
1528 		break;
1529 
1530 	case 1:
1531 		if (vmcb->control.exit_code != SVM_EXIT_ERR) {
1532 			report_fail("VMEXIT not due to error. Exit reason 0x%x",
1533 				    vmcb->control.exit_code);
1534 			return true;
1535 		}
1536 		report(count_exc == 0, "exception with vector 2 not injected");
1537 		vmcb->control.event_inj = DE_VECTOR | SVM_EVTINJ_TYPE_EXEPT | SVM_EVTINJ_VALID;
1538 		break;
1539 
1540 	case 2:
1541 		if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
1542 			report_fail("VMEXIT not due to vmmcall. Exit reason 0x%x",
1543 				    vmcb->control.exit_code);
1544 			return true;
1545 		}
1546 		vmcb->save.rip += 3;
1547 		report(count_exc == 1, "divide overflow exception injected");
1548 		report(!(vmcb->control.event_inj & SVM_EVTINJ_VALID), "eventinj.VALID cleared");
1549 		break;
1550 
1551 	default:
1552 		return true;
1553 	}
1554 
1555 	inc_test_stage(test);
1556 
1557 	return get_test_stage(test) == 3;
1558 }
1559 
1560 static bool exc_inject_check(struct svm_test *test)
1561 {
1562 	return count_exc == 1 && get_test_stage(test) == 3;
1563 }
1564 
1565 static volatile bool virq_fired;
1566 
1567 static void virq_isr(isr_regs_t *regs)
1568 {
1569 	virq_fired = true;
1570 }
1571 
1572 static void virq_inject_prepare(struct svm_test *test)
1573 {
1574 	handle_irq(0xf1, virq_isr);
1575 	default_prepare(test);
1576 	vmcb->control.int_ctl = V_INTR_MASKING_MASK | V_IRQ_MASK |
1577 		(0x0f << V_INTR_PRIO_SHIFT); // Set to the highest priority
1578 	vmcb->control.int_vector = 0xf1;
1579 	virq_fired = false;
1580 	set_test_stage(test, 0);
1581 }
1582 
1583 static void virq_inject_test(struct svm_test *test)
1584 {
1585 	report_svm_guest(!virq_fired, test, "virtual IRQ blocked after L2 cli");
1586 
1587 	irq_enable();
1588 	asm volatile ("nop");
1589 	irq_disable();
1590 
1591 	report_svm_guest(virq_fired, test, "virtual IRQ fired after L2 sti");
1592 
1593 	vmmcall();
1594 
1595 	report_svm_guest(!virq_fired, test, "intercepted VINTR blocked after L2 cli");
1596 
1597 	irq_enable();
1598 	asm volatile ("nop");
1599 	irq_disable();
1600 
1601 	report_svm_guest(virq_fired, test, "intercepted VINTR fired after L2 sti");
1602 
1603 	vmmcall();
1604 
1605 	irq_enable();
1606 	asm volatile ("nop");
1607 	irq_disable();
1608 
1609 	report_svm_guest(!virq_fired, test,
1610 			  "virtual IRQ blocked V_IRQ_PRIO less than V_TPR");
1611 
1612 	vmmcall();
1613 	vmmcall();
1614 }
1615 
1616 static bool virq_inject_finished(struct svm_test *test)
1617 {
1618 	vmcb->save.rip += 3;
1619 
1620 	switch (get_test_stage(test)) {
1621 	case 0:
1622 		if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
1623 			report_fail("VMEXIT not due to vmmcall. Exit reason 0x%x",
1624 				    vmcb->control.exit_code);
1625 			return true;
1626 		}
1627 		if (vmcb->control.int_ctl & V_IRQ_MASK) {
1628 			report_fail("V_IRQ not cleared on VMEXIT after firing");
1629 			return true;
1630 		}
1631 		virq_fired = false;
1632 		vmcb->control.intercept |= (1ULL << INTERCEPT_VINTR);
1633 		vmcb->control.int_ctl = V_INTR_MASKING_MASK | V_IRQ_MASK |
1634 			(0x0f << V_INTR_PRIO_SHIFT);
1635 		break;
1636 
1637 	case 1:
1638 		if (vmcb->control.exit_code != SVM_EXIT_VINTR) {
1639 			report_fail("VMEXIT not due to vintr. Exit reason 0x%x",
1640 				    vmcb->control.exit_code);
1641 			return true;
1642 		}
1643 		if (virq_fired) {
1644 			report_fail("V_IRQ fired before SVM_EXIT_VINTR");
1645 			return true;
1646 		}
1647 		vmcb->control.intercept &= ~(1ULL << INTERCEPT_VINTR);
1648 		break;
1649 
1650 	case 2:
1651 		if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
1652 			report_fail("VMEXIT not due to vmmcall. Exit reason 0x%x",
1653 				    vmcb->control.exit_code);
1654 			return true;
1655 		}
1656 		virq_fired = false;
1657 		// Set irq to lower priority
1658 		vmcb->control.int_ctl = V_INTR_MASKING_MASK | V_IRQ_MASK |
1659 			(0x08 << V_INTR_PRIO_SHIFT);
1660 		// Raise guest TPR
1661 		vmcb->control.int_ctl |= 0x0a & V_TPR_MASK;
1662 		break;
1663 
1664 	case 3:
1665 		if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
1666 			report_fail("VMEXIT not due to vmmcall. Exit reason 0x%x",
1667 				    vmcb->control.exit_code);
1668 			return true;
1669 		}
1670 		vmcb->control.intercept |= (1ULL << INTERCEPT_VINTR);
1671 		break;
1672 
1673 	case 4:
1674 		// INTERCEPT_VINTR should be ignored because V_INTR_PRIO < V_TPR
1675 		if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
1676 			report_fail("VMEXIT not due to vmmcall. Exit reason 0x%x",
1677 				    vmcb->control.exit_code);
1678 			return true;
1679 		}
1680 		break;
1681 
1682 	default:
1683 		return true;
1684 	}
1685 
1686 	inc_test_stage(test);
1687 
1688 	return get_test_stage(test) == 5;
1689 }
1690 
1691 static bool virq_inject_check(struct svm_test *test)
1692 {
1693 	return get_test_stage(test) == 5;
1694 }
1695 
1696 /*
1697  * Detect nested guest RIP corruption as explained in kernel commit
1698  * b6162e82aef19fee9c32cb3fe9ac30d9116a8c73
1699  *
1700  * In the assembly loop below 'ins' is executed while IO instructions
1701  * are not intercepted; the instruction is emulated by L0.
1702  *
1703  * At the same time we are getting interrupts from the local APIC timer,
1704  * and we do intercept them in L1
1705  *
1706  * If the interrupt happens on the insb instruction, L0 will VMexit, emulate
1707  * the insb instruction and then it will inject the interrupt to L1 through
1708  * a nested VMexit.  Due to a bug, it would leave pre-emulation values of RIP,
1709  * RAX and RSP in the VMCB.
1710  *
1711  * In our intercept handler we detect the bug by checking that RIP is that of
1712  * the insb instruction, but its memory operand has already been written.
1713  * This means that insb was already executed.
1714  */
1715 
1716 static volatile int isr_cnt = 0;
1717 static volatile uint8_t io_port_var = 0xAA;
1718 extern const char insb_instruction_label[];
1719 
1720 static void reg_corruption_isr(isr_regs_t *regs)
1721 {
1722 	isr_cnt++;
1723 	apic_write(APIC_EOI, 0);
1724 }
1725 
1726 static void reg_corruption_prepare(struct svm_test *test)
1727 {
1728 	default_prepare(test);
1729 	set_test_stage(test, 0);
1730 
1731 	vmcb->control.int_ctl = V_INTR_MASKING_MASK;
1732 	vmcb->control.intercept |= (1ULL << INTERCEPT_INTR);
1733 
1734 	handle_irq(TIMER_VECTOR, reg_corruption_isr);
1735 
1736 	/* set local APIC to inject external interrupts */
1737 	apic_write(APIC_TMICT, 0);
1738 	apic_write(APIC_TDCR, 0);
1739 	apic_write(APIC_LVTT, TIMER_VECTOR | APIC_LVT_TIMER_PERIODIC);
1740 	apic_write(APIC_TMICT, 1000);
1741 }
1742 
1743 static void reg_corruption_test(struct svm_test *test)
1744 {
1745 	/* this is endless loop, which is interrupted by the timer interrupt */
1746 	asm volatile (
1747 		      "1:\n\t"
1748 		      "movw $0x4d0, %%dx\n\t" // IO port
1749 		      "lea %[io_port_var], %%rdi\n\t"
1750 		      "movb $0xAA, %[io_port_var]\n\t"
1751 		      "insb_instruction_label:\n\t"
1752 		      "insb\n\t"
1753 		      "jmp 1b\n\t"
1754 
1755 		      : [io_port_var] "=m" (io_port_var)
1756 		      : /* no inputs*/
1757 		      : "rdx", "rdi"
1758 		      );
1759 }
1760 
1761 static bool reg_corruption_finished(struct svm_test *test)
1762 {
1763 	if (isr_cnt == 10000) {
1764 		report_pass("No RIP corruption detected after %d timer interrupts",
1765 			    isr_cnt);
1766 		set_test_stage(test, 1);
1767 		goto cleanup;
1768 	}
1769 
1770 	if (vmcb->control.exit_code == SVM_EXIT_INTR) {
1771 
1772 		void* guest_rip = (void*)vmcb->save.rip;
1773 
1774 		irq_enable();
1775 		asm volatile ("nop");
1776 		irq_disable();
1777 
1778 		if (guest_rip == insb_instruction_label && io_port_var != 0xAA) {
1779 			report_fail("RIP corruption detected after %d timer interrupts",
1780 				    isr_cnt);
1781 			goto cleanup;
1782 		}
1783 
1784 	}
1785 	return false;
1786 cleanup:
1787 	apic_write(APIC_LVTT, APIC_LVT_TIMER_MASK);
1788 	apic_write(APIC_TMICT, 0);
1789 	return true;
1790 
1791 }
1792 
1793 static bool reg_corruption_check(struct svm_test *test)
1794 {
1795 	return get_test_stage(test) == 1;
1796 }
1797 
1798 static void get_tss_entry(void *data)
1799 {
1800 	*((gdt_entry_t **)data) = get_tss_descr();
1801 }
1802 
1803 static int orig_cpu_count;
1804 
1805 static void init_startup_prepare(struct svm_test *test)
1806 {
1807 	gdt_entry_t *tss_entry;
1808 	int i;
1809 
1810 	on_cpu(1, get_tss_entry, &tss_entry);
1811 
1812 	orig_cpu_count = atomic_read(&cpu_online_count);
1813 
1814 	apic_icr_write(APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT,
1815 		       id_map[1]);
1816 
1817 	delay(100000000ULL);
1818 
1819 	atomic_dec(&cpu_online_count);
1820 
1821 	tss_entry->type &= ~DESC_BUSY;
1822 
1823 	apic_icr_write(APIC_DEST_PHYSICAL | APIC_DM_STARTUP, id_map[1]);
1824 
1825 	for (i = 0; i < 5 && atomic_read(&cpu_online_count) < orig_cpu_count; i++)
1826 		delay(100000000ULL);
1827 }
1828 
1829 static bool init_startup_finished(struct svm_test *test)
1830 {
1831 	return true;
1832 }
1833 
1834 static bool init_startup_check(struct svm_test *test)
1835 {
1836 	return atomic_read(&cpu_online_count) == orig_cpu_count;
1837 }
1838 
1839 static volatile bool init_intercept;
1840 
1841 static void init_intercept_prepare(struct svm_test *test)
1842 {
1843 	init_intercept = false;
1844 	vmcb->control.intercept |= (1ULL << INTERCEPT_INIT);
1845 }
1846 
1847 static void init_intercept_test(struct svm_test *test)
1848 {
1849 	apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT, 0);
1850 }
1851 
1852 static bool init_intercept_finished(struct svm_test *test)
1853 {
1854 	vmcb->save.rip += 3;
1855 
1856 	if (vmcb->control.exit_code != SVM_EXIT_INIT) {
1857 		report_fail("VMEXIT not due to init intercept. Exit reason 0x%x",
1858 			    vmcb->control.exit_code);
1859 
1860 		return true;
1861 	}
1862 
1863 	init_intercept = true;
1864 
1865 	report_pass("INIT to vcpu intercepted");
1866 
1867 	return true;
1868 }
1869 
1870 static bool init_intercept_check(struct svm_test *test)
1871 {
1872 	return init_intercept;
1873 }
1874 
1875 /*
1876  * Setting host EFLAGS.TF causes a #DB trap after the VMRUN completes on the
1877  * host side (i.e., after the #VMEXIT from the guest).
1878  *
1879  * Setting host EFLAGS.RF suppresses any potential instruction breakpoint
1880  * match on the VMRUN and completion of the VMRUN instruction clears the
1881  * host EFLAGS.RF bit.
1882  *
1883  * [AMD APM]
1884  */
1885 static volatile u8 host_rflags_guest_main_flag = 0;
1886 static volatile u8 host_rflags_db_handler_flag = 0;
1887 static volatile bool host_rflags_ss_on_vmrun = false;
1888 static volatile bool host_rflags_vmrun_reached = false;
1889 static volatile bool host_rflags_set_tf = false;
1890 static volatile bool host_rflags_set_rf = false;
1891 static u64 rip_detected;
1892 
1893 extern u64 *vmrun_rip;
1894 
1895 static void host_rflags_db_handler(struct ex_regs *r)
1896 {
1897 	if (host_rflags_ss_on_vmrun) {
1898 		if (host_rflags_vmrun_reached) {
1899 			if (!host_rflags_set_rf) {
1900 				r->rflags &= ~X86_EFLAGS_TF;
1901 				rip_detected = r->rip;
1902 			} else {
1903 				r->rflags |= X86_EFLAGS_RF;
1904 				++host_rflags_db_handler_flag;
1905 			}
1906 		} else {
1907 			if (r->rip == (u64)&vmrun_rip) {
1908 				host_rflags_vmrun_reached = true;
1909 
1910 				if (host_rflags_set_rf) {
1911 					host_rflags_guest_main_flag = 0;
1912 					rip_detected = r->rip;
1913 					r->rflags &= ~X86_EFLAGS_TF;
1914 
1915 					/* Trigger #DB via debug registers */
1916 					write_dr0((void *)&vmrun_rip);
1917 					write_dr7(0x403);
1918 				}
1919 			}
1920 		}
1921 	} else {
1922 		r->rflags &= ~X86_EFLAGS_TF;
1923 	}
1924 }
1925 
1926 static void host_rflags_prepare(struct svm_test *test)
1927 {
1928 	default_prepare(test);
1929 	handle_exception(DB_VECTOR, host_rflags_db_handler);
1930 	set_test_stage(test, 0);
1931 }
1932 
1933 static void host_rflags_prepare_gif_clear(struct svm_test *test)
1934 {
1935 	if (host_rflags_set_tf)
1936 		write_rflags(read_rflags() | X86_EFLAGS_TF);
1937 }
1938 
1939 static void host_rflags_test(struct svm_test *test)
1940 {
1941 	while (1) {
1942 		if (get_test_stage(test) > 0) {
1943 			if ((host_rflags_set_tf && !host_rflags_ss_on_vmrun && !host_rflags_db_handler_flag) ||
1944 			    (host_rflags_set_rf && host_rflags_db_handler_flag == 1))
1945 				host_rflags_guest_main_flag = 1;
1946 		}
1947 
1948 		if (get_test_stage(test) == 4)
1949 			break;
1950 		vmmcall();
1951 	}
1952 }
1953 
1954 static bool host_rflags_finished(struct svm_test *test)
1955 {
1956 	switch (get_test_stage(test)) {
1957 	case 0:
1958 		if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
1959 			report_fail("Unexpected VMEXIT. Exit reason 0x%x",
1960 				    vmcb->control.exit_code);
1961 			return true;
1962 		}
1963 		vmcb->save.rip += 3;
1964 		/*
1965 		 * Setting host EFLAGS.TF not immediately before VMRUN, causes
1966 		 * #DB trap before first guest instruction is executed
1967 		 */
1968 		host_rflags_set_tf = true;
1969 		break;
1970 	case 1:
1971 		if (vmcb->control.exit_code != SVM_EXIT_VMMCALL ||
1972 		    host_rflags_guest_main_flag != 1) {
1973 			report_fail("Unexpected VMEXIT or #DB handler"
1974 				    " invoked before guest main. Exit reason 0x%x",
1975 				    vmcb->control.exit_code);
1976 			return true;
1977 		}
1978 		vmcb->save.rip += 3;
1979 		/*
1980 		 * Setting host EFLAGS.TF immediately before VMRUN, causes #DB
1981 		 * trap after VMRUN completes on the host side (i.e., after
1982 		 * VMEXIT from guest).
1983 		 */
1984 		host_rflags_ss_on_vmrun = true;
1985 		break;
1986 	case 2:
1987 		if (vmcb->control.exit_code != SVM_EXIT_VMMCALL ||
1988 		    rip_detected != (u64)&vmrun_rip + 3) {
1989 			report_fail("Unexpected VMEXIT or RIP mismatch."
1990 				    " Exit reason 0x%x, RIP actual: %lx, RIP expected: "
1991 				    "%lx", vmcb->control.exit_code,
1992 				    (u64)&vmrun_rip + 3, rip_detected);
1993 			return true;
1994 		}
1995 		host_rflags_set_rf = true;
1996 		host_rflags_guest_main_flag = 0;
1997 		host_rflags_vmrun_reached = false;
1998 		vmcb->save.rip += 3;
1999 		break;
2000 	case 3:
2001 		if (vmcb->control.exit_code != SVM_EXIT_VMMCALL ||
2002 		    rip_detected != (u64)&vmrun_rip ||
2003 		    host_rflags_guest_main_flag != 1 ||
2004 		    host_rflags_db_handler_flag > 1 ||
2005 		    read_rflags() & X86_EFLAGS_RF) {
2006 			report_fail("Unexpected VMEXIT or RIP mismatch or "
2007 				    "EFLAGS.RF not cleared."
2008 				    " Exit reason 0x%x, RIP actual: %lx, RIP expected: "
2009 				    "%lx", vmcb->control.exit_code,
2010 				    (u64)&vmrun_rip, rip_detected);
2011 			return true;
2012 		}
2013 		host_rflags_set_tf = false;
2014 		host_rflags_set_rf = false;
2015 		vmcb->save.rip += 3;
2016 		break;
2017 	default:
2018 		return true;
2019 	}
2020 	inc_test_stage(test);
2021 	return get_test_stage(test) == 5;
2022 }
2023 
2024 static bool host_rflags_check(struct svm_test *test)
2025 {
2026 	return get_test_stage(test) == 4;
2027 }
2028 
2029 #define TEST(name) { #name, .v2 = name }
2030 
2031 /*
2032  * v2 tests
2033  */
2034 
2035 /*
2036  * Ensure that kvm recalculates the L1 guest's CPUID.01H:ECX.OSXSAVE
2037  * after VM-exit from an L2 guest that sets CR4.OSXSAVE to a different
2038  * value than in L1.
2039  */
2040 
2041 static void svm_cr4_osxsave_test_guest(struct svm_test *test)
2042 {
2043 	write_cr4(read_cr4() & ~X86_CR4_OSXSAVE);
2044 }
2045 
2046 static void svm_cr4_osxsave_test(void)
2047 {
2048 	if (!this_cpu_has(X86_FEATURE_XSAVE)) {
2049 		report_skip("XSAVE not detected");
2050 		return;
2051 	}
2052 
2053 	if (!(read_cr4() & X86_CR4_OSXSAVE)) {
2054 		unsigned long cr4 = read_cr4() | X86_CR4_OSXSAVE;
2055 
2056 		write_cr4(cr4);
2057 		vmcb->save.cr4 = cr4;
2058 	}
2059 
2060 	report(this_cpu_has(X86_FEATURE_OSXSAVE), "CPUID.01H:ECX.XSAVE set before VMRUN");
2061 
2062 	test_set_guest(svm_cr4_osxsave_test_guest);
2063 	report(svm_vmrun() == SVM_EXIT_VMMCALL,
2064 	       "svm_cr4_osxsave_test_guest finished with VMMCALL");
2065 
2066 	report(this_cpu_has(X86_FEATURE_OSXSAVE), "CPUID.01H:ECX.XSAVE set after VMRUN");
2067 }
2068 
2069 static void basic_guest_main(struct svm_test *test)
2070 {
2071 }
2072 
2073 
2074 #define SVM_TEST_REG_RESERVED_BITS(start, end, inc, str_name, reg, val,	\
2075 				   resv_mask)				\
2076 {									\
2077 	u64 tmp, mask;							\
2078 	int i;								\
2079 									\
2080 	for (i = start; i <= end; i = i + inc) {			\
2081 		mask = 1ull << i;					\
2082 		if (!(mask & resv_mask))				\
2083 			continue;					\
2084 		tmp = val | mask;					\
2085 		reg = tmp;						\
2086 		report(svm_vmrun() == SVM_EXIT_ERR, "Test %s %d:%d: %lx", \
2087 		       str_name, end, start, tmp);			\
2088 	}								\
2089 }
2090 
2091 #define SVM_TEST_CR_RESERVED_BITS(start, end, inc, cr, val, resv_mask,	\
2092 				  exit_code, test_name)			\
2093 {									\
2094 	u64 tmp, mask;							\
2095 	u32 r;								\
2096 	int i;								\
2097 									\
2098 	for (i = start; i <= end; i = i + inc) {			\
2099 		mask = 1ull << i;					\
2100 		if (!(mask & resv_mask))				\
2101 			continue;					\
2102 		tmp = val | mask;					\
2103 		switch (cr) {						\
2104 		case 0:							\
2105 			vmcb->save.cr0 = tmp;				\
2106 			break;						\
2107 		case 3:							\
2108 			vmcb->save.cr3 = tmp;				\
2109 			break;						\
2110 		case 4:							\
2111 			vmcb->save.cr4 = tmp;				\
2112 		}							\
2113 		r = svm_vmrun();					\
2114 		report(r == exit_code, "Test CR%d %s%d:%d: %lx, wanted exit 0x%x, got 0x%x", \
2115 		       cr, test_name, end, start, tmp, exit_code, r);	\
2116 	}								\
2117 }
2118 
2119 static void test_efer(void)
2120 {
2121 	/*
2122 	 * Un-setting EFER.SVME is illegal
2123 	 */
2124 	u64 efer_saved = vmcb->save.efer;
2125 	u64 efer = efer_saved;
2126 
2127 	report (svm_vmrun() == SVM_EXIT_VMMCALL, "EFER.SVME: %lx", efer);
2128 	efer &= ~EFER_SVME;
2129 	vmcb->save.efer = efer;
2130 	report (svm_vmrun() == SVM_EXIT_ERR, "EFER.SVME: %lx", efer);
2131 	vmcb->save.efer = efer_saved;
2132 
2133 	/*
2134 	 * EFER MBZ bits: 63:16, 9
2135 	 */
2136 	efer_saved = vmcb->save.efer;
2137 
2138 	SVM_TEST_REG_RESERVED_BITS(8, 9, 1, "EFER", vmcb->save.efer,
2139 				   efer_saved, SVM_EFER_RESERVED_MASK);
2140 	SVM_TEST_REG_RESERVED_BITS(16, 63, 4, "EFER", vmcb->save.efer,
2141 				   efer_saved, SVM_EFER_RESERVED_MASK);
2142 
2143 	/*
2144 	 * EFER.LME and CR0.PG are both set and CR4.PAE is zero.
2145 	 */
2146 	u64 cr0_saved = vmcb->save.cr0;
2147 	u64 cr0;
2148 	u64 cr4_saved = vmcb->save.cr4;
2149 	u64 cr4;
2150 
2151 	efer = efer_saved | EFER_LME;
2152 	vmcb->save.efer = efer;
2153 	cr0 = cr0_saved | X86_CR0_PG | X86_CR0_PE;
2154 	vmcb->save.cr0 = cr0;
2155 	cr4 = cr4_saved & ~X86_CR4_PAE;
2156 	vmcb->save.cr4 = cr4;
2157 	report(svm_vmrun() == SVM_EXIT_ERR, "EFER.LME=1 (%lx), "
2158 	       "CR0.PG=1 (%lx) and CR4.PAE=0 (%lx)", efer, cr0, cr4);
2159 
2160 	/*
2161 	 * EFER.LME and CR0.PG are both set and CR0.PE is zero.
2162 	 * CR4.PAE needs to be set as we otherwise cannot
2163 	 * determine if CR4.PAE=0 or CR0.PE=0 triggered the
2164 	 * SVM_EXIT_ERR.
2165 	 */
2166 	cr4 = cr4_saved | X86_CR4_PAE;
2167 	vmcb->save.cr4 = cr4;
2168 	cr0 &= ~X86_CR0_PE;
2169 	vmcb->save.cr0 = cr0;
2170 	report(svm_vmrun() == SVM_EXIT_ERR, "EFER.LME=1 (%lx), "
2171 	       "CR0.PG=1 and CR0.PE=0 (%lx)", efer, cr0);
2172 
2173 	/*
2174 	 * EFER.LME, CR0.PG, CR4.PAE, CS.L, and CS.D are all non-zero.
2175 	 */
2176 	u32 cs_attrib_saved = vmcb->save.cs.attrib;
2177 	u32 cs_attrib;
2178 
2179 	cr0 |= X86_CR0_PE;
2180 	vmcb->save.cr0 = cr0;
2181 	cs_attrib = cs_attrib_saved | SVM_SELECTOR_L_MASK |
2182 		SVM_SELECTOR_DB_MASK;
2183 	vmcb->save.cs.attrib = cs_attrib;
2184 	report(svm_vmrun() == SVM_EXIT_ERR, "EFER.LME=1 (%lx), "
2185 	       "CR0.PG=1 (%lx), CR4.PAE=1 (%lx), CS.L=1 and CS.D=1 (%x)",
2186 	       efer, cr0, cr4, cs_attrib);
2187 
2188 	vmcb->save.cr0 = cr0_saved;
2189 	vmcb->save.cr4 = cr4_saved;
2190 	vmcb->save.efer = efer_saved;
2191 	vmcb->save.cs.attrib = cs_attrib_saved;
2192 }
2193 
2194 static void test_cr0(void)
2195 {
2196 	/*
2197 	 * Un-setting CR0.CD and setting CR0.NW is illegal combination
2198 	 */
2199 	u64 cr0_saved = vmcb->save.cr0;
2200 	u64 cr0 = cr0_saved;
2201 
2202 	cr0 |= X86_CR0_CD;
2203 	cr0 &= ~X86_CR0_NW;
2204 	vmcb->save.cr0 = cr0;
2205 	report (svm_vmrun() == SVM_EXIT_VMMCALL, "Test CR0 CD=1,NW=0: %lx",
2206 		cr0);
2207 	cr0 |= X86_CR0_NW;
2208 	vmcb->save.cr0 = cr0;
2209 	report (svm_vmrun() == SVM_EXIT_VMMCALL, "Test CR0 CD=1,NW=1: %lx",
2210 		cr0);
2211 	cr0 &= ~X86_CR0_NW;
2212 	cr0 &= ~X86_CR0_CD;
2213 	vmcb->save.cr0 = cr0;
2214 	report (svm_vmrun() == SVM_EXIT_VMMCALL, "Test CR0 CD=0,NW=0: %lx",
2215 		cr0);
2216 	cr0 |= X86_CR0_NW;
2217 	vmcb->save.cr0 = cr0;
2218 	report (svm_vmrun() == SVM_EXIT_ERR, "Test CR0 CD=0,NW=1: %lx",
2219 		cr0);
2220 	vmcb->save.cr0 = cr0_saved;
2221 
2222 	/*
2223 	 * CR0[63:32] are not zero
2224 	 */
2225 	cr0 = cr0_saved;
2226 
2227 	SVM_TEST_REG_RESERVED_BITS(32, 63, 4, "CR0", vmcb->save.cr0, cr0_saved,
2228 				   SVM_CR0_RESERVED_MASK);
2229 	vmcb->save.cr0 = cr0_saved;
2230 }
2231 
2232 static void test_cr3(void)
2233 {
2234 	/*
2235 	 * CR3 MBZ bits based on different modes:
2236 	 *   [63:52] - long mode
2237 	 */
2238 	u64 cr3_saved = vmcb->save.cr3;
2239 
2240 	SVM_TEST_CR_RESERVED_BITS(0, 63, 1, 3, cr3_saved,
2241 				  SVM_CR3_LONG_MBZ_MASK, SVM_EXIT_ERR, "");
2242 
2243 	vmcb->save.cr3 = cr3_saved & ~SVM_CR3_LONG_MBZ_MASK;
2244 	report(svm_vmrun() == SVM_EXIT_VMMCALL, "Test CR3 63:0: %lx",
2245 	       vmcb->save.cr3);
2246 
2247 	/*
2248 	 * CR3 non-MBZ reserved bits based on different modes:
2249 	 *   [11:5] [2:0] - long mode (PCIDE=0)
2250 	 *          [2:0] - PAE legacy mode
2251 	 */
2252 	u64 cr4_saved = vmcb->save.cr4;
2253 	u64 *pdpe = npt_get_pml4e();
2254 
2255 	/*
2256 	 * Long mode
2257 	 */
2258 	if (this_cpu_has(X86_FEATURE_PCID)) {
2259 		vmcb->save.cr4 = cr4_saved | X86_CR4_PCIDE;
2260 		SVM_TEST_CR_RESERVED_BITS(0, 11, 1, 3, cr3_saved,
2261 					  SVM_CR3_LONG_RESERVED_MASK, SVM_EXIT_VMMCALL, "(PCIDE=1) ");
2262 
2263 		vmcb->save.cr3 = cr3_saved & ~SVM_CR3_LONG_RESERVED_MASK;
2264 		report(svm_vmrun() == SVM_EXIT_VMMCALL, "Test CR3 63:0: %lx",
2265 		       vmcb->save.cr3);
2266 	}
2267 
2268 	vmcb->save.cr4 = cr4_saved & ~X86_CR4_PCIDE;
2269 
2270 	if (!npt_supported())
2271 		goto skip_npt_only;
2272 
2273 	/* Clear P (Present) bit in NPT in order to trigger #NPF */
2274 	pdpe[0] &= ~1ULL;
2275 
2276 	SVM_TEST_CR_RESERVED_BITS(0, 11, 1, 3, cr3_saved,
2277 				  SVM_CR3_LONG_RESERVED_MASK, SVM_EXIT_NPF, "(PCIDE=0) ");
2278 
2279 	pdpe[0] |= 1ULL;
2280 	vmcb->save.cr3 = cr3_saved;
2281 
2282 	/*
2283 	 * PAE legacy
2284 	 */
2285 	pdpe[0] &= ~1ULL;
2286 	vmcb->save.cr4 = cr4_saved | X86_CR4_PAE;
2287 	SVM_TEST_CR_RESERVED_BITS(0, 2, 1, 3, cr3_saved,
2288 				  SVM_CR3_PAE_LEGACY_RESERVED_MASK, SVM_EXIT_NPF, "(PAE) ");
2289 
2290 	pdpe[0] |= 1ULL;
2291 
2292 skip_npt_only:
2293 	vmcb->save.cr3 = cr3_saved;
2294 	vmcb->save.cr4 = cr4_saved;
2295 }
2296 
2297 /* Test CR4 MBZ bits based on legacy or long modes */
2298 static void test_cr4(void)
2299 {
2300 	u64 cr4_saved = vmcb->save.cr4;
2301 	u64 efer_saved = vmcb->save.efer;
2302 	u64 efer = efer_saved;
2303 
2304 	efer &= ~EFER_LME;
2305 	vmcb->save.efer = efer;
2306 	SVM_TEST_CR_RESERVED_BITS(12, 31, 1, 4, cr4_saved,
2307 				  SVM_CR4_LEGACY_RESERVED_MASK, SVM_EXIT_ERR, "");
2308 
2309 	efer |= EFER_LME;
2310 	vmcb->save.efer = efer;
2311 	SVM_TEST_CR_RESERVED_BITS(12, 31, 1, 4, cr4_saved,
2312 				  SVM_CR4_RESERVED_MASK, SVM_EXIT_ERR, "");
2313 	SVM_TEST_CR_RESERVED_BITS(32, 63, 4, 4, cr4_saved,
2314 				  SVM_CR4_RESERVED_MASK, SVM_EXIT_ERR, "");
2315 
2316 	vmcb->save.cr4 = cr4_saved;
2317 	vmcb->save.efer = efer_saved;
2318 }
2319 
2320 static void test_dr(void)
2321 {
2322 	/*
2323 	 * DR6[63:32] and DR7[63:32] are MBZ
2324 	 */
2325 	u64 dr_saved = vmcb->save.dr6;
2326 
2327 	SVM_TEST_REG_RESERVED_BITS(32, 63, 4, "DR6", vmcb->save.dr6, dr_saved,
2328 				   SVM_DR6_RESERVED_MASK);
2329 	vmcb->save.dr6 = dr_saved;
2330 
2331 	dr_saved = vmcb->save.dr7;
2332 	SVM_TEST_REG_RESERVED_BITS(32, 63, 4, "DR7", vmcb->save.dr7, dr_saved,
2333 				   SVM_DR7_RESERVED_MASK);
2334 
2335 	vmcb->save.dr7 = dr_saved;
2336 }
2337 
2338 /* TODO: verify if high 32-bits are sign- or zero-extended on bare metal */
2339 #define	TEST_BITMAP_ADDR(save_intercept, type, addr, exit_code,		\
2340 			 msg) {						\
2341 		vmcb->control.intercept = saved_intercept | 1ULL << type; \
2342 		if (type == INTERCEPT_MSR_PROT)				\
2343 			vmcb->control.msrpm_base_pa = addr;		\
2344 		else							\
2345 			vmcb->control.iopm_base_pa = addr;		\
2346 		report(svm_vmrun() == exit_code,			\
2347 		       "Test %s address: %lx", msg, addr);		\
2348 	}
2349 
2350 /*
2351  * If the MSR or IOIO intercept table extends to a physical address that
2352  * is greater than or equal to the maximum supported physical address, the
2353  * guest state is illegal.
2354  *
2355  * The VMRUN instruction ignores the lower 12 bits of the address specified
2356  * in the VMCB.
2357  *
2358  * MSRPM spans 2 contiguous 4KB pages while IOPM spans 2 contiguous 4KB
2359  * pages + 1 byte.
2360  *
2361  * [APM vol 2]
2362  *
2363  * Note: Unallocated MSRPM addresses conforming to consistency checks, generate
2364  * #NPF.
2365  */
2366 static void test_msrpm_iopm_bitmap_addrs(void)
2367 {
2368 	u64 saved_intercept = vmcb->control.intercept;
2369 	u64 addr_beyond_limit = 1ull << cpuid_maxphyaddr();
2370 	u64 addr = virt_to_phys(msr_bitmap) & (~((1ull << 12) - 1));
2371 
2372 	TEST_BITMAP_ADDR(saved_intercept, INTERCEPT_MSR_PROT,
2373 			 addr_beyond_limit - 2 * PAGE_SIZE, SVM_EXIT_ERR,
2374 			 "MSRPM");
2375 	TEST_BITMAP_ADDR(saved_intercept, INTERCEPT_MSR_PROT,
2376 			 addr_beyond_limit - 2 * PAGE_SIZE + 1, SVM_EXIT_ERR,
2377 			 "MSRPM");
2378 	TEST_BITMAP_ADDR(saved_intercept, INTERCEPT_MSR_PROT,
2379 			 addr_beyond_limit - PAGE_SIZE, SVM_EXIT_ERR,
2380 			 "MSRPM");
2381 	TEST_BITMAP_ADDR(saved_intercept, INTERCEPT_MSR_PROT, addr,
2382 			 SVM_EXIT_VMMCALL, "MSRPM");
2383 	addr |= (1ull << 12) - 1;
2384 	TEST_BITMAP_ADDR(saved_intercept, INTERCEPT_MSR_PROT, addr,
2385 			 SVM_EXIT_VMMCALL, "MSRPM");
2386 
2387 	TEST_BITMAP_ADDR(saved_intercept, INTERCEPT_IOIO_PROT,
2388 			 addr_beyond_limit - 4 * PAGE_SIZE, SVM_EXIT_VMMCALL,
2389 			 "IOPM");
2390 	TEST_BITMAP_ADDR(saved_intercept, INTERCEPT_IOIO_PROT,
2391 			 addr_beyond_limit - 3 * PAGE_SIZE, SVM_EXIT_VMMCALL,
2392 			 "IOPM");
2393 	TEST_BITMAP_ADDR(saved_intercept, INTERCEPT_IOIO_PROT,
2394 			 addr_beyond_limit - 2 * PAGE_SIZE - 2, SVM_EXIT_VMMCALL,
2395 			 "IOPM");
2396 	TEST_BITMAP_ADDR(saved_intercept, INTERCEPT_IOIO_PROT,
2397 			 addr_beyond_limit - 2 * PAGE_SIZE, SVM_EXIT_ERR,
2398 			 "IOPM");
2399 	TEST_BITMAP_ADDR(saved_intercept, INTERCEPT_IOIO_PROT,
2400 			 addr_beyond_limit - PAGE_SIZE, SVM_EXIT_ERR,
2401 			 "IOPM");
2402 	addr = virt_to_phys(io_bitmap) & (~((1ull << 11) - 1));
2403 	TEST_BITMAP_ADDR(saved_intercept, INTERCEPT_IOIO_PROT, addr,
2404 			 SVM_EXIT_VMMCALL, "IOPM");
2405 	addr |= (1ull << 12) - 1;
2406 	TEST_BITMAP_ADDR(saved_intercept, INTERCEPT_IOIO_PROT, addr,
2407 			 SVM_EXIT_VMMCALL, "IOPM");
2408 
2409 	vmcb->control.intercept = saved_intercept;
2410 }
2411 
2412 /*
2413  * Unlike VMSAVE, VMRUN seems not to update the value of noncanonical
2414  * segment bases in the VMCB.  However, VMENTRY succeeds as documented.
2415  */
2416 #define TEST_CANONICAL_VMRUN(seg_base, msg)				\
2417 	saved_addr = seg_base;						\
2418 	seg_base = (seg_base & ((1ul << addr_limit) - 1)) | noncanonical_mask; \
2419 	return_value = svm_vmrun();					\
2420 	report(return_value == SVM_EXIT_VMMCALL,			\
2421 	       "Successful VMRUN with noncanonical %s.base", msg);	\
2422 	seg_base = saved_addr;
2423 
2424 
2425 #define TEST_CANONICAL_VMLOAD(seg_base, msg)				\
2426 	saved_addr = seg_base;						\
2427 	seg_base = (seg_base & ((1ul << addr_limit) - 1)) | noncanonical_mask; \
2428 	asm volatile ("vmload %0" : : "a"(vmcb_phys) : "memory");	\
2429 	asm volatile ("vmsave %0" : : "a"(vmcb_phys) : "memory");	\
2430 	report(is_canonical(seg_base),					\
2431 	       "Test %s.base for canonical form: %lx", msg, seg_base);	\
2432 	seg_base = saved_addr;
2433 
2434 static void test_canonicalization(void)
2435 {
2436 	u64 saved_addr;
2437 	u64 return_value;
2438 	u64 addr_limit;
2439 	u64 vmcb_phys = virt_to_phys(vmcb);
2440 
2441 	addr_limit = (this_cpu_has(X86_FEATURE_LA57)) ? 57 : 48;
2442 	u64 noncanonical_mask = NONCANONICAL & ~((1ul << addr_limit) - 1);
2443 
2444 	TEST_CANONICAL_VMLOAD(vmcb->save.fs.base, "FS");
2445 	TEST_CANONICAL_VMLOAD(vmcb->save.gs.base, "GS");
2446 	TEST_CANONICAL_VMLOAD(vmcb->save.ldtr.base, "LDTR");
2447 	TEST_CANONICAL_VMLOAD(vmcb->save.tr.base, "TR");
2448 	TEST_CANONICAL_VMLOAD(vmcb->save.kernel_gs_base, "KERNEL GS");
2449 	TEST_CANONICAL_VMRUN(vmcb->save.es.base, "ES");
2450 	TEST_CANONICAL_VMRUN(vmcb->save.cs.base, "CS");
2451 	TEST_CANONICAL_VMRUN(vmcb->save.ss.base, "SS");
2452 	TEST_CANONICAL_VMRUN(vmcb->save.ds.base, "DS");
2453 	TEST_CANONICAL_VMRUN(vmcb->save.gdtr.base, "GDTR");
2454 	TEST_CANONICAL_VMRUN(vmcb->save.idtr.base, "IDTR");
2455 }
2456 
2457 /*
2458  * When VMRUN loads a guest value of 1 in EFLAGS.TF, that value does not
2459  * cause a trace trap between the VMRUN and the first guest instruction, but
2460  * rather after completion of the first guest instruction.
2461  *
2462  * [APM vol 2]
2463  */
2464 u64 guest_rflags_test_trap_rip;
2465 
2466 static void guest_rflags_test_db_handler(struct ex_regs *r)
2467 {
2468 	guest_rflags_test_trap_rip = r->rip;
2469 	r->rflags &= ~X86_EFLAGS_TF;
2470 }
2471 
2472 static void svm_guest_state_test(void)
2473 {
2474 	test_set_guest(basic_guest_main);
2475 	test_efer();
2476 	test_cr0();
2477 	test_cr3();
2478 	test_cr4();
2479 	test_dr();
2480 	test_msrpm_iopm_bitmap_addrs();
2481 	test_canonicalization();
2482 }
2483 
2484 extern void guest_rflags_test_guest(struct svm_test *test);
2485 extern u64 *insn2;
2486 extern u64 *guest_end;
2487 
2488 asm("guest_rflags_test_guest:\n\t"
2489     "push %rbp\n\t"
2490     ".global insn2\n\t"
2491     "insn2:\n\t"
2492     "mov %rsp,%rbp\n\t"
2493     "vmmcall\n\t"
2494     "vmmcall\n\t"
2495     ".global guest_end\n\t"
2496     "guest_end:\n\t"
2497     "vmmcall\n\t"
2498     "pop %rbp\n\t"
2499     "ret");
2500 
2501 static void svm_test_singlestep(void)
2502 {
2503 	handle_exception(DB_VECTOR, guest_rflags_test_db_handler);
2504 
2505 	/*
2506 	 * Trap expected after completion of first guest instruction
2507 	 */
2508 	vmcb->save.rflags |= X86_EFLAGS_TF;
2509 	report (__svm_vmrun((u64)guest_rflags_test_guest) == SVM_EXIT_VMMCALL &&
2510 		guest_rflags_test_trap_rip == (u64)&insn2,
2511 		"Test EFLAGS.TF on VMRUN: trap expected  after completion of first guest instruction");
2512 	/*
2513 	 * No trap expected
2514 	 */
2515 	guest_rflags_test_trap_rip = 0;
2516 	vmcb->save.rip += 3;
2517 	vmcb->save.rflags |= X86_EFLAGS_TF;
2518 	report (__svm_vmrun(vmcb->save.rip) == SVM_EXIT_VMMCALL &&
2519 		guest_rflags_test_trap_rip == 0, "Test EFLAGS.TF on VMRUN: trap not expected");
2520 
2521 	/*
2522 	 * Let guest finish execution
2523 	 */
2524 	vmcb->save.rip += 3;
2525 	report (__svm_vmrun(vmcb->save.rip) == SVM_EXIT_VMMCALL &&
2526 		vmcb->save.rip == (u64)&guest_end, "Test EFLAGS.TF on VMRUN: guest execution completion");
2527 }
2528 
2529 static bool volatile svm_errata_reproduced = false;
2530 static unsigned long volatile physical = 0;
2531 
2532 
2533 /*
2534  *
2535  * Test the following errata:
2536  * If the VMRUN/VMSAVE/VMLOAD are attempted by the nested guest,
2537  * the CPU would first check the EAX against host reserved memory
2538  * regions (so far only SMM_ADDR/SMM_MASK are known to cause it),
2539  * and only then signal #VMexit
2540  *
2541  * Try to reproduce this by trying vmsave on each possible 4K aligned memory
2542  * address in the low 4G where the SMM area has to reside.
2543  */
2544 
2545 static void gp_isr(struct ex_regs *r)
2546 {
2547 	svm_errata_reproduced = true;
2548 	/* skip over the vmsave instruction*/
2549 	r->rip += 3;
2550 }
2551 
2552 static void svm_vmrun_errata_test(void)
2553 {
2554 	unsigned long *last_page = NULL;
2555 
2556 	handle_exception(GP_VECTOR, gp_isr);
2557 
2558 	while (!svm_errata_reproduced) {
2559 
2560 		unsigned long *page = alloc_pages(1);
2561 
2562 		if (!page) {
2563 			report_pass("All guest memory tested, no bug found");
2564 			break;
2565 		}
2566 
2567 		physical = virt_to_phys(page);
2568 
2569 		asm volatile (
2570 			      "mov %[_physical], %%rax\n\t"
2571 			      "vmsave %%rax\n\t"
2572 
2573 			      : [_physical] "=m" (physical)
2574 			      : /* no inputs*/
2575 			      : "rax" /*clobbers*/
2576 			      );
2577 
2578 		if (svm_errata_reproduced) {
2579 			report_fail("Got #GP exception - svm errata reproduced at 0x%lx",
2580 				    physical);
2581 			break;
2582 		}
2583 
2584 		*page = (unsigned long)last_page;
2585 		last_page = page;
2586 	}
2587 
2588 	while (last_page) {
2589 		unsigned long *page = last_page;
2590 		last_page = (unsigned long *)*last_page;
2591 		free_pages_by_order(page, 1);
2592 	}
2593 }
2594 
2595 static void vmload_vmsave_guest_main(struct svm_test *test)
2596 {
2597 	u64 vmcb_phys = virt_to_phys(vmcb);
2598 
2599 	asm volatile ("vmload %0" : : "a"(vmcb_phys));
2600 	asm volatile ("vmsave %0" : : "a"(vmcb_phys));
2601 }
2602 
2603 static void svm_vmload_vmsave(void)
2604 {
2605 	u32 intercept_saved = vmcb->control.intercept;
2606 
2607 	test_set_guest(vmload_vmsave_guest_main);
2608 
2609 	/*
2610 	 * Disabling intercept for VMLOAD and VMSAVE doesn't cause
2611 	 * respective #VMEXIT to host
2612 	 */
2613 	vmcb->control.intercept &= ~(1ULL << INTERCEPT_VMLOAD);
2614 	vmcb->control.intercept &= ~(1ULL << INTERCEPT_VMSAVE);
2615 	svm_vmrun();
2616 	report(vmcb->control.exit_code == SVM_EXIT_VMMCALL, "Test "
2617 	       "VMLOAD/VMSAVE intercept: Expected VMMCALL #VMEXIT");
2618 
2619 	/*
2620 	 * Enabling intercept for VMLOAD and VMSAVE causes respective
2621 	 * #VMEXIT to host
2622 	 */
2623 	vmcb->control.intercept |= (1ULL << INTERCEPT_VMLOAD);
2624 	svm_vmrun();
2625 	report(vmcb->control.exit_code == SVM_EXIT_VMLOAD, "Test "
2626 	       "VMLOAD/VMSAVE intercept: Expected VMLOAD #VMEXIT");
2627 	vmcb->control.intercept &= ~(1ULL << INTERCEPT_VMLOAD);
2628 	vmcb->control.intercept |= (1ULL << INTERCEPT_VMSAVE);
2629 	svm_vmrun();
2630 	report(vmcb->control.exit_code == SVM_EXIT_VMSAVE, "Test "
2631 	       "VMLOAD/VMSAVE intercept: Expected VMSAVE #VMEXIT");
2632 	vmcb->control.intercept &= ~(1ULL << INTERCEPT_VMSAVE);
2633 	svm_vmrun();
2634 	report(vmcb->control.exit_code == SVM_EXIT_VMMCALL, "Test "
2635 	       "VMLOAD/VMSAVE intercept: Expected VMMCALL #VMEXIT");
2636 
2637 	vmcb->control.intercept |= (1ULL << INTERCEPT_VMLOAD);
2638 	svm_vmrun();
2639 	report(vmcb->control.exit_code == SVM_EXIT_VMLOAD, "Test "
2640 	       "VMLOAD/VMSAVE intercept: Expected VMLOAD #VMEXIT");
2641 	vmcb->control.intercept &= ~(1ULL << INTERCEPT_VMLOAD);
2642 	svm_vmrun();
2643 	report(vmcb->control.exit_code == SVM_EXIT_VMMCALL, "Test "
2644 	       "VMLOAD/VMSAVE intercept: Expected VMMCALL #VMEXIT");
2645 
2646 	vmcb->control.intercept |= (1ULL << INTERCEPT_VMSAVE);
2647 	svm_vmrun();
2648 	report(vmcb->control.exit_code == SVM_EXIT_VMSAVE, "Test "
2649 	       "VMLOAD/VMSAVE intercept: Expected VMSAVE #VMEXIT");
2650 	vmcb->control.intercept &= ~(1ULL << INTERCEPT_VMSAVE);
2651 	svm_vmrun();
2652 	report(vmcb->control.exit_code == SVM_EXIT_VMMCALL, "Test "
2653 	       "VMLOAD/VMSAVE intercept: Expected VMMCALL #VMEXIT");
2654 
2655 	vmcb->control.intercept = intercept_saved;
2656 }
2657 
2658 static void prepare_vgif_enabled(struct svm_test *test)
2659 {
2660 	default_prepare(test);
2661 }
2662 
2663 static void test_vgif(struct svm_test *test)
2664 {
2665 	asm volatile ("vmmcall\n\tstgi\n\tvmmcall\n\tclgi\n\tvmmcall\n\t");
2666 }
2667 
2668 static bool vgif_finished(struct svm_test *test)
2669 {
2670 	switch (get_test_stage(test))
2671 		{
2672 		case 0:
2673 			if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
2674 				report_fail("VMEXIT not due to vmmcall.");
2675 				return true;
2676 			}
2677 			vmcb->control.int_ctl |= V_GIF_ENABLED_MASK;
2678 			vmcb->save.rip += 3;
2679 			inc_test_stage(test);
2680 			break;
2681 		case 1:
2682 			if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
2683 				report_fail("VMEXIT not due to vmmcall.");
2684 				return true;
2685 			}
2686 			if (!(vmcb->control.int_ctl & V_GIF_MASK)) {
2687 				report_fail("Failed to set VGIF when executing STGI.");
2688 				vmcb->control.int_ctl &= ~V_GIF_ENABLED_MASK;
2689 				return true;
2690 			}
2691 			report_pass("STGI set VGIF bit.");
2692 			vmcb->save.rip += 3;
2693 			inc_test_stage(test);
2694 			break;
2695 		case 2:
2696 			if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
2697 				report_fail("VMEXIT not due to vmmcall.");
2698 				return true;
2699 			}
2700 			if (vmcb->control.int_ctl & V_GIF_MASK) {
2701 				report_fail("Failed to clear VGIF when executing CLGI.");
2702 				vmcb->control.int_ctl &= ~V_GIF_ENABLED_MASK;
2703 				return true;
2704 			}
2705 			report_pass("CLGI cleared VGIF bit.");
2706 			vmcb->save.rip += 3;
2707 			inc_test_stage(test);
2708 			vmcb->control.int_ctl &= ~V_GIF_ENABLED_MASK;
2709 			break;
2710 		default:
2711 			return true;
2712 			break;
2713 		}
2714 
2715 	return get_test_stage(test) == 3;
2716 }
2717 
2718 static bool vgif_check(struct svm_test *test)
2719 {
2720 	return get_test_stage(test) == 3;
2721 }
2722 
2723 
2724 static int pause_test_counter;
2725 static int wait_counter;
2726 
2727 static void pause_filter_test_guest_main(struct svm_test *test)
2728 {
2729 	int i;
2730 	for (i = 0 ; i < pause_test_counter ; i++)
2731 		pause();
2732 
2733 	if (!wait_counter)
2734 		return;
2735 
2736 	for (i = 0; i < wait_counter; i++)
2737 		;
2738 
2739 	for (i = 0 ; i < pause_test_counter ; i++)
2740 		pause();
2741 
2742 }
2743 
2744 static void pause_filter_run_test(int pause_iterations, int filter_value, int wait_iterations, int threshold)
2745 {
2746 	test_set_guest(pause_filter_test_guest_main);
2747 
2748 	pause_test_counter = pause_iterations;
2749 	wait_counter = wait_iterations;
2750 
2751 	vmcb->control.pause_filter_count = filter_value;
2752 	vmcb->control.pause_filter_thresh = threshold;
2753 	svm_vmrun();
2754 
2755 	if (filter_value <= pause_iterations || wait_iterations < threshold)
2756 		report(vmcb->control.exit_code == SVM_EXIT_PAUSE, "expected PAUSE vmexit");
2757 	else
2758 		report(vmcb->control.exit_code == SVM_EXIT_VMMCALL, "no expected PAUSE vmexit");
2759 }
2760 
2761 static void pause_filter_test(void)
2762 {
2763 	if (!pause_filter_supported()) {
2764 		report_skip("PAUSE filter not supported in the guest");
2765 		return;
2766 	}
2767 
2768 	vmcb->control.intercept |= (1 << INTERCEPT_PAUSE);
2769 
2770 	// filter count more that pause count - no VMexit
2771 	pause_filter_run_test(10, 9, 0, 0);
2772 
2773 	// filter count smaller pause count - no VMexit
2774 	pause_filter_run_test(20, 21, 0, 0);
2775 
2776 
2777 	if (pause_threshold_supported()) {
2778 		// filter count smaller pause count - no VMexit +  large enough threshold
2779 		// so that filter counter resets
2780 		pause_filter_run_test(20, 21, 1000, 10);
2781 
2782 		// filter count smaller pause count - no VMexit +  small threshold
2783 		// so that filter doesn't reset
2784 		pause_filter_run_test(20, 21, 10, 1000);
2785 	} else {
2786 		report_skip("PAUSE threshold not supported in the guest");
2787 		return;
2788 	}
2789 }
2790 
2791 /* If CR0.TS and CR0.EM are cleared in L2, no #NM is generated. */
2792 static void svm_no_nm_test(void)
2793 {
2794 	write_cr0(read_cr0() & ~X86_CR0_TS);
2795 	test_set_guest((test_guest_func)fnop);
2796 
2797 	vmcb->save.cr0 = vmcb->save.cr0 & ~(X86_CR0_TS | X86_CR0_EM);
2798 	report(svm_vmrun() == SVM_EXIT_VMMCALL,
2799 	       "fnop with CR0.TS and CR0.EM unset no #NM excpetion");
2800 }
2801 
2802 static bool check_lbr(u64 *from_excepted, u64 *to_expected)
2803 {
2804 	u64 from = rdmsr(MSR_IA32_LASTBRANCHFROMIP);
2805 	u64 to = rdmsr(MSR_IA32_LASTBRANCHTOIP);
2806 
2807 	if ((u64)from_excepted != from) {
2808 		report(false, "MSR_IA32_LASTBRANCHFROMIP, expected=0x%lx, actual=0x%lx",
2809 		       (u64)from_excepted, from);
2810 		return false;
2811 	}
2812 
2813 	if ((u64)to_expected != to) {
2814 		report(false, "MSR_IA32_LASTBRANCHFROMIP, expected=0x%lx, actual=0x%lx",
2815 		       (u64)from_excepted, from);
2816 		return false;
2817 	}
2818 
2819 	return true;
2820 }
2821 
2822 static bool check_dbgctl(u64 dbgctl, u64 dbgctl_expected)
2823 {
2824 	if (dbgctl != dbgctl_expected) {
2825 		report(false, "Unexpected MSR_IA32_DEBUGCTLMSR value 0x%lx", dbgctl);
2826 		return false;
2827 	}
2828 	return true;
2829 }
2830 
2831 
2832 #define DO_BRANCH(branch_name)				\
2833 	asm volatile (					\
2834 		      # branch_name "_from:"		\
2835 		      "jmp " # branch_name  "_to\n"	\
2836 		      "nop\n"				\
2837 		      "nop\n"				\
2838 		      # branch_name  "_to:"		\
2839 		      "nop\n"				\
2840 		       )
2841 
2842 
2843 extern u64 guest_branch0_from, guest_branch0_to;
2844 extern u64 guest_branch2_from, guest_branch2_to;
2845 
2846 extern u64 host_branch0_from, host_branch0_to;
2847 extern u64 host_branch2_from, host_branch2_to;
2848 extern u64 host_branch3_from, host_branch3_to;
2849 extern u64 host_branch4_from, host_branch4_to;
2850 
2851 u64 dbgctl;
2852 
2853 static void svm_lbrv_test_guest1(void)
2854 {
2855 	/*
2856 	 * This guest expects the LBR to be already enabled when it starts,
2857 	 * it does a branch, and then disables the LBR and then checks.
2858 	 */
2859 
2860 	DO_BRANCH(guest_branch0);
2861 
2862 	dbgctl = rdmsr(MSR_IA32_DEBUGCTLMSR);
2863 	wrmsr(MSR_IA32_DEBUGCTLMSR, 0);
2864 
2865 	if (dbgctl != DEBUGCTLMSR_LBR)
2866 		asm volatile("ud2\n");
2867 	if (rdmsr(MSR_IA32_DEBUGCTLMSR) != 0)
2868 		asm volatile("ud2\n");
2869 	if (rdmsr(MSR_IA32_LASTBRANCHFROMIP) != (u64)&guest_branch0_from)
2870 		asm volatile("ud2\n");
2871 	if (rdmsr(MSR_IA32_LASTBRANCHTOIP) != (u64)&guest_branch0_to)
2872 		asm volatile("ud2\n");
2873 
2874 	asm volatile ("vmmcall\n");
2875 }
2876 
2877 static void svm_lbrv_test_guest2(void)
2878 {
2879 	/*
2880 	 * This guest expects the LBR to be disabled when it starts,
2881 	 * enables it, does a branch, disables it and then checks.
2882 	 */
2883 
2884 	DO_BRANCH(guest_branch1);
2885 	dbgctl = rdmsr(MSR_IA32_DEBUGCTLMSR);
2886 
2887 	if (dbgctl != 0)
2888 		asm volatile("ud2\n");
2889 
2890 	if (rdmsr(MSR_IA32_LASTBRANCHFROMIP) != (u64)&host_branch2_from)
2891 		asm volatile("ud2\n");
2892 	if (rdmsr(MSR_IA32_LASTBRANCHTOIP) != (u64)&host_branch2_to)
2893 		asm volatile("ud2\n");
2894 
2895 
2896 	wrmsr(MSR_IA32_DEBUGCTLMSR, DEBUGCTLMSR_LBR);
2897 	dbgctl = rdmsr(MSR_IA32_DEBUGCTLMSR);
2898 	DO_BRANCH(guest_branch2);
2899 	wrmsr(MSR_IA32_DEBUGCTLMSR, 0);
2900 
2901 	if (dbgctl != DEBUGCTLMSR_LBR)
2902 		asm volatile("ud2\n");
2903 	if (rdmsr(MSR_IA32_LASTBRANCHFROMIP) != (u64)&guest_branch2_from)
2904 		asm volatile("ud2\n");
2905 	if (rdmsr(MSR_IA32_LASTBRANCHTOIP) != (u64)&guest_branch2_to)
2906 		asm volatile("ud2\n");
2907 
2908 	asm volatile ("vmmcall\n");
2909 }
2910 
2911 static void svm_lbrv_test0(void)
2912 {
2913 	report(true, "Basic LBR test");
2914 	wrmsr(MSR_IA32_DEBUGCTLMSR, DEBUGCTLMSR_LBR);
2915 	DO_BRANCH(host_branch0);
2916 	dbgctl = rdmsr(MSR_IA32_DEBUGCTLMSR);
2917 	wrmsr(MSR_IA32_DEBUGCTLMSR, 0);
2918 
2919 	check_dbgctl(dbgctl, DEBUGCTLMSR_LBR);
2920 	dbgctl = rdmsr(MSR_IA32_DEBUGCTLMSR);
2921 	check_dbgctl(dbgctl, 0);
2922 
2923 	check_lbr(&host_branch0_from, &host_branch0_to);
2924 }
2925 
2926 static void svm_lbrv_test1(void)
2927 {
2928 	report(true, "Test that without LBRV enabled, guest LBR state does 'leak' to the host(1)");
2929 
2930 	vmcb->save.rip = (ulong)svm_lbrv_test_guest1;
2931 	vmcb->control.virt_ext = 0;
2932 
2933 	wrmsr(MSR_IA32_DEBUGCTLMSR, DEBUGCTLMSR_LBR);
2934 	DO_BRANCH(host_branch1);
2935 	SVM_BARE_VMRUN;
2936 	dbgctl = rdmsr(MSR_IA32_DEBUGCTLMSR);
2937 
2938 	if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
2939 		report(false, "VMEXIT not due to vmmcall. Exit reason 0x%x",
2940 		       vmcb->control.exit_code);
2941 		return;
2942 	}
2943 
2944 	check_dbgctl(dbgctl, 0);
2945 	check_lbr(&guest_branch0_from, &guest_branch0_to);
2946 }
2947 
2948 static void svm_lbrv_test2(void)
2949 {
2950 	report(true, "Test that without LBRV enabled, guest LBR state does 'leak' to the host(2)");
2951 
2952 	vmcb->save.rip = (ulong)svm_lbrv_test_guest2;
2953 	vmcb->control.virt_ext = 0;
2954 
2955 	wrmsr(MSR_IA32_DEBUGCTLMSR, DEBUGCTLMSR_LBR);
2956 	DO_BRANCH(host_branch2);
2957 	wrmsr(MSR_IA32_DEBUGCTLMSR, 0);
2958 	SVM_BARE_VMRUN;
2959 	dbgctl = rdmsr(MSR_IA32_DEBUGCTLMSR);
2960 	wrmsr(MSR_IA32_DEBUGCTLMSR, 0);
2961 
2962 	if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
2963 		report(false, "VMEXIT not due to vmmcall. Exit reason 0x%x",
2964 		       vmcb->control.exit_code);
2965 		return;
2966 	}
2967 
2968 	check_dbgctl(dbgctl, 0);
2969 	check_lbr(&guest_branch2_from, &guest_branch2_to);
2970 }
2971 
2972 static void svm_lbrv_nested_test1(void)
2973 {
2974 	if (!lbrv_supported()) {
2975 		report_skip("LBRV not supported in the guest");
2976 		return;
2977 	}
2978 
2979 	report(true, "Test that with LBRV enabled, guest LBR state doesn't leak (1)");
2980 	vmcb->save.rip = (ulong)svm_lbrv_test_guest1;
2981 	vmcb->control.virt_ext = LBR_CTL_ENABLE_MASK;
2982 	vmcb->save.dbgctl = DEBUGCTLMSR_LBR;
2983 
2984 	wrmsr(MSR_IA32_DEBUGCTLMSR, DEBUGCTLMSR_LBR);
2985 	DO_BRANCH(host_branch3);
2986 	SVM_BARE_VMRUN;
2987 	dbgctl = rdmsr(MSR_IA32_DEBUGCTLMSR);
2988 	wrmsr(MSR_IA32_DEBUGCTLMSR, 0);
2989 
2990 	if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
2991 		report(false, "VMEXIT not due to vmmcall. Exit reason 0x%x",
2992 		       vmcb->control.exit_code);
2993 		return;
2994 	}
2995 
2996 	if (vmcb->save.dbgctl != 0) {
2997 		report(false, "unexpected virtual guest MSR_IA32_DEBUGCTLMSR value 0x%lx", vmcb->save.dbgctl);
2998 		return;
2999 	}
3000 
3001 	check_dbgctl(dbgctl, DEBUGCTLMSR_LBR);
3002 	check_lbr(&host_branch3_from, &host_branch3_to);
3003 }
3004 
3005 static void svm_lbrv_nested_test2(void)
3006 {
3007 	if (!lbrv_supported()) {
3008 		report_skip("LBRV not supported in the guest");
3009 		return;
3010 	}
3011 
3012 	report(true, "Test that with LBRV enabled, guest LBR state doesn't leak (2)");
3013 	vmcb->save.rip = (ulong)svm_lbrv_test_guest2;
3014 	vmcb->control.virt_ext = LBR_CTL_ENABLE_MASK;
3015 
3016 	vmcb->save.dbgctl = 0;
3017 	vmcb->save.br_from = (u64)&host_branch2_from;
3018 	vmcb->save.br_to = (u64)&host_branch2_to;
3019 
3020 	wrmsr(MSR_IA32_DEBUGCTLMSR, DEBUGCTLMSR_LBR);
3021 	DO_BRANCH(host_branch4);
3022 	SVM_BARE_VMRUN;
3023 	dbgctl = rdmsr(MSR_IA32_DEBUGCTLMSR);
3024 	wrmsr(MSR_IA32_DEBUGCTLMSR, 0);
3025 
3026 	if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
3027 		report(false, "VMEXIT not due to vmmcall. Exit reason 0x%x",
3028 		       vmcb->control.exit_code);
3029 		return;
3030 	}
3031 
3032 	check_dbgctl(dbgctl, DEBUGCTLMSR_LBR);
3033 	check_lbr(&host_branch4_from, &host_branch4_to);
3034 }
3035 
3036 
3037 // test that a nested guest which does enable INTR interception
3038 // but doesn't enable virtual interrupt masking works
3039 
3040 static volatile int dummy_isr_recevied;
3041 static void dummy_isr(isr_regs_t *regs)
3042 {
3043 	dummy_isr_recevied++;
3044 	eoi();
3045 }
3046 
3047 
3048 static volatile int nmi_recevied;
3049 static void dummy_nmi_handler(struct ex_regs *regs)
3050 {
3051 	nmi_recevied++;
3052 }
3053 
3054 
3055 static void svm_intr_intercept_mix_run_guest(volatile int *counter, int expected_vmexit)
3056 {
3057 	if (counter)
3058 		*counter = 0;
3059 
3060 	sti();  // host IF value should not matter
3061 	clgi(); // vmrun will set back GI to 1
3062 
3063 	svm_vmrun();
3064 
3065 	if (counter)
3066 		report(!*counter, "No interrupt expected");
3067 
3068 	stgi();
3069 
3070 	if (counter)
3071 		report(*counter == 1, "Interrupt is expected");
3072 
3073 	report (vmcb->control.exit_code == expected_vmexit, "Test expected VM exit");
3074 	report(vmcb->save.rflags & X86_EFLAGS_IF, "Guest should have EFLAGS.IF set now");
3075 	cli();
3076 }
3077 
3078 
3079 // subtest: test that enabling EFLAGS.IF is enought to trigger an interrupt
3080 static void svm_intr_intercept_mix_if_guest(struct svm_test *test)
3081 {
3082 	asm volatile("nop;nop;nop;nop");
3083 	report(!dummy_isr_recevied, "No interrupt expected");
3084 	sti();
3085 	asm volatile("nop");
3086 	report(0, "must not reach here");
3087 }
3088 
3089 static void svm_intr_intercept_mix_if(void)
3090 {
3091 	// make a physical interrupt to be pending
3092 	handle_irq(0x55, dummy_isr);
3093 
3094 	vmcb->control.intercept |= (1 << INTERCEPT_INTR);
3095 	vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK;
3096 	vmcb->save.rflags &= ~X86_EFLAGS_IF;
3097 
3098 	test_set_guest(svm_intr_intercept_mix_if_guest);
3099 	apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL | APIC_DM_FIXED | 0x55, 0);
3100 	svm_intr_intercept_mix_run_guest(&dummy_isr_recevied, SVM_EXIT_INTR);
3101 }
3102 
3103 
3104 // subtest: test that a clever guest can trigger an interrupt by setting GIF
3105 // if GIF is not intercepted
3106 static void svm_intr_intercept_mix_gif_guest(struct svm_test *test)
3107 {
3108 
3109 	asm volatile("nop;nop;nop;nop");
3110 	report(!dummy_isr_recevied, "No interrupt expected");
3111 
3112 	// clear GIF and enable IF
3113 	// that should still not cause VM exit
3114 	clgi();
3115 	sti();
3116 	asm volatile("nop");
3117 	report(!dummy_isr_recevied, "No interrupt expected");
3118 
3119 	stgi();
3120 	asm volatile("nop");
3121 	report(0, "must not reach here");
3122 }
3123 
3124 static void svm_intr_intercept_mix_gif(void)
3125 {
3126 	handle_irq(0x55, dummy_isr);
3127 
3128 	vmcb->control.intercept |= (1 << INTERCEPT_INTR);
3129 	vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK;
3130 	vmcb->save.rflags &= ~X86_EFLAGS_IF;
3131 
3132 	test_set_guest(svm_intr_intercept_mix_gif_guest);
3133 	apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL | APIC_DM_FIXED | 0x55, 0);
3134 	svm_intr_intercept_mix_run_guest(&dummy_isr_recevied, SVM_EXIT_INTR);
3135 }
3136 
3137 // subtest: test that a clever guest can trigger an interrupt by setting GIF
3138 // if GIF is not intercepted and interrupt comes after guest
3139 // started running
3140 static void svm_intr_intercept_mix_gif_guest2(struct svm_test *test)
3141 {
3142 	asm volatile("nop;nop;nop;nop");
3143 	report(!dummy_isr_recevied, "No interrupt expected");
3144 
3145 	clgi();
3146 	apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL | APIC_DM_FIXED | 0x55, 0);
3147 	report(!dummy_isr_recevied, "No interrupt expected");
3148 
3149 	stgi();
3150 	asm volatile("nop");
3151 	report(0, "must not reach here");
3152 }
3153 
3154 static void svm_intr_intercept_mix_gif2(void)
3155 {
3156 	handle_irq(0x55, dummy_isr);
3157 
3158 	vmcb->control.intercept |= (1 << INTERCEPT_INTR);
3159 	vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK;
3160 	vmcb->save.rflags |= X86_EFLAGS_IF;
3161 
3162 	test_set_guest(svm_intr_intercept_mix_gif_guest2);
3163 	svm_intr_intercept_mix_run_guest(&dummy_isr_recevied, SVM_EXIT_INTR);
3164 }
3165 
3166 
3167 // subtest: test that pending NMI will be handled when guest enables GIF
3168 static void svm_intr_intercept_mix_nmi_guest(struct svm_test *test)
3169 {
3170 	asm volatile("nop;nop;nop;nop");
3171 	report(!nmi_recevied, "No NMI expected");
3172 	cli(); // should have no effect
3173 
3174 	clgi();
3175 	asm volatile("nop");
3176 	apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL | APIC_DM_NMI, 0);
3177 	sti(); // should have no effect
3178 	asm volatile("nop");
3179 	report(!nmi_recevied, "No NMI expected");
3180 
3181 	stgi();
3182 	asm volatile("nop");
3183 	report(0, "must not reach here");
3184 }
3185 
3186 static void svm_intr_intercept_mix_nmi(void)
3187 {
3188 	handle_exception(2, dummy_nmi_handler);
3189 
3190 	vmcb->control.intercept |= (1 << INTERCEPT_NMI);
3191 	vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK;
3192 	vmcb->save.rflags |= X86_EFLAGS_IF;
3193 
3194 	test_set_guest(svm_intr_intercept_mix_nmi_guest);
3195 	svm_intr_intercept_mix_run_guest(&nmi_recevied, SVM_EXIT_NMI);
3196 }
3197 
3198 // test that pending SMI will be handled when guest enables GIF
3199 // TODO: can't really count #SMIs so just test that guest doesn't hang
3200 // and VMexits on SMI
3201 static void svm_intr_intercept_mix_smi_guest(struct svm_test *test)
3202 {
3203 	asm volatile("nop;nop;nop;nop");
3204 
3205 	clgi();
3206 	asm volatile("nop");
3207 	apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL | APIC_DM_SMI, 0);
3208 	sti(); // should have no effect
3209 	asm volatile("nop");
3210 	stgi();
3211 	asm volatile("nop");
3212 	report(0, "must not reach here");
3213 }
3214 
3215 static void svm_intr_intercept_mix_smi(void)
3216 {
3217 	vmcb->control.intercept |= (1 << INTERCEPT_SMI);
3218 	vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK;
3219 	test_set_guest(svm_intr_intercept_mix_smi_guest);
3220 	svm_intr_intercept_mix_run_guest(NULL, SVM_EXIT_SMI);
3221 }
3222 
3223 static void svm_l2_ac_test(void)
3224 {
3225 	bool hit_ac = false;
3226 
3227 	write_cr0(read_cr0() | X86_CR0_AM);
3228 	write_rflags(read_rflags() | X86_EFLAGS_AC);
3229 
3230 	run_in_user(generate_usermode_ac, AC_VECTOR, 0, 0, 0, 0, &hit_ac);
3231 	report(hit_ac, "Usermode #AC handled in L2");
3232 	vmmcall();
3233 }
3234 
3235 struct svm_exception_test {
3236 	u8 vector;
3237 	void (*guest_code)(void);
3238 };
3239 
3240 struct svm_exception_test svm_exception_tests[] = {
3241 	{ GP_VECTOR, generate_non_canonical_gp },
3242 	{ UD_VECTOR, generate_ud },
3243 	{ DE_VECTOR, generate_de },
3244 	{ DB_VECTOR, generate_single_step_db },
3245 	{ BP_VECTOR, generate_bp },
3246 	{ AC_VECTOR, svm_l2_ac_test },
3247 	{ OF_VECTOR, generate_of },
3248 	{ NM_VECTOR, generate_cr0_ts_nm },
3249 	{ NM_VECTOR, generate_cr0_em_nm },
3250 };
3251 
3252 static u8 svm_exception_test_vector;
3253 
3254 static void svm_exception_handler(struct ex_regs *regs)
3255 {
3256 	report(regs->vector == svm_exception_test_vector,
3257 		"Handling %s in L2's exception handler",
3258 		exception_mnemonic(svm_exception_test_vector));
3259 	vmmcall();
3260 }
3261 
3262 static void handle_exception_in_l2(u8 vector)
3263 {
3264 	handler old_handler = handle_exception(vector, svm_exception_handler);
3265 	svm_exception_test_vector = vector;
3266 
3267 	report(svm_vmrun() == SVM_EXIT_VMMCALL,
3268 		"%s handled by L2", exception_mnemonic(vector));
3269 
3270 	handle_exception(vector, old_handler);
3271 }
3272 
3273 static void handle_exception_in_l1(u32 vector)
3274 {
3275 	u32 old_ie = vmcb->control.intercept_exceptions;
3276 
3277 	vmcb->control.intercept_exceptions |= (1ULL << vector);
3278 
3279 	report(svm_vmrun() == (SVM_EXIT_EXCP_BASE + vector),
3280 		"%s handled by L1",  exception_mnemonic(vector));
3281 
3282 	vmcb->control.intercept_exceptions = old_ie;
3283 }
3284 
3285 static void svm_exception_test(void)
3286 {
3287 	struct svm_exception_test *t;
3288 	int i;
3289 
3290 	for (i = 0; i < ARRAY_SIZE(svm_exception_tests); i++) {
3291 		t = &svm_exception_tests[i];
3292 		test_set_guest((test_guest_func)t->guest_code);
3293 
3294 		handle_exception_in_l2(t->vector);
3295 		vmcb_ident(vmcb);
3296 
3297 		handle_exception_in_l1(t->vector);
3298 		vmcb_ident(vmcb);
3299 	}
3300 }
3301 
3302 struct svm_test svm_tests[] = {
3303 	{ "null", default_supported, default_prepare,
3304 	  default_prepare_gif_clear, null_test,
3305 	  default_finished, null_check },
3306 	{ "vmrun", default_supported, default_prepare,
3307 	  default_prepare_gif_clear, test_vmrun,
3308 	  default_finished, check_vmrun },
3309 	{ "ioio", default_supported, prepare_ioio,
3310 	  default_prepare_gif_clear, test_ioio,
3311 	  ioio_finished, check_ioio },
3312 	{ "vmrun intercept check", default_supported, prepare_no_vmrun_int,
3313 	  default_prepare_gif_clear, null_test, default_finished,
3314 	  check_no_vmrun_int },
3315 	{ "rsm", default_supported,
3316 	  prepare_rsm_intercept, default_prepare_gif_clear,
3317 	  test_rsm_intercept, finished_rsm_intercept, check_rsm_intercept },
3318 	{ "cr3 read intercept", default_supported,
3319 	  prepare_cr3_intercept, default_prepare_gif_clear,
3320 	  test_cr3_intercept, default_finished, check_cr3_intercept },
3321 	{ "cr3 read nointercept", default_supported, default_prepare,
3322 	  default_prepare_gif_clear, test_cr3_intercept, default_finished,
3323 	  check_cr3_nointercept },
3324 	{ "cr3 read intercept emulate", smp_supported,
3325 	  prepare_cr3_intercept_bypass, default_prepare_gif_clear,
3326 	  test_cr3_intercept_bypass, default_finished, check_cr3_intercept },
3327 	{ "dr intercept check", default_supported, prepare_dr_intercept,
3328 	  default_prepare_gif_clear, test_dr_intercept, dr_intercept_finished,
3329 	  check_dr_intercept },
3330 	{ "next_rip", next_rip_supported, prepare_next_rip,
3331 	  default_prepare_gif_clear, test_next_rip,
3332 	  default_finished, check_next_rip },
3333 	{ "msr intercept check", default_supported, prepare_msr_intercept,
3334 	  default_prepare_gif_clear, test_msr_intercept,
3335 	  msr_intercept_finished, check_msr_intercept },
3336 	{ "mode_switch", default_supported, prepare_mode_switch,
3337 	  default_prepare_gif_clear, test_mode_switch,
3338 	  mode_switch_finished, check_mode_switch },
3339 	{ "asid_zero", default_supported, prepare_asid_zero,
3340 	  default_prepare_gif_clear, test_asid_zero,
3341 	  default_finished, check_asid_zero },
3342 	{ "sel_cr0_bug", default_supported, sel_cr0_bug_prepare,
3343 	  default_prepare_gif_clear, sel_cr0_bug_test,
3344 	  sel_cr0_bug_finished, sel_cr0_bug_check },
3345 	{ "tsc_adjust", tsc_adjust_supported, tsc_adjust_prepare,
3346 	  default_prepare_gif_clear, tsc_adjust_test,
3347 	  default_finished, tsc_adjust_check },
3348 	{ "latency_run_exit", default_supported, latency_prepare,
3349 	  default_prepare_gif_clear, latency_test,
3350 	  latency_finished, latency_check },
3351 	{ "latency_run_exit_clean", default_supported, latency_prepare,
3352 	  default_prepare_gif_clear, latency_test,
3353 	  latency_finished_clean, latency_check },
3354 	{ "latency_svm_insn", default_supported, lat_svm_insn_prepare,
3355 	  default_prepare_gif_clear, null_test,
3356 	  lat_svm_insn_finished, lat_svm_insn_check },
3357 	{ "exc_inject", default_supported, exc_inject_prepare,
3358 	  default_prepare_gif_clear, exc_inject_test,
3359 	  exc_inject_finished, exc_inject_check },
3360 	{ "pending_event", default_supported, pending_event_prepare,
3361 	  default_prepare_gif_clear,
3362 	  pending_event_test, pending_event_finished, pending_event_check },
3363 	{ "pending_event_cli", default_supported, pending_event_cli_prepare,
3364 	  pending_event_cli_prepare_gif_clear,
3365 	  pending_event_cli_test, pending_event_cli_finished,
3366 	  pending_event_cli_check },
3367 	{ "interrupt", default_supported, interrupt_prepare,
3368 	  default_prepare_gif_clear, interrupt_test,
3369 	  interrupt_finished, interrupt_check },
3370 	{ "nmi", default_supported, nmi_prepare,
3371 	  default_prepare_gif_clear, nmi_test,
3372 	  nmi_finished, nmi_check },
3373 	{ "nmi_hlt", smp_supported, nmi_prepare,
3374 	  default_prepare_gif_clear, nmi_hlt_test,
3375 	  nmi_hlt_finished, nmi_hlt_check },
3376         { "vnmi", vnmi_supported, vnmi_prepare,
3377           default_prepare_gif_clear, vnmi_test,
3378           vnmi_finished, vnmi_check },
3379 	{ "virq_inject", default_supported, virq_inject_prepare,
3380 	  default_prepare_gif_clear, virq_inject_test,
3381 	  virq_inject_finished, virq_inject_check },
3382 	{ "reg_corruption", default_supported, reg_corruption_prepare,
3383 	  default_prepare_gif_clear, reg_corruption_test,
3384 	  reg_corruption_finished, reg_corruption_check },
3385 	{ "svm_init_startup_test", smp_supported, init_startup_prepare,
3386 	  default_prepare_gif_clear, null_test,
3387 	  init_startup_finished, init_startup_check },
3388 	{ "svm_init_intercept_test", smp_supported, init_intercept_prepare,
3389 	  default_prepare_gif_clear, init_intercept_test,
3390 	  init_intercept_finished, init_intercept_check, .on_vcpu = 2 },
3391 	{ "host_rflags", default_supported, host_rflags_prepare,
3392 	  host_rflags_prepare_gif_clear, host_rflags_test,
3393 	  host_rflags_finished, host_rflags_check },
3394 	{ "vgif", vgif_supported, prepare_vgif_enabled,
3395 	  default_prepare_gif_clear, test_vgif, vgif_finished,
3396 	  vgif_check },
3397 	TEST(svm_cr4_osxsave_test),
3398 	TEST(svm_guest_state_test),
3399 	TEST(svm_vmrun_errata_test),
3400 	TEST(svm_vmload_vmsave),
3401 	TEST(svm_test_singlestep),
3402 	TEST(svm_no_nm_test),
3403 	TEST(svm_exception_test),
3404 	TEST(svm_lbrv_test0),
3405 	TEST(svm_lbrv_test1),
3406 	TEST(svm_lbrv_test2),
3407 	TEST(svm_lbrv_nested_test1),
3408 	TEST(svm_lbrv_nested_test2),
3409 	TEST(svm_intr_intercept_mix_if),
3410 	TEST(svm_intr_intercept_mix_gif),
3411 	TEST(svm_intr_intercept_mix_gif2),
3412 	TEST(svm_intr_intercept_mix_nmi),
3413 	TEST(svm_intr_intercept_mix_smi),
3414 	TEST(svm_tsc_scale_test),
3415 	TEST(pause_filter_test),
3416 	{ NULL, NULL, NULL, NULL, NULL, NULL, NULL }
3417 };
3418 
3419 int main(int ac, char **av)
3420 {
3421 	setup_vm();
3422 	return run_svm_tests(ac, av, svm_tests);
3423 }
3424