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