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