xref: /kvm-unit-tests/x86/svm_tests.c (revision ea71612b8b179d3c38e6878faa5f010306168dc3)
1 #include "svm.h"
2 #include "libcflat.h"
3 #include "processor.h"
4 #include "desc.h"
5 #include "msr.h"
6 #include "vm.h"
7 #include "smp.h"
8 #include "types.h"
9 #include "alloc_page.h"
10 #include "isr.h"
11 #include "apic.h"
12 #include "delay.h"
13 
14 #define SVM_EXIT_MAX_DR_INTERCEPT 0x3f
15 
16 static void *scratch_page;
17 
18 #define LATENCY_RUNS 1000000
19 
20 extern u16 cpu_online_count;
21 
22 u64 tsc_start;
23 u64 tsc_end;
24 
25 u64 vmrun_sum, vmexit_sum;
26 u64 vmsave_sum, vmload_sum;
27 u64 stgi_sum, clgi_sum;
28 u64 latvmrun_max;
29 u64 latvmrun_min;
30 u64 latvmexit_max;
31 u64 latvmexit_min;
32 u64 latvmload_max;
33 u64 latvmload_min;
34 u64 latvmsave_max;
35 u64 latvmsave_min;
36 u64 latstgi_max;
37 u64 latstgi_min;
38 u64 latclgi_max;
39 u64 latclgi_min;
40 u64 runs;
41 
42 static void null_test(struct svm_test *test)
43 {
44 }
45 
46 static bool null_check(struct svm_test *test)
47 {
48     return vmcb->control.exit_code == SVM_EXIT_VMMCALL;
49 }
50 
51 static void prepare_no_vmrun_int(struct svm_test *test)
52 {
53     vmcb->control.intercept &= ~(1ULL << INTERCEPT_VMRUN);
54 }
55 
56 static bool check_no_vmrun_int(struct svm_test *test)
57 {
58     return vmcb->control.exit_code == SVM_EXIT_ERR;
59 }
60 
61 static void test_vmrun(struct svm_test *test)
62 {
63     asm volatile ("vmrun %0" : : "a"(virt_to_phys(vmcb)));
64 }
65 
66 static bool check_vmrun(struct svm_test *test)
67 {
68     return vmcb->control.exit_code == SVM_EXIT_VMRUN;
69 }
70 
71 static void prepare_rsm_intercept(struct svm_test *test)
72 {
73     default_prepare(test);
74     vmcb->control.intercept |= 1 << INTERCEPT_RSM;
75     vmcb->control.intercept_exceptions |= (1ULL << UD_VECTOR);
76 }
77 
78 static void test_rsm_intercept(struct svm_test *test)
79 {
80     asm volatile ("rsm" : : : "memory");
81 }
82 
83 static bool check_rsm_intercept(struct svm_test *test)
84 {
85     return get_test_stage(test) == 2;
86 }
87 
88 static bool finished_rsm_intercept(struct svm_test *test)
89 {
90     switch (get_test_stage(test)) {
91     case 0:
92         if (vmcb->control.exit_code != SVM_EXIT_RSM) {
93             report(false, "VMEXIT not due to rsm. Exit reason 0x%x",
94                    vmcb->control.exit_code);
95             return true;
96         }
97         vmcb->control.intercept &= ~(1 << INTERCEPT_RSM);
98         inc_test_stage(test);
99         break;
100 
101     case 1:
102         if (vmcb->control.exit_code != SVM_EXIT_EXCP_BASE + UD_VECTOR) {
103             report(false, "VMEXIT not due to #UD. Exit reason 0x%x",
104                    vmcb->control.exit_code);
105             return true;
106         }
107         vmcb->save.rip += 2;
108         inc_test_stage(test);
109         break;
110 
111     default:
112         return true;
113     }
114     return get_test_stage(test) == 2;
115 }
116 
117 static void prepare_cr3_intercept(struct svm_test *test)
118 {
119     default_prepare(test);
120     vmcb->control.intercept_cr_read |= 1 << 3;
121 }
122 
123 static void test_cr3_intercept(struct svm_test *test)
124 {
125     asm volatile ("mov %%cr3, %0" : "=r"(test->scratch) : : "memory");
126 }
127 
128 static bool check_cr3_intercept(struct svm_test *test)
129 {
130     return vmcb->control.exit_code == SVM_EXIT_READ_CR3;
131 }
132 
133 static bool check_cr3_nointercept(struct svm_test *test)
134 {
135     return null_check(test) && test->scratch == read_cr3();
136 }
137 
138 static void corrupt_cr3_intercept_bypass(void *_test)
139 {
140     struct svm_test *test = _test;
141     extern volatile u32 mmio_insn;
142 
143     while (!__sync_bool_compare_and_swap(&test->scratch, 1, 2))
144         pause();
145     pause();
146     pause();
147     pause();
148     mmio_insn = 0x90d8200f;  // mov %cr3, %rax; nop
149 }
150 
151 static void prepare_cr3_intercept_bypass(struct svm_test *test)
152 {
153     default_prepare(test);
154     vmcb->control.intercept_cr_read |= 1 << 3;
155     on_cpu_async(1, corrupt_cr3_intercept_bypass, test);
156 }
157 
158 static void test_cr3_intercept_bypass(struct svm_test *test)
159 {
160     ulong a = 0xa0000;
161 
162     test->scratch = 1;
163     while (test->scratch != 2)
164         barrier();
165 
166     asm volatile ("mmio_insn: mov %0, (%0); nop"
167                   : "+a"(a) : : "memory");
168     test->scratch = a;
169 }
170 
171 static void prepare_dr_intercept(struct svm_test *test)
172 {
173     default_prepare(test);
174     vmcb->control.intercept_dr_read = 0xff;
175     vmcb->control.intercept_dr_write = 0xff;
176 }
177 
178 static void test_dr_intercept(struct svm_test *test)
179 {
180     unsigned int i, failcnt = 0;
181 
182     /* Loop testing debug register reads */
183     for (i = 0; i < 8; i++) {
184 
185         switch (i) {
186         case 0:
187             asm volatile ("mov %%dr0, %0" : "=r"(test->scratch) : : "memory");
188             break;
189         case 1:
190             asm volatile ("mov %%dr1, %0" : "=r"(test->scratch) : : "memory");
191             break;
192         case 2:
193             asm volatile ("mov %%dr2, %0" : "=r"(test->scratch) : : "memory");
194             break;
195         case 3:
196             asm volatile ("mov %%dr3, %0" : "=r"(test->scratch) : : "memory");
197             break;
198         case 4:
199             asm volatile ("mov %%dr4, %0" : "=r"(test->scratch) : : "memory");
200             break;
201         case 5:
202             asm volatile ("mov %%dr5, %0" : "=r"(test->scratch) : : "memory");
203             break;
204         case 6:
205             asm volatile ("mov %%dr6, %0" : "=r"(test->scratch) : : "memory");
206             break;
207         case 7:
208             asm volatile ("mov %%dr7, %0" : "=r"(test->scratch) : : "memory");
209             break;
210         }
211 
212         if (test->scratch != i) {
213             report(false, "dr%u read intercept", i);
214             failcnt++;
215         }
216     }
217 
218     /* Loop testing debug register writes */
219     for (i = 0; i < 8; i++) {
220 
221         switch (i) {
222         case 0:
223             asm volatile ("mov %0, %%dr0" : : "r"(test->scratch) : "memory");
224             break;
225         case 1:
226             asm volatile ("mov %0, %%dr1" : : "r"(test->scratch) : "memory");
227             break;
228         case 2:
229             asm volatile ("mov %0, %%dr2" : : "r"(test->scratch) : "memory");
230             break;
231         case 3:
232             asm volatile ("mov %0, %%dr3" : : "r"(test->scratch) : "memory");
233             break;
234         case 4:
235             asm volatile ("mov %0, %%dr4" : : "r"(test->scratch) : "memory");
236             break;
237         case 5:
238             asm volatile ("mov %0, %%dr5" : : "r"(test->scratch) : "memory");
239             break;
240         case 6:
241             asm volatile ("mov %0, %%dr6" : : "r"(test->scratch) : "memory");
242             break;
243         case 7:
244             asm volatile ("mov %0, %%dr7" : : "r"(test->scratch) : "memory");
245             break;
246         }
247 
248         if (test->scratch != i) {
249             report(false, "dr%u write intercept", i);
250             failcnt++;
251         }
252     }
253 
254     test->scratch = failcnt;
255 }
256 
257 static bool dr_intercept_finished(struct svm_test *test)
258 {
259     ulong n = (vmcb->control.exit_code - SVM_EXIT_READ_DR0);
260 
261     /* Only expect DR intercepts */
262     if (n > (SVM_EXIT_MAX_DR_INTERCEPT - SVM_EXIT_READ_DR0))
263         return true;
264 
265     /*
266      * Compute debug register number.
267      * Per Appendix C "SVM Intercept Exit Codes" of AMD64 Architecture
268      * Programmer's Manual Volume 2 - System Programming:
269      * http://support.amd.com/TechDocs/24593.pdf
270      * there are 16 VMEXIT codes each for DR read and write.
271      */
272     test->scratch = (n % 16);
273 
274     /* Jump over MOV instruction */
275     vmcb->save.rip += 3;
276 
277     return false;
278 }
279 
280 static bool check_dr_intercept(struct svm_test *test)
281 {
282     return !test->scratch;
283 }
284 
285 static bool next_rip_supported(void)
286 {
287     return this_cpu_has(X86_FEATURE_NRIPS);
288 }
289 
290 static void prepare_next_rip(struct svm_test *test)
291 {
292     vmcb->control.intercept |= (1ULL << INTERCEPT_RDTSC);
293 }
294 
295 
296 static void test_next_rip(struct svm_test *test)
297 {
298     asm volatile ("rdtsc\n\t"
299                   ".globl exp_next_rip\n\t"
300                   "exp_next_rip:\n\t" ::: "eax", "edx");
301 }
302 
303 static bool check_next_rip(struct svm_test *test)
304 {
305     extern char exp_next_rip;
306     unsigned long address = (unsigned long)&exp_next_rip;
307 
308     return address == vmcb->control.next_rip;
309 }
310 
311 extern u8 *msr_bitmap;
312 
313 static void prepare_msr_intercept(struct svm_test *test)
314 {
315     default_prepare(test);
316     vmcb->control.intercept |= (1ULL << INTERCEPT_MSR_PROT);
317     vmcb->control.intercept_exceptions |= (1ULL << GP_VECTOR);
318     memset(msr_bitmap, 0xff, MSR_BITMAP_SIZE);
319 }
320 
321 static void test_msr_intercept(struct svm_test *test)
322 {
323     unsigned long msr_value = 0xef8056791234abcd; /* Arbitrary value */
324     unsigned long msr_index;
325 
326     for (msr_index = 0; msr_index <= 0xc0011fff; msr_index++) {
327         if (msr_index == 0xC0010131 /* MSR_SEV_STATUS */) {
328             /*
329              * Per section 15.34.10 "SEV_STATUS MSR" of AMD64 Architecture
330              * Programmer's Manual volume 2 - System Programming:
331              * http://support.amd.com/TechDocs/24593.pdf
332              * SEV_STATUS MSR (C001_0131) is a non-interceptable MSR.
333              */
334             continue;
335         }
336 
337         /* Skips gaps between supported MSR ranges */
338         if (msr_index == 0x2000)
339             msr_index = 0xc0000000;
340         else if (msr_index == 0xc0002000)
341             msr_index = 0xc0010000;
342 
343         test->scratch = -1;
344 
345         rdmsr(msr_index);
346 
347         /* Check that a read intercept occurred for MSR at msr_index */
348         if (test->scratch != msr_index)
349             report(false, "MSR 0x%lx read intercept", msr_index);
350 
351         /*
352          * Poor man approach to generate a value that
353          * seems arbitrary each time around the loop.
354          */
355         msr_value += (msr_value << 1);
356 
357         wrmsr(msr_index, msr_value);
358 
359         /* Check that a write intercept occurred for MSR with msr_value */
360         if (test->scratch != msr_value)
361             report(false, "MSR 0x%lx write intercept", msr_index);
362     }
363 
364     test->scratch = -2;
365 }
366 
367 static bool msr_intercept_finished(struct svm_test *test)
368 {
369     u32 exit_code = vmcb->control.exit_code;
370     u64 exit_info_1;
371     u8 *opcode;
372 
373     if (exit_code == SVM_EXIT_MSR) {
374         exit_info_1 = vmcb->control.exit_info_1;
375     } else {
376         /*
377          * If #GP exception occurs instead, check that it was
378          * for RDMSR/WRMSR and set exit_info_1 accordingly.
379          */
380 
381         if (exit_code != (SVM_EXIT_EXCP_BASE + GP_VECTOR))
382             return true;
383 
384         opcode = (u8 *)vmcb->save.rip;
385         if (opcode[0] != 0x0f)
386             return true;
387 
388         switch (opcode[1]) {
389         case 0x30: /* WRMSR */
390             exit_info_1 = 1;
391             break;
392         case 0x32: /* RDMSR */
393             exit_info_1 = 0;
394             break;
395         default:
396             return true;
397         }
398 
399         /*
400          * Warn that #GP exception occured instead.
401          * RCX holds the MSR index.
402          */
403         printf("%s 0x%lx #GP exception\n",
404             exit_info_1 ? "WRMSR" : "RDMSR", get_regs().rcx);
405     }
406 
407     /* Jump over RDMSR/WRMSR instruction */
408     vmcb->save.rip += 2;
409 
410     /*
411      * Test whether the intercept was for RDMSR/WRMSR.
412      * For RDMSR, test->scratch is set to the MSR index;
413      *      RCX holds the MSR index.
414      * For WRMSR, test->scratch is set to the MSR value;
415      *      RDX holds the upper 32 bits of the MSR value,
416      *      while RAX hold its lower 32 bits.
417      */
418     if (exit_info_1)
419         test->scratch =
420             ((get_regs().rdx << 32) | (vmcb->save.rax & 0xffffffff));
421     else
422         test->scratch = get_regs().rcx;
423 
424     return false;
425 }
426 
427 static bool check_msr_intercept(struct svm_test *test)
428 {
429     memset(msr_bitmap, 0, MSR_BITMAP_SIZE);
430     return (test->scratch == -2);
431 }
432 
433 static void prepare_mode_switch(struct svm_test *test)
434 {
435     vmcb->control.intercept_exceptions |= (1ULL << GP_VECTOR)
436                                              |  (1ULL << UD_VECTOR)
437                                              |  (1ULL << DF_VECTOR)
438                                              |  (1ULL << PF_VECTOR);
439     test->scratch = 0;
440 }
441 
442 static void test_mode_switch(struct svm_test *test)
443 {
444     asm volatile("	cli\n"
445 		 "	ljmp *1f\n" /* jump to 32-bit code segment */
446 		 "1:\n"
447 		 "	.long 2f\n"
448 		 "	.long " xstr(KERNEL_CS32) "\n"
449 		 ".code32\n"
450 		 "2:\n"
451 		 "	movl %%cr0, %%eax\n"
452 		 "	btcl  $31, %%eax\n" /* clear PG */
453 		 "	movl %%eax, %%cr0\n"
454 		 "	movl $0xc0000080, %%ecx\n" /* EFER */
455 		 "	rdmsr\n"
456 		 "	btcl $8, %%eax\n" /* clear LME */
457 		 "	wrmsr\n"
458 		 "	movl %%cr4, %%eax\n"
459 		 "	btcl $5, %%eax\n" /* clear PAE */
460 		 "	movl %%eax, %%cr4\n"
461 		 "	movw %[ds16], %%ax\n"
462 		 "	movw %%ax, %%ds\n"
463 		 "	ljmpl %[cs16], $3f\n" /* jump to 16 bit protected-mode */
464 		 ".code16\n"
465 		 "3:\n"
466 		 "	movl %%cr0, %%eax\n"
467 		 "	btcl $0, %%eax\n" /* clear PE  */
468 		 "	movl %%eax, %%cr0\n"
469 		 "	ljmpl $0, $4f\n"   /* jump to real-mode */
470 		 "4:\n"
471 		 "	vmmcall\n"
472 		 "	movl %%cr0, %%eax\n"
473 		 "	btsl $0, %%eax\n" /* set PE  */
474 		 "	movl %%eax, %%cr0\n"
475 		 "	ljmpl %[cs32], $5f\n" /* back to protected mode */
476 		 ".code32\n"
477 		 "5:\n"
478 		 "	movl %%cr4, %%eax\n"
479 		 "	btsl $5, %%eax\n" /* set PAE */
480 		 "	movl %%eax, %%cr4\n"
481 		 "	movl $0xc0000080, %%ecx\n" /* EFER */
482 		 "	rdmsr\n"
483 		 "	btsl $8, %%eax\n" /* set LME */
484 		 "	wrmsr\n"
485 		 "	movl %%cr0, %%eax\n"
486 		 "	btsl  $31, %%eax\n" /* set PG */
487 		 "	movl %%eax, %%cr0\n"
488 		 "	ljmpl %[cs64], $6f\n"    /* back to long mode */
489 		 ".code64\n\t"
490 		 "6:\n"
491 		 "	vmmcall\n"
492 		 :: [cs16] "i"(KERNEL_CS16), [ds16] "i"(KERNEL_DS16),
493 		    [cs32] "i"(KERNEL_CS32), [cs64] "i"(KERNEL_CS64)
494 		 : "rax", "rbx", "rcx", "rdx", "memory");
495 }
496 
497 static bool mode_switch_finished(struct svm_test *test)
498 {
499     u64 cr0, cr4, efer;
500 
501     cr0  = vmcb->save.cr0;
502     cr4  = vmcb->save.cr4;
503     efer = vmcb->save.efer;
504 
505     /* Only expect VMMCALL intercepts */
506     if (vmcb->control.exit_code != SVM_EXIT_VMMCALL)
507 	    return true;
508 
509     /* Jump over VMMCALL instruction */
510     vmcb->save.rip += 3;
511 
512     /* Do sanity checks */
513     switch (test->scratch) {
514     case 0:
515         /* Test should be in real mode now - check for this */
516         if ((cr0  & 0x80000001) || /* CR0.PG, CR0.PE */
517             (cr4  & 0x00000020) || /* CR4.PAE */
518             (efer & 0x00000500))   /* EFER.LMA, EFER.LME */
519                 return true;
520         break;
521     case 2:
522         /* Test should be back in long-mode now - check for this */
523         if (((cr0  & 0x80000001) != 0x80000001) || /* CR0.PG, CR0.PE */
524             ((cr4  & 0x00000020) != 0x00000020) || /* CR4.PAE */
525             ((efer & 0x00000500) != 0x00000500))   /* EFER.LMA, EFER.LME */
526 		    return true;
527 	break;
528     }
529 
530     /* one step forward */
531     test->scratch += 1;
532 
533     return test->scratch == 2;
534 }
535 
536 static bool check_mode_switch(struct svm_test *test)
537 {
538 	return test->scratch == 2;
539 }
540 
541 extern u8 *io_bitmap;
542 
543 static void prepare_ioio(struct svm_test *test)
544 {
545     vmcb->control.intercept |= (1ULL << INTERCEPT_IOIO_PROT);
546     test->scratch = 0;
547     memset(io_bitmap, 0, 8192);
548     io_bitmap[8192] = 0xFF;
549 }
550 
551 static void test_ioio(struct svm_test *test)
552 {
553     // stage 0, test IO pass
554     inb(0x5000);
555     outb(0x0, 0x5000);
556     if (get_test_stage(test) != 0)
557         goto fail;
558 
559     // test IO width, in/out
560     io_bitmap[0] = 0xFF;
561     inc_test_stage(test);
562     inb(0x0);
563     if (get_test_stage(test) != 2)
564         goto fail;
565 
566     outw(0x0, 0x0);
567     if (get_test_stage(test) != 3)
568         goto fail;
569 
570     inl(0x0);
571     if (get_test_stage(test) != 4)
572         goto fail;
573 
574     // test low/high IO port
575     io_bitmap[0x5000 / 8] = (1 << (0x5000 % 8));
576     inb(0x5000);
577     if (get_test_stage(test) != 5)
578         goto fail;
579 
580     io_bitmap[0x9000 / 8] = (1 << (0x9000 % 8));
581     inw(0x9000);
582     if (get_test_stage(test) != 6)
583         goto fail;
584 
585     // test partial pass
586     io_bitmap[0x5000 / 8] = (1 << (0x5000 % 8));
587     inl(0x4FFF);
588     if (get_test_stage(test) != 7)
589         goto fail;
590 
591     // test across pages
592     inc_test_stage(test);
593     inl(0x7FFF);
594     if (get_test_stage(test) != 8)
595         goto fail;
596 
597     inc_test_stage(test);
598     io_bitmap[0x8000 / 8] = 1 << (0x8000 % 8);
599     inl(0x7FFF);
600     if (get_test_stage(test) != 10)
601         goto fail;
602 
603     io_bitmap[0] = 0;
604     inl(0xFFFF);
605     if (get_test_stage(test) != 11)
606         goto fail;
607 
608     io_bitmap[0] = 0xFF;
609     io_bitmap[8192] = 0;
610     inl(0xFFFF);
611     inc_test_stage(test);
612     if (get_test_stage(test) != 12)
613         goto fail;
614 
615     return;
616 
617 fail:
618     report(false, "stage %d", get_test_stage(test));
619     test->scratch = -1;
620 }
621 
622 static bool ioio_finished(struct svm_test *test)
623 {
624     unsigned port, size;
625 
626     /* Only expect IOIO intercepts */
627     if (vmcb->control.exit_code == SVM_EXIT_VMMCALL)
628         return true;
629 
630     if (vmcb->control.exit_code != SVM_EXIT_IOIO)
631         return true;
632 
633     /* one step forward */
634     test->scratch += 1;
635 
636     port = vmcb->control.exit_info_1 >> 16;
637     size = (vmcb->control.exit_info_1 >> SVM_IOIO_SIZE_SHIFT) & 7;
638 
639     while (size--) {
640         io_bitmap[port / 8] &= ~(1 << (port & 7));
641         port++;
642     }
643 
644     return false;
645 }
646 
647 static bool check_ioio(struct svm_test *test)
648 {
649     memset(io_bitmap, 0, 8193);
650     return test->scratch != -1;
651 }
652 
653 static void prepare_asid_zero(struct svm_test *test)
654 {
655     vmcb->control.asid = 0;
656 }
657 
658 static void test_asid_zero(struct svm_test *test)
659 {
660     asm volatile ("vmmcall\n\t");
661 }
662 
663 static bool check_asid_zero(struct svm_test *test)
664 {
665     return vmcb->control.exit_code == SVM_EXIT_ERR;
666 }
667 
668 static void sel_cr0_bug_prepare(struct svm_test *test)
669 {
670     vmcb_ident(vmcb);
671     vmcb->control.intercept |= (1ULL << INTERCEPT_SELECTIVE_CR0);
672 }
673 
674 static bool sel_cr0_bug_finished(struct svm_test *test)
675 {
676 	return true;
677 }
678 
679 static void sel_cr0_bug_test(struct svm_test *test)
680 {
681     unsigned long cr0;
682 
683     /* read cr0, clear CD, and write back */
684     cr0  = read_cr0();
685     cr0 |= (1UL << 30);
686     write_cr0(cr0);
687 
688     /*
689      * If we are here the test failed, not sure what to do now because we
690      * are not in guest-mode anymore so we can't trigger an intercept.
691      * Trigger a tripple-fault for now.
692      */
693     report(false, "sel_cr0 test. Can not recover from this - exiting");
694     exit(report_summary());
695 }
696 
697 static bool sel_cr0_bug_check(struct svm_test *test)
698 {
699     return vmcb->control.exit_code == SVM_EXIT_CR0_SEL_WRITE;
700 }
701 
702 static void npt_nx_prepare(struct svm_test *test)
703 {
704 
705     u64 *pte;
706 
707     vmcb_ident(vmcb);
708     pte = npt_get_pte((u64)null_test);
709 
710     *pte |= (1ULL << 63);
711 }
712 
713 static bool npt_nx_check(struct svm_test *test)
714 {
715     u64 *pte = npt_get_pte((u64)null_test);
716 
717     *pte &= ~(1ULL << 63);
718 
719     vmcb->save.efer |= (1 << 11);
720 
721     return (vmcb->control.exit_code == SVM_EXIT_NPF)
722            && (vmcb->control.exit_info_1 == 0x100000015ULL);
723 }
724 
725 static void npt_np_prepare(struct svm_test *test)
726 {
727     u64 *pte;
728 
729     scratch_page = alloc_page();
730     vmcb_ident(vmcb);
731     pte = npt_get_pte((u64)scratch_page);
732 
733     *pte &= ~1ULL;
734 }
735 
736 static void npt_np_test(struct svm_test *test)
737 {
738     (void) *(volatile u64 *)scratch_page;
739 }
740 
741 static bool npt_np_check(struct svm_test *test)
742 {
743     u64 *pte = npt_get_pte((u64)scratch_page);
744 
745     *pte |= 1ULL;
746 
747     return (vmcb->control.exit_code == SVM_EXIT_NPF)
748            && (vmcb->control.exit_info_1 == 0x100000004ULL);
749 }
750 
751 static void npt_us_prepare(struct svm_test *test)
752 {
753     u64 *pte;
754 
755     scratch_page = alloc_page();
756     vmcb_ident(vmcb);
757     pte = npt_get_pte((u64)scratch_page);
758 
759     *pte &= ~(1ULL << 2);
760 }
761 
762 static void npt_us_test(struct svm_test *test)
763 {
764     (void) *(volatile u64 *)scratch_page;
765 }
766 
767 static bool npt_us_check(struct svm_test *test)
768 {
769     u64 *pte = npt_get_pte((u64)scratch_page);
770 
771     *pte |= (1ULL << 2);
772 
773     return (vmcb->control.exit_code == SVM_EXIT_NPF)
774            && (vmcb->control.exit_info_1 == 0x100000005ULL);
775 }
776 
777 u64 save_pde;
778 
779 static void npt_rsvd_prepare(struct svm_test *test)
780 {
781     u64 *pde;
782 
783     vmcb_ident(vmcb);
784     pde = npt_get_pde((u64) null_test);
785 
786     save_pde = *pde;
787     *pde = (1ULL << 19) | (1ULL << 7) | 0x27;
788 }
789 
790 static bool npt_rsvd_check(struct svm_test *test)
791 {
792     u64 *pde = npt_get_pde((u64) null_test);
793 
794     *pde = save_pde;
795 
796     return (vmcb->control.exit_code == SVM_EXIT_NPF)
797             && (vmcb->control.exit_info_1 == 0x10000001dULL);
798 }
799 
800 static void npt_rw_prepare(struct svm_test *test)
801 {
802 
803     u64 *pte;
804 
805     vmcb_ident(vmcb);
806     pte = npt_get_pte(0x80000);
807 
808     *pte &= ~(1ULL << 1);
809 }
810 
811 static void npt_rw_test(struct svm_test *test)
812 {
813     u64 *data = (void*)(0x80000);
814 
815     *data = 0;
816 }
817 
818 static bool npt_rw_check(struct svm_test *test)
819 {
820     u64 *pte = npt_get_pte(0x80000);
821 
822     *pte |= (1ULL << 1);
823 
824     return (vmcb->control.exit_code == SVM_EXIT_NPF)
825            && (vmcb->control.exit_info_1 == 0x100000007ULL);
826 }
827 
828 static void npt_rw_pfwalk_prepare(struct svm_test *test)
829 {
830 
831     u64 *pte;
832 
833     vmcb_ident(vmcb);
834     pte = npt_get_pte(read_cr3());
835 
836     *pte &= ~(1ULL << 1);
837 }
838 
839 static bool npt_rw_pfwalk_check(struct svm_test *test)
840 {
841     u64 *pte = npt_get_pte(read_cr3());
842 
843     *pte |= (1ULL << 1);
844 
845     return (vmcb->control.exit_code == SVM_EXIT_NPF)
846            && (vmcb->control.exit_info_1 == 0x200000007ULL)
847 	   && (vmcb->control.exit_info_2 == read_cr3());
848 }
849 
850 static void npt_rsvd_pfwalk_prepare(struct svm_test *test)
851 {
852     u64 *pdpe;
853     vmcb_ident(vmcb);
854 
855     pdpe = npt_get_pml4e();
856     pdpe[0] |= (1ULL << 8);
857 }
858 
859 static bool npt_rsvd_pfwalk_check(struct svm_test *test)
860 {
861     u64 *pdpe = npt_get_pml4e();
862     pdpe[0] &= ~(1ULL << 8);
863 
864     return (vmcb->control.exit_code == SVM_EXIT_NPF)
865             && (vmcb->control.exit_info_1 == 0x20000000fULL);
866 }
867 
868 static void npt_l1mmio_prepare(struct svm_test *test)
869 {
870     vmcb_ident(vmcb);
871 }
872 
873 u32 nested_apic_version1;
874 u32 nested_apic_version2;
875 
876 static void npt_l1mmio_test(struct svm_test *test)
877 {
878     volatile u32 *data = (volatile void*)(0xfee00030UL);
879 
880     nested_apic_version1 = *data;
881     nested_apic_version2 = *data;
882 }
883 
884 static bool npt_l1mmio_check(struct svm_test *test)
885 {
886     volatile u32 *data = (volatile void*)(0xfee00030);
887     u32 lvr = *data;
888 
889     return nested_apic_version1 == lvr && nested_apic_version2 == lvr;
890 }
891 
892 static void npt_rw_l1mmio_prepare(struct svm_test *test)
893 {
894 
895     u64 *pte;
896 
897     vmcb_ident(vmcb);
898     pte = npt_get_pte(0xfee00080);
899 
900     *pte &= ~(1ULL << 1);
901 }
902 
903 static void npt_rw_l1mmio_test(struct svm_test *test)
904 {
905     volatile u32 *data = (volatile void*)(0xfee00080);
906 
907     *data = *data;
908 }
909 
910 static bool npt_rw_l1mmio_check(struct svm_test *test)
911 {
912     u64 *pte = npt_get_pte(0xfee00080);
913 
914     *pte |= (1ULL << 1);
915 
916     return (vmcb->control.exit_code == SVM_EXIT_NPF)
917            && (vmcb->control.exit_info_1 == 0x100000007ULL);
918 }
919 
920 #define TSC_ADJUST_VALUE    (1ll << 32)
921 #define TSC_OFFSET_VALUE    (~0ull << 48)
922 static bool ok;
923 
924 static bool tsc_adjust_supported(void)
925 {
926     return this_cpu_has(X86_FEATURE_TSC_ADJUST);
927 }
928 
929 static void tsc_adjust_prepare(struct svm_test *test)
930 {
931     default_prepare(test);
932     vmcb->control.tsc_offset = TSC_OFFSET_VALUE;
933 
934     wrmsr(MSR_IA32_TSC_ADJUST, -TSC_ADJUST_VALUE);
935     int64_t adjust = rdmsr(MSR_IA32_TSC_ADJUST);
936     ok = adjust == -TSC_ADJUST_VALUE;
937 }
938 
939 static void tsc_adjust_test(struct svm_test *test)
940 {
941     int64_t adjust = rdmsr(MSR_IA32_TSC_ADJUST);
942     ok &= adjust == -TSC_ADJUST_VALUE;
943 
944     uint64_t l1_tsc = rdtsc() - TSC_OFFSET_VALUE;
945     wrmsr(MSR_IA32_TSC, l1_tsc - TSC_ADJUST_VALUE);
946 
947     adjust = rdmsr(MSR_IA32_TSC_ADJUST);
948     ok &= adjust <= -2 * TSC_ADJUST_VALUE;
949 
950     uint64_t l1_tsc_end = rdtsc() - TSC_OFFSET_VALUE;
951     ok &= (l1_tsc_end + TSC_ADJUST_VALUE - l1_tsc) < TSC_ADJUST_VALUE;
952 
953     uint64_t l1_tsc_msr = rdmsr(MSR_IA32_TSC) - TSC_OFFSET_VALUE;
954     ok &= (l1_tsc_msr + TSC_ADJUST_VALUE - l1_tsc) < TSC_ADJUST_VALUE;
955 }
956 
957 static bool tsc_adjust_check(struct svm_test *test)
958 {
959     int64_t adjust = rdmsr(MSR_IA32_TSC_ADJUST);
960 
961     wrmsr(MSR_IA32_TSC_ADJUST, 0);
962     return ok && adjust <= -2 * TSC_ADJUST_VALUE;
963 }
964 
965 static void latency_prepare(struct svm_test *test)
966 {
967     default_prepare(test);
968     runs = LATENCY_RUNS;
969     latvmrun_min = latvmexit_min = -1ULL;
970     latvmrun_max = latvmexit_max = 0;
971     vmrun_sum = vmexit_sum = 0;
972     tsc_start = rdtsc();
973 }
974 
975 static void latency_test(struct svm_test *test)
976 {
977     u64 cycles;
978 
979 start:
980     tsc_end = rdtsc();
981 
982     cycles = tsc_end - tsc_start;
983 
984     if (cycles > latvmrun_max)
985         latvmrun_max = cycles;
986 
987     if (cycles < latvmrun_min)
988         latvmrun_min = cycles;
989 
990     vmrun_sum += cycles;
991 
992     tsc_start = rdtsc();
993 
994     asm volatile ("vmmcall" : : : "memory");
995     goto start;
996 }
997 
998 static bool latency_finished(struct svm_test *test)
999 {
1000     u64 cycles;
1001 
1002     tsc_end = rdtsc();
1003 
1004     cycles = tsc_end - tsc_start;
1005 
1006     if (cycles > latvmexit_max)
1007         latvmexit_max = cycles;
1008 
1009     if (cycles < latvmexit_min)
1010         latvmexit_min = cycles;
1011 
1012     vmexit_sum += cycles;
1013 
1014     vmcb->save.rip += 3;
1015 
1016     runs -= 1;
1017 
1018     tsc_end = rdtsc();
1019 
1020     return runs == 0;
1021 }
1022 
1023 static bool latency_check(struct svm_test *test)
1024 {
1025     printf("    Latency VMRUN : max: %ld min: %ld avg: %ld\n", latvmrun_max,
1026             latvmrun_min, vmrun_sum / LATENCY_RUNS);
1027     printf("    Latency VMEXIT: max: %ld min: %ld avg: %ld\n", latvmexit_max,
1028             latvmexit_min, vmexit_sum / LATENCY_RUNS);
1029     return true;
1030 }
1031 
1032 static void lat_svm_insn_prepare(struct svm_test *test)
1033 {
1034     default_prepare(test);
1035     runs = LATENCY_RUNS;
1036     latvmload_min = latvmsave_min = latstgi_min = latclgi_min = -1ULL;
1037     latvmload_max = latvmsave_max = latstgi_max = latclgi_max = 0;
1038     vmload_sum = vmsave_sum = stgi_sum = clgi_sum;
1039 }
1040 
1041 static bool lat_svm_insn_finished(struct svm_test *test)
1042 {
1043     u64 vmcb_phys = virt_to_phys(vmcb);
1044     u64 cycles;
1045 
1046     for ( ; runs != 0; runs--) {
1047         tsc_start = rdtsc();
1048         asm volatile("vmload %0\n\t" : : "a"(vmcb_phys) : "memory");
1049         cycles = rdtsc() - tsc_start;
1050         if (cycles > latvmload_max)
1051             latvmload_max = cycles;
1052         if (cycles < latvmload_min)
1053             latvmload_min = cycles;
1054         vmload_sum += cycles;
1055 
1056         tsc_start = rdtsc();
1057         asm volatile("vmsave %0\n\t" : : "a"(vmcb_phys) : "memory");
1058         cycles = rdtsc() - tsc_start;
1059         if (cycles > latvmsave_max)
1060             latvmsave_max = cycles;
1061         if (cycles < latvmsave_min)
1062             latvmsave_min = cycles;
1063         vmsave_sum += cycles;
1064 
1065         tsc_start = rdtsc();
1066         asm volatile("stgi\n\t");
1067         cycles = rdtsc() - tsc_start;
1068         if (cycles > latstgi_max)
1069             latstgi_max = cycles;
1070         if (cycles < latstgi_min)
1071             latstgi_min = cycles;
1072         stgi_sum += cycles;
1073 
1074         tsc_start = rdtsc();
1075         asm volatile("clgi\n\t");
1076         cycles = rdtsc() - tsc_start;
1077         if (cycles > latclgi_max)
1078             latclgi_max = cycles;
1079         if (cycles < latclgi_min)
1080             latclgi_min = cycles;
1081         clgi_sum += cycles;
1082     }
1083 
1084     tsc_end = rdtsc();
1085 
1086     return true;
1087 }
1088 
1089 static bool lat_svm_insn_check(struct svm_test *test)
1090 {
1091     printf("    Latency VMLOAD: max: %ld min: %ld avg: %ld\n", latvmload_max,
1092             latvmload_min, vmload_sum / LATENCY_RUNS);
1093     printf("    Latency VMSAVE: max: %ld min: %ld avg: %ld\n", latvmsave_max,
1094             latvmsave_min, vmsave_sum / LATENCY_RUNS);
1095     printf("    Latency STGI:   max: %ld min: %ld avg: %ld\n", latstgi_max,
1096             latstgi_min, stgi_sum / LATENCY_RUNS);
1097     printf("    Latency CLGI:   max: %ld min: %ld avg: %ld\n", latclgi_max,
1098             latclgi_min, clgi_sum / LATENCY_RUNS);
1099     return true;
1100 }
1101 
1102 bool pending_event_ipi_fired;
1103 bool pending_event_guest_run;
1104 
1105 static void pending_event_ipi_isr(isr_regs_t *regs)
1106 {
1107     pending_event_ipi_fired = true;
1108     eoi();
1109 }
1110 
1111 static void pending_event_prepare(struct svm_test *test)
1112 {
1113     int ipi_vector = 0xf1;
1114 
1115     default_prepare(test);
1116 
1117     pending_event_ipi_fired = false;
1118 
1119     handle_irq(ipi_vector, pending_event_ipi_isr);
1120 
1121     pending_event_guest_run = false;
1122 
1123     vmcb->control.intercept |= (1ULL << INTERCEPT_INTR);
1124     vmcb->control.int_ctl |= V_INTR_MASKING_MASK;
1125 
1126     apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL |
1127                   APIC_DM_FIXED | ipi_vector, 0);
1128 
1129     set_test_stage(test, 0);
1130 }
1131 
1132 static void pending_event_test(struct svm_test *test)
1133 {
1134     pending_event_guest_run = true;
1135 }
1136 
1137 static bool pending_event_finished(struct svm_test *test)
1138 {
1139     switch (get_test_stage(test)) {
1140     case 0:
1141         if (vmcb->control.exit_code != SVM_EXIT_INTR) {
1142             report(false, "VMEXIT not due to pending interrupt. Exit reason 0x%x",
1143                    vmcb->control.exit_code);
1144             return true;
1145         }
1146 
1147         vmcb->control.intercept &= ~(1ULL << INTERCEPT_INTR);
1148         vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK;
1149 
1150         if (pending_event_guest_run) {
1151             report(false, "Guest ran before host received IPI\n");
1152             return true;
1153         }
1154 
1155         irq_enable();
1156         asm volatile ("nop");
1157         irq_disable();
1158 
1159         if (!pending_event_ipi_fired) {
1160             report(false, "Pending interrupt not dispatched after IRQ enabled\n");
1161             return true;
1162         }
1163         break;
1164 
1165     case 1:
1166         if (!pending_event_guest_run) {
1167             report(false, "Guest did not resume when no interrupt\n");
1168             return true;
1169         }
1170         break;
1171     }
1172 
1173     inc_test_stage(test);
1174 
1175     return get_test_stage(test) == 2;
1176 }
1177 
1178 static bool pending_event_check(struct svm_test *test)
1179 {
1180     return get_test_stage(test) == 2;
1181 }
1182 
1183 static void pending_event_cli_prepare(struct svm_test *test)
1184 {
1185     default_prepare(test);
1186 
1187     pending_event_ipi_fired = false;
1188 
1189     handle_irq(0xf1, pending_event_ipi_isr);
1190 
1191     apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL |
1192               APIC_DM_FIXED | 0xf1, 0);
1193 
1194     set_test_stage(test, 0);
1195 }
1196 
1197 static void pending_event_cli_prepare_gif_clear(struct svm_test *test)
1198 {
1199     asm("cli");
1200 }
1201 
1202 static void pending_event_cli_test(struct svm_test *test)
1203 {
1204     if (pending_event_ipi_fired == true) {
1205         set_test_stage(test, -1);
1206         report(false, "Interrupt preceeded guest");
1207         vmmcall();
1208     }
1209 
1210     /* VINTR_MASKING is zero.  This should cause the IPI to fire.  */
1211     irq_enable();
1212     asm volatile ("nop");
1213     irq_disable();
1214 
1215     if (pending_event_ipi_fired != true) {
1216         set_test_stage(test, -1);
1217         report(false, "Interrupt not triggered by guest");
1218     }
1219 
1220     vmmcall();
1221 
1222     /*
1223      * Now VINTR_MASKING=1, but no interrupt is pending so
1224      * the VINTR interception should be clear in VMCB02.  Check
1225      * that L0 did not leave a stale VINTR in the VMCB.
1226      */
1227     irq_enable();
1228     asm volatile ("nop");
1229     irq_disable();
1230 }
1231 
1232 static bool pending_event_cli_finished(struct svm_test *test)
1233 {
1234     if ( vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
1235         report(false, "VM_EXIT return to host is not EXIT_VMMCALL exit reason 0x%x",
1236                vmcb->control.exit_code);
1237         return true;
1238     }
1239 
1240     switch (get_test_stage(test)) {
1241     case 0:
1242         vmcb->save.rip += 3;
1243 
1244         pending_event_ipi_fired = false;
1245 
1246         vmcb->control.int_ctl |= V_INTR_MASKING_MASK;
1247 
1248 	/* Now entering again with VINTR_MASKING=1.  */
1249         apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL |
1250               APIC_DM_FIXED | 0xf1, 0);
1251 
1252         break;
1253 
1254     case 1:
1255         if (pending_event_ipi_fired == true) {
1256             report(false, "Interrupt triggered by guest");
1257             return true;
1258         }
1259 
1260         irq_enable();
1261         asm volatile ("nop");
1262         irq_disable();
1263 
1264         if (pending_event_ipi_fired != true) {
1265             report(false, "Interrupt not triggered by host");
1266             return true;
1267         }
1268 
1269         break;
1270 
1271     default:
1272         return true;
1273     }
1274 
1275     inc_test_stage(test);
1276 
1277     return get_test_stage(test) == 2;
1278 }
1279 
1280 static bool pending_event_cli_check(struct svm_test *test)
1281 {
1282     return get_test_stage(test) == 2;
1283 }
1284 
1285 #define TIMER_VECTOR    222
1286 
1287 static volatile bool timer_fired;
1288 
1289 static void timer_isr(isr_regs_t *regs)
1290 {
1291     timer_fired = true;
1292     apic_write(APIC_EOI, 0);
1293 }
1294 
1295 static void interrupt_prepare(struct svm_test *test)
1296 {
1297     default_prepare(test);
1298     handle_irq(TIMER_VECTOR, timer_isr);
1299     timer_fired = false;
1300     set_test_stage(test, 0);
1301 }
1302 
1303 static void interrupt_test(struct svm_test *test)
1304 {
1305     long long start, loops;
1306 
1307     apic_write(APIC_LVTT, TIMER_VECTOR);
1308     irq_enable();
1309     apic_write(APIC_TMICT, 1); //Timer Initial Count Register 0x380 one-shot
1310     for (loops = 0; loops < 10000000 && !timer_fired; loops++)
1311         asm volatile ("nop");
1312 
1313     report(timer_fired, "direct interrupt while running guest");
1314 
1315     if (!timer_fired) {
1316         set_test_stage(test, -1);
1317         vmmcall();
1318     }
1319 
1320     apic_write(APIC_TMICT, 0);
1321     irq_disable();
1322     vmmcall();
1323 
1324     timer_fired = false;
1325     apic_write(APIC_TMICT, 1);
1326     for (loops = 0; loops < 10000000 && !timer_fired; loops++)
1327         asm volatile ("nop");
1328 
1329     report(timer_fired, "intercepted interrupt while running guest");
1330 
1331     if (!timer_fired) {
1332         set_test_stage(test, -1);
1333         vmmcall();
1334     }
1335 
1336     irq_enable();
1337     apic_write(APIC_TMICT, 0);
1338     irq_disable();
1339 
1340     timer_fired = false;
1341     start = rdtsc();
1342     apic_write(APIC_TMICT, 1000000);
1343     asm volatile ("sti; hlt");
1344 
1345     report(rdtsc() - start > 10000 && timer_fired,
1346           "direct interrupt + hlt");
1347 
1348     if (!timer_fired) {
1349         set_test_stage(test, -1);
1350         vmmcall();
1351     }
1352 
1353     apic_write(APIC_TMICT, 0);
1354     irq_disable();
1355     vmmcall();
1356 
1357     timer_fired = false;
1358     start = rdtsc();
1359     apic_write(APIC_TMICT, 1000000);
1360     asm volatile ("hlt");
1361 
1362     report(rdtsc() - start > 10000 && timer_fired,
1363            "intercepted interrupt + hlt");
1364 
1365     if (!timer_fired) {
1366         set_test_stage(test, -1);
1367         vmmcall();
1368     }
1369 
1370     apic_write(APIC_TMICT, 0);
1371     irq_disable();
1372 }
1373 
1374 static bool interrupt_finished(struct svm_test *test)
1375 {
1376     switch (get_test_stage(test)) {
1377     case 0:
1378     case 2:
1379         if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
1380             report(false, "VMEXIT not due to vmmcall. Exit reason 0x%x",
1381                    vmcb->control.exit_code);
1382             return true;
1383         }
1384         vmcb->save.rip += 3;
1385 
1386         vmcb->control.intercept |= (1ULL << INTERCEPT_INTR);
1387         vmcb->control.int_ctl |= V_INTR_MASKING_MASK;
1388         break;
1389 
1390     case 1:
1391     case 3:
1392         if (vmcb->control.exit_code != SVM_EXIT_INTR) {
1393             report(false, "VMEXIT not due to intr intercept. Exit reason 0x%x",
1394                    vmcb->control.exit_code);
1395             return true;
1396         }
1397 
1398         irq_enable();
1399         asm volatile ("nop");
1400         irq_disable();
1401 
1402         vmcb->control.intercept &= ~(1ULL << INTERCEPT_INTR);
1403         vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK;
1404         break;
1405 
1406     case 4:
1407         break;
1408 
1409     default:
1410         return true;
1411     }
1412 
1413     inc_test_stage(test);
1414 
1415     return get_test_stage(test) == 5;
1416 }
1417 
1418 static bool interrupt_check(struct svm_test *test)
1419 {
1420     return get_test_stage(test) == 5;
1421 }
1422 
1423 static volatile bool nmi_fired;
1424 
1425 static void nmi_handler(isr_regs_t *regs)
1426 {
1427     nmi_fired = true;
1428     apic_write(APIC_EOI, 0);
1429 }
1430 
1431 static void nmi_prepare(struct svm_test *test)
1432 {
1433     default_prepare(test);
1434     nmi_fired = false;
1435     handle_irq(NMI_VECTOR, nmi_handler);
1436     set_test_stage(test, 0);
1437 }
1438 
1439 static void nmi_test(struct svm_test *test)
1440 {
1441     apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL | APIC_DM_NMI | APIC_INT_ASSERT, 0);
1442 
1443     report(nmi_fired, "direct NMI while running guest");
1444 
1445     if (!nmi_fired)
1446         set_test_stage(test, -1);
1447 
1448     vmmcall();
1449 
1450     nmi_fired = false;
1451 
1452     apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL | APIC_DM_NMI | APIC_INT_ASSERT, 0);
1453 
1454     if (!nmi_fired) {
1455         report(nmi_fired, "intercepted pending NMI not dispatched");
1456         set_test_stage(test, -1);
1457     }
1458 
1459 }
1460 
1461 static bool nmi_finished(struct svm_test *test)
1462 {
1463     switch (get_test_stage(test)) {
1464     case 0:
1465         if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
1466             report(false, "VMEXIT not due to vmmcall. Exit reason 0x%x",
1467                    vmcb->control.exit_code);
1468             return true;
1469         }
1470         vmcb->save.rip += 3;
1471 
1472         vmcb->control.intercept |= (1ULL << INTERCEPT_NMI);
1473         break;
1474 
1475     case 1:
1476         if (vmcb->control.exit_code != SVM_EXIT_NMI) {
1477             report(false, "VMEXIT not due to NMI intercept. Exit reason 0x%x",
1478                    vmcb->control.exit_code);
1479             return true;
1480         }
1481 
1482         report(true, "NMI intercept while running guest");
1483         break;
1484 
1485     case 2:
1486         break;
1487 
1488     default:
1489         return true;
1490     }
1491 
1492     inc_test_stage(test);
1493 
1494     return get_test_stage(test) == 3;
1495 }
1496 
1497 static bool nmi_check(struct svm_test *test)
1498 {
1499     return get_test_stage(test) == 3;
1500 }
1501 
1502 #define NMI_DELAY 100000000ULL
1503 
1504 static void nmi_message_thread(void *_test)
1505 {
1506     struct svm_test *test = _test;
1507 
1508     while (get_test_stage(test) != 1)
1509         pause();
1510 
1511     delay(NMI_DELAY);
1512 
1513     apic_icr_write(APIC_DEST_PHYSICAL | APIC_DM_NMI | APIC_INT_ASSERT, id_map[0]);
1514 
1515     while (get_test_stage(test) != 2)
1516         pause();
1517 
1518     delay(NMI_DELAY);
1519 
1520     apic_icr_write(APIC_DEST_PHYSICAL | APIC_DM_NMI | APIC_INT_ASSERT, id_map[0]);
1521 }
1522 
1523 static void nmi_hlt_test(struct svm_test *test)
1524 {
1525     long long start;
1526 
1527     on_cpu_async(1, nmi_message_thread, test);
1528 
1529     start = rdtsc();
1530 
1531     set_test_stage(test, 1);
1532 
1533     asm volatile ("hlt");
1534 
1535     report((rdtsc() - start > NMI_DELAY) && nmi_fired,
1536           "direct NMI + hlt");
1537 
1538     if (!nmi_fired)
1539         set_test_stage(test, -1);
1540 
1541     nmi_fired = false;
1542 
1543     vmmcall();
1544 
1545     start = rdtsc();
1546 
1547     set_test_stage(test, 2);
1548 
1549     asm volatile ("hlt");
1550 
1551     report((rdtsc() - start > NMI_DELAY) && nmi_fired,
1552            "intercepted NMI + hlt");
1553 
1554     if (!nmi_fired) {
1555         report(nmi_fired, "intercepted pending NMI not dispatched");
1556         set_test_stage(test, -1);
1557         vmmcall();
1558     }
1559 
1560     set_test_stage(test, 3);
1561 }
1562 
1563 static bool nmi_hlt_finished(struct svm_test *test)
1564 {
1565     switch (get_test_stage(test)) {
1566     case 1:
1567         if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
1568             report(false, "VMEXIT not due to vmmcall. Exit reason 0x%x",
1569                    vmcb->control.exit_code);
1570             return true;
1571         }
1572         vmcb->save.rip += 3;
1573 
1574         vmcb->control.intercept |= (1ULL << INTERCEPT_NMI);
1575         break;
1576 
1577     case 2:
1578         if (vmcb->control.exit_code != SVM_EXIT_NMI) {
1579             report(false, "VMEXIT not due to NMI intercept. Exit reason 0x%x",
1580                    vmcb->control.exit_code);
1581             return true;
1582         }
1583 
1584         report(true, "NMI intercept while running guest");
1585         break;
1586 
1587     case 3:
1588         break;
1589 
1590     default:
1591         return true;
1592     }
1593 
1594     return get_test_stage(test) == 3;
1595 }
1596 
1597 static bool nmi_hlt_check(struct svm_test *test)
1598 {
1599     return get_test_stage(test) == 3;
1600 }
1601 
1602 static volatile int count_exc = 0;
1603 
1604 static void my_isr(struct ex_regs *r)
1605 {
1606         count_exc++;
1607 }
1608 
1609 static void exc_inject_prepare(struct svm_test *test)
1610 {
1611     default_prepare(test);
1612     handle_exception(DE_VECTOR, my_isr);
1613     handle_exception(NMI_VECTOR, my_isr);
1614 }
1615 
1616 
1617 static void exc_inject_test(struct svm_test *test)
1618 {
1619     asm volatile ("vmmcall\n\tvmmcall\n\t");
1620 }
1621 
1622 static bool exc_inject_finished(struct svm_test *test)
1623 {
1624     switch (get_test_stage(test)) {
1625     case 0:
1626         if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
1627             report(false, "VMEXIT not due to vmmcall. Exit reason 0x%x",
1628                    vmcb->control.exit_code);
1629             return true;
1630         }
1631         vmcb->save.rip += 3;
1632         vmcb->control.event_inj = NMI_VECTOR | SVM_EVTINJ_TYPE_EXEPT | SVM_EVTINJ_VALID;
1633         break;
1634 
1635     case 1:
1636         if (vmcb->control.exit_code != SVM_EXIT_ERR) {
1637             report(false, "VMEXIT not due to error. Exit reason 0x%x",
1638                    vmcb->control.exit_code);
1639             return true;
1640         }
1641         report(count_exc == 0, "exception with vector 2 not injected");
1642         vmcb->control.event_inj = DE_VECTOR | SVM_EVTINJ_TYPE_EXEPT | SVM_EVTINJ_VALID;
1643         break;
1644 
1645     case 2:
1646         if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
1647             report(false, "VMEXIT not due to vmmcall. Exit reason 0x%x",
1648                    vmcb->control.exit_code);
1649             return true;
1650         }
1651         vmcb->save.rip += 3;
1652         report(count_exc == 1, "divide overflow exception injected");
1653         report(!(vmcb->control.event_inj & SVM_EVTINJ_VALID), "eventinj.VALID cleared");
1654         break;
1655 
1656     default:
1657         return true;
1658     }
1659 
1660     inc_test_stage(test);
1661 
1662     return get_test_stage(test) == 3;
1663 }
1664 
1665 static bool exc_inject_check(struct svm_test *test)
1666 {
1667     return count_exc == 1 && get_test_stage(test) == 3;
1668 }
1669 
1670 static volatile bool virq_fired;
1671 
1672 static void virq_isr(isr_regs_t *regs)
1673 {
1674     virq_fired = true;
1675 }
1676 
1677 static void virq_inject_prepare(struct svm_test *test)
1678 {
1679     handle_irq(0xf1, virq_isr);
1680     default_prepare(test);
1681     vmcb->control.int_ctl = V_INTR_MASKING_MASK | V_IRQ_MASK |
1682                             (0x0f << V_INTR_PRIO_SHIFT); // Set to the highest priority
1683     vmcb->control.int_vector = 0xf1;
1684     virq_fired = false;
1685     set_test_stage(test, 0);
1686 }
1687 
1688 static void virq_inject_test(struct svm_test *test)
1689 {
1690     if (virq_fired) {
1691         report(false, "virtual interrupt fired before L2 sti");
1692         set_test_stage(test, -1);
1693         vmmcall();
1694     }
1695 
1696     irq_enable();
1697     asm volatile ("nop");
1698     irq_disable();
1699 
1700     if (!virq_fired) {
1701         report(false, "virtual interrupt not fired after L2 sti");
1702         set_test_stage(test, -1);
1703     }
1704 
1705     vmmcall();
1706 
1707     if (virq_fired) {
1708         report(false, "virtual interrupt fired before L2 sti after VINTR intercept");
1709         set_test_stage(test, -1);
1710         vmmcall();
1711     }
1712 
1713     irq_enable();
1714     asm volatile ("nop");
1715     irq_disable();
1716 
1717     if (!virq_fired) {
1718         report(false, "virtual interrupt not fired after return from VINTR intercept");
1719         set_test_stage(test, -1);
1720     }
1721 
1722     vmmcall();
1723 
1724     irq_enable();
1725     asm volatile ("nop");
1726     irq_disable();
1727 
1728     if (virq_fired) {
1729         report(false, "virtual interrupt fired when V_IRQ_PRIO less than V_TPR");
1730         set_test_stage(test, -1);
1731     }
1732 
1733     vmmcall();
1734     vmmcall();
1735 }
1736 
1737 static bool virq_inject_finished(struct svm_test *test)
1738 {
1739     vmcb->save.rip += 3;
1740 
1741     switch (get_test_stage(test)) {
1742     case 0:
1743         if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
1744             report(false, "VMEXIT not due to vmmcall. Exit reason 0x%x",
1745                    vmcb->control.exit_code);
1746             return true;
1747         }
1748         if (vmcb->control.int_ctl & V_IRQ_MASK) {
1749             report(false, "V_IRQ not cleared on VMEXIT after firing");
1750             return true;
1751         }
1752         virq_fired = false;
1753         vmcb->control.intercept |= (1ULL << INTERCEPT_VINTR);
1754         vmcb->control.int_ctl = V_INTR_MASKING_MASK | V_IRQ_MASK |
1755                             (0x0f << V_INTR_PRIO_SHIFT);
1756         break;
1757 
1758     case 1:
1759         if (vmcb->control.exit_code != SVM_EXIT_VINTR) {
1760             report(false, "VMEXIT not due to vintr. Exit reason 0x%x",
1761                    vmcb->control.exit_code);
1762             return true;
1763         }
1764         if (virq_fired) {
1765             report(false, "V_IRQ fired before SVM_EXIT_VINTR");
1766             return true;
1767         }
1768         vmcb->control.intercept &= ~(1ULL << INTERCEPT_VINTR);
1769         break;
1770 
1771     case 2:
1772         if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
1773             report(false, "VMEXIT not due to vmmcall. Exit reason 0x%x",
1774                    vmcb->control.exit_code);
1775             return true;
1776         }
1777         virq_fired = false;
1778         // Set irq to lower priority
1779         vmcb->control.int_ctl = V_INTR_MASKING_MASK | V_IRQ_MASK |
1780                             (0x08 << V_INTR_PRIO_SHIFT);
1781         // Raise guest TPR
1782         vmcb->control.int_ctl |= 0x0a & V_TPR_MASK;
1783         break;
1784 
1785     case 3:
1786         if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
1787             report(false, "VMEXIT not due to vmmcall. Exit reason 0x%x",
1788                    vmcb->control.exit_code);
1789             return true;
1790         }
1791         vmcb->control.intercept |= (1ULL << INTERCEPT_VINTR);
1792         break;
1793 
1794     case 4:
1795         // INTERCEPT_VINTR should be ignored because V_INTR_PRIO < V_TPR
1796         if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
1797             report(false, "VMEXIT not due to vmmcall. Exit reason 0x%x",
1798                    vmcb->control.exit_code);
1799             return true;
1800         }
1801         break;
1802 
1803     default:
1804         return true;
1805     }
1806 
1807     inc_test_stage(test);
1808 
1809     return get_test_stage(test) == 5;
1810 }
1811 
1812 static bool virq_inject_check(struct svm_test *test)
1813 {
1814     return get_test_stage(test) == 5;
1815 }
1816 
1817 /*
1818  * Detect nested guest RIP corruption as explained in kernel commit
1819  * b6162e82aef19fee9c32cb3fe9ac30d9116a8c73
1820  *
1821  * In the assembly loop below 'ins' is executed while IO instructions
1822  * are not intercepted; the instruction is emulated by L0.
1823  *
1824  * At the same time we are getting interrupts from the local APIC timer,
1825  * and we do intercept them in L1
1826  *
1827  * If the interrupt happens on the insb instruction, L0 will VMexit, emulate
1828  * the insb instruction and then it will inject the interrupt to L1 through
1829  * a nested VMexit.  Due to a bug, it would leave pre-emulation values of RIP,
1830  * RAX and RSP in the VMCB.
1831  *
1832  * In our intercept handler we detect the bug by checking that RIP is that of
1833  * the insb instruction, but its memory operand has already been written.
1834  * This means that insb was already executed.
1835  */
1836 
1837 static volatile int isr_cnt = 0;
1838 static volatile uint8_t io_port_var = 0xAA;
1839 extern const char insb_instruction_label[];
1840 
1841 static void reg_corruption_isr(isr_regs_t *regs)
1842 {
1843     isr_cnt++;
1844     apic_write(APIC_EOI, 0);
1845 }
1846 
1847 static void reg_corruption_prepare(struct svm_test *test)
1848 {
1849     default_prepare(test);
1850     set_test_stage(test, 0);
1851 
1852     vmcb->control.int_ctl = V_INTR_MASKING_MASK;
1853     vmcb->control.intercept |= (1ULL << INTERCEPT_INTR);
1854 
1855     handle_irq(TIMER_VECTOR, reg_corruption_isr);
1856 
1857     /* set local APIC to inject external interrupts */
1858     apic_write(APIC_TMICT, 0);
1859     apic_write(APIC_TDCR, 0);
1860     apic_write(APIC_LVTT, TIMER_VECTOR | APIC_LVT_TIMER_PERIODIC);
1861     apic_write(APIC_TMICT, 1000);
1862 }
1863 
1864 static void reg_corruption_test(struct svm_test *test)
1865 {
1866     /* this is endless loop, which is interrupted by the timer interrupt */
1867     asm volatile (
1868             "1:\n\t"
1869             "movw $0x4d0, %%dx\n\t" // IO port
1870             "lea %[io_port_var], %%rdi\n\t"
1871             "movb $0xAA, %[io_port_var]\n\t"
1872             "insb_instruction_label:\n\t"
1873             "insb\n\t"
1874             "jmp 1b\n\t"
1875 
1876             : [io_port_var] "=m" (io_port_var)
1877             : /* no inputs*/
1878             : "rdx", "rdi"
1879     );
1880 }
1881 
1882 static bool reg_corruption_finished(struct svm_test *test)
1883 {
1884     if (isr_cnt == 10000) {
1885         report(true,
1886                "No RIP corruption detected after %d timer interrupts",
1887                isr_cnt);
1888         set_test_stage(test, 1);
1889         return true;
1890     }
1891 
1892     if (vmcb->control.exit_code == SVM_EXIT_INTR) {
1893 
1894         void* guest_rip = (void*)vmcb->save.rip;
1895 
1896         irq_enable();
1897         asm volatile ("nop");
1898         irq_disable();
1899 
1900         if (guest_rip == insb_instruction_label && io_port_var != 0xAA) {
1901             report(false,
1902                    "RIP corruption detected after %d timer interrupts",
1903                    isr_cnt);
1904             return true;
1905         }
1906 
1907     }
1908     return false;
1909 }
1910 
1911 static bool reg_corruption_check(struct svm_test *test)
1912 {
1913     return get_test_stage(test) == 1;
1914 }
1915 
1916 static void get_tss_entry(void *data)
1917 {
1918     struct descriptor_table_ptr gdt;
1919     struct segment_desc64 *gdt_table;
1920     struct segment_desc64 *tss_entry;
1921     u16 tr = 0;
1922 
1923     sgdt(&gdt);
1924     tr = str();
1925     gdt_table = (struct segment_desc64 *) gdt.base;
1926     tss_entry = &gdt_table[tr / sizeof(struct segment_desc64)];
1927     *((struct segment_desc64 **)data) = tss_entry;
1928 }
1929 
1930 static int orig_cpu_count;
1931 
1932 static void init_startup_prepare(struct svm_test *test)
1933 {
1934     struct segment_desc64 *tss_entry;
1935     int i;
1936 
1937     vmcb_ident(vmcb);
1938 
1939     on_cpu(1, get_tss_entry, &tss_entry);
1940 
1941     orig_cpu_count = cpu_online_count;
1942 
1943     apic_icr_write(APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT,
1944                    id_map[1]);
1945 
1946     delay(100000000ULL);
1947 
1948     --cpu_online_count;
1949 
1950     *(uint64_t *)tss_entry &= ~DESC_BUSY;
1951 
1952     apic_icr_write(APIC_DEST_PHYSICAL | APIC_DM_STARTUP, id_map[1]);
1953 
1954     for (i = 0; i < 5 && cpu_online_count < orig_cpu_count; i++)
1955        delay(100000000ULL);
1956 }
1957 
1958 static bool init_startup_finished(struct svm_test *test)
1959 {
1960     return true;
1961 }
1962 
1963 static bool init_startup_check(struct svm_test *test)
1964 {
1965     return cpu_online_count == orig_cpu_count;
1966 }
1967 
1968 static volatile bool init_intercept;
1969 
1970 static void init_intercept_prepare(struct svm_test *test)
1971 {
1972     init_intercept = false;
1973     vmcb_ident(vmcb);
1974     vmcb->control.intercept |= (1ULL << INTERCEPT_INIT);
1975 }
1976 
1977 static void init_intercept_test(struct svm_test *test)
1978 {
1979     apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT, 0);
1980 }
1981 
1982 static bool init_intercept_finished(struct svm_test *test)
1983 {
1984     vmcb->save.rip += 3;
1985 
1986     if (vmcb->control.exit_code != SVM_EXIT_INIT) {
1987         report(false, "VMEXIT not due to init intercept. Exit reason 0x%x",
1988                vmcb->control.exit_code);
1989 
1990         return true;
1991         }
1992 
1993     init_intercept = true;
1994 
1995     report(true, "INIT to vcpu intercepted");
1996 
1997     return true;
1998 }
1999 
2000 static bool init_intercept_check(struct svm_test *test)
2001 {
2002     return init_intercept;
2003 }
2004 
2005 #define TEST(name) { #name, .v2 = name }
2006 
2007 /*
2008  * v2 tests
2009  */
2010 
2011 /*
2012  * Ensure that kvm recalculates the L1 guest's CPUID.01H:ECX.OSXSAVE
2013  * after VM-exit from an L2 guest that sets CR4.OSXSAVE to a different
2014  * value than in L1.
2015  */
2016 
2017 static void svm_cr4_osxsave_test_guest(struct svm_test *test)
2018 {
2019 	write_cr4(read_cr4() & ~X86_CR4_OSXSAVE);
2020 }
2021 
2022 static void svm_cr4_osxsave_test(void)
2023 {
2024 	if (!this_cpu_has(X86_FEATURE_XSAVE)) {
2025 		report_skip("XSAVE not detected");
2026 		return;
2027 	}
2028 
2029 	if (!(read_cr4() & X86_CR4_OSXSAVE)) {
2030 		unsigned long cr4 = read_cr4() | X86_CR4_OSXSAVE;
2031 
2032 		write_cr4(cr4);
2033 		vmcb->save.cr4 = cr4;
2034 	}
2035 
2036 	report(cpuid_osxsave(), "CPUID.01H:ECX.XSAVE set before VMRUN");
2037 
2038 	test_set_guest(svm_cr4_osxsave_test_guest);
2039 	report(svm_vmrun() == SVM_EXIT_VMMCALL,
2040 	       "svm_cr4_osxsave_test_guest finished with VMMCALL");
2041 
2042 	report(cpuid_osxsave(), "CPUID.01H:ECX.XSAVE set after VMRUN");
2043 }
2044 
2045 static void basic_guest_main(struct svm_test *test)
2046 {
2047 }
2048 
2049 
2050 #define SVM_TEST_REG_RESERVED_BITS(start, end, inc, str_name, reg, val,	\
2051 				   resv_mask)				\
2052 {									\
2053         u64 tmp, mask;							\
2054         int i;								\
2055 									\
2056         for (i = start; i <= end; i = i + inc) {			\
2057                 mask = 1ull << i;					\
2058                 if (!(mask & resv_mask))				\
2059                         continue;					\
2060                 tmp = val | mask;					\
2061 		reg = tmp;						\
2062 		report(svm_vmrun() == SVM_EXIT_ERR, "Test %s %d:%d: %lx",\
2063 		    str_name, end, start, tmp);				\
2064         }								\
2065 }
2066 
2067 #define SVM_TEST_CR_RESERVED_BITS(start, end, inc, cr, val, resv_mask,	\
2068 				  exit_code, test_name)			\
2069 {									\
2070 	u64 tmp, mask;							\
2071 	int i;								\
2072 									\
2073 	for (i = start; i <= end; i = i + inc) {			\
2074 		mask = 1ull << i;					\
2075 		if (!(mask & resv_mask))				\
2076 			continue;					\
2077 		tmp = val | mask;					\
2078 		switch (cr) {						\
2079 		case 0:							\
2080 			vmcb->save.cr0 = tmp;				\
2081 			break;						\
2082 		case 3:							\
2083 			vmcb->save.cr3 = tmp;				\
2084 			break;						\
2085 		case 4:							\
2086 			vmcb->save.cr4 = tmp;				\
2087 		}							\
2088 		report(svm_vmrun() == exit_code, "Test CR%d " test_name "%d:%d: %lx",\
2089 		    cr, end, start, tmp);				\
2090 	}								\
2091 }
2092 
2093 static void test_efer(void)
2094 {
2095 	/*
2096 	 * Un-setting EFER.SVME is illegal
2097 	 */
2098 	u64 efer_saved = vmcb->save.efer;
2099 	u64 efer = efer_saved;
2100 
2101 	report (svm_vmrun() == SVM_EXIT_VMMCALL, "EFER.SVME: %lx", efer);
2102 	efer &= ~EFER_SVME;
2103 	vmcb->save.efer = efer;
2104 	report (svm_vmrun() == SVM_EXIT_ERR, "EFER.SVME: %lx", efer);
2105 	vmcb->save.efer = efer_saved;
2106 
2107 	/*
2108 	 * EFER MBZ bits: 63:16, 9
2109 	 */
2110 	efer_saved = vmcb->save.efer;
2111 
2112 	SVM_TEST_REG_RESERVED_BITS(8, 9, 1, "EFER", vmcb->save.efer,
2113 	    efer_saved, SVM_EFER_RESERVED_MASK);
2114 	SVM_TEST_REG_RESERVED_BITS(16, 63, 4, "EFER", vmcb->save.efer,
2115 	    efer_saved, SVM_EFER_RESERVED_MASK);
2116 
2117 	/*
2118 	 * EFER.LME and CR0.PG are both set and CR4.PAE is zero.
2119 	 */
2120 	u64 cr0_saved = vmcb->save.cr0;
2121 	u64 cr0;
2122 	u64 cr4_saved = vmcb->save.cr4;
2123 	u64 cr4;
2124 
2125 	efer = efer_saved | EFER_LME;
2126 	vmcb->save.efer = efer;
2127 	cr0 = cr0_saved | X86_CR0_PG | X86_CR0_PE;
2128 	vmcb->save.cr0 = cr0;
2129 	cr4 = cr4_saved & ~X86_CR4_PAE;
2130 	vmcb->save.cr4 = cr4;
2131 	report(svm_vmrun() == SVM_EXIT_ERR, "EFER.LME=1 (%lx), "
2132 	    "CR0.PG=1 (%lx) and CR4.PAE=0 (%lx)", efer, cr0, cr4);
2133 
2134 	/*
2135 	 * EFER.LME and CR0.PG are both set and CR0.PE is zero.
2136 	 */
2137 	vmcb->save.cr4 = cr4_saved | X86_CR4_PAE;
2138 	cr0 &= ~X86_CR0_PE;
2139 	vmcb->save.cr0 = cr0;
2140 	report(svm_vmrun() == SVM_EXIT_ERR, "EFER.LME=1 (%lx), "
2141 	    "CR0.PG=1 and CR0.PE=0 (%lx)", efer, cr0);
2142 
2143 	/*
2144 	 * EFER.LME, CR0.PG, CR4.PAE, CS.L, and CS.D are all non-zero.
2145 	 */
2146 	u32 cs_attrib_saved = vmcb->save.cs.attrib;
2147 	u32 cs_attrib;
2148 
2149 	cr0 |= X86_CR0_PE;
2150 	vmcb->save.cr0 = cr0;
2151 	cs_attrib = cs_attrib_saved | SVM_SELECTOR_L_MASK |
2152 	    SVM_SELECTOR_DB_MASK;
2153 	vmcb->save.cs.attrib = cs_attrib;
2154 	report(svm_vmrun() == SVM_EXIT_ERR, "EFER.LME=1 (%lx), "
2155 	    "CR0.PG=1 (%lx), CR4.PAE=1 (%lx), CS.L=1 and CS.D=1 (%x)",
2156 	    efer, cr0, cr4, cs_attrib);
2157 
2158 	vmcb->save.cr0 = cr0_saved;
2159 	vmcb->save.cr4 = cr4_saved;
2160 	vmcb->save.efer = efer_saved;
2161 	vmcb->save.cs.attrib = cs_attrib_saved;
2162 }
2163 
2164 static void test_cr0(void)
2165 {
2166 	/*
2167 	 * Un-setting CR0.CD and setting CR0.NW is illegal combination
2168 	 */
2169 	u64 cr0_saved = vmcb->save.cr0;
2170 	u64 cr0 = cr0_saved;
2171 
2172 	cr0 |= X86_CR0_CD;
2173 	cr0 &= ~X86_CR0_NW;
2174 	vmcb->save.cr0 = cr0;
2175 	report (svm_vmrun() == SVM_EXIT_VMMCALL, "Test CR0 CD=1,NW=0: %lx",
2176 	    cr0);
2177 	cr0 |= X86_CR0_NW;
2178 	vmcb->save.cr0 = cr0;
2179 	report (svm_vmrun() == SVM_EXIT_VMMCALL, "Test CR0 CD=1,NW=1: %lx",
2180 	    cr0);
2181 	cr0 &= ~X86_CR0_NW;
2182 	cr0 &= ~X86_CR0_CD;
2183 	vmcb->save.cr0 = cr0;
2184 	report (svm_vmrun() == SVM_EXIT_VMMCALL, "Test CR0 CD=0,NW=0: %lx",
2185 	    cr0);
2186 	cr0 |= X86_CR0_NW;
2187 	vmcb->save.cr0 = cr0;
2188 	report (svm_vmrun() == SVM_EXIT_ERR, "Test CR0 CD=0,NW=1: %lx",
2189 	    cr0);
2190 	vmcb->save.cr0 = cr0_saved;
2191 
2192 	/*
2193 	 * CR0[63:32] are not zero
2194 	 */
2195 	cr0 = cr0_saved;
2196 
2197 	SVM_TEST_REG_RESERVED_BITS(32, 63, 4, "CR0", vmcb->save.cr0, cr0_saved,
2198 	    SVM_CR0_RESERVED_MASK);
2199 	vmcb->save.cr0 = cr0_saved;
2200 }
2201 
2202 static void test_cr3(void)
2203 {
2204 	/*
2205 	 * CR3 MBZ bits based on different modes:
2206 	 *   [63:52] - long mode
2207 	 */
2208 	u64 cr3_saved = vmcb->save.cr3;
2209 
2210 	SVM_TEST_CR_RESERVED_BITS(0, 63, 1, 3, cr3_saved,
2211 	    SVM_CR3_LONG_MBZ_MASK, SVM_EXIT_ERR, "");
2212 
2213 	vmcb->save.cr3 = cr3_saved & ~SVM_CR3_LONG_MBZ_MASK;
2214 	report(svm_vmrun() == SVM_EXIT_VMMCALL, "Test CR3 63:0: %lx",
2215 	    vmcb->save.cr3);
2216 
2217 	/*
2218 	 * CR3 non-MBZ reserved bits based on different modes:
2219 	 *   [11:5] [2:0] - long mode (PCIDE=0)
2220 	 *          [2:0] - PAE legacy mode
2221 	 */
2222 	u64 cr4_saved = vmcb->save.cr4;
2223 	u64 *pdpe = npt_get_pml4e();
2224 
2225 	/*
2226 	 * Long mode
2227 	 */
2228 	if (this_cpu_has(X86_FEATURE_PCID)) {
2229 		vmcb->save.cr4 = cr4_saved | X86_CR4_PCIDE;
2230 		SVM_TEST_CR_RESERVED_BITS(0, 11, 1, 3, cr3_saved,
2231 		    SVM_CR3_LONG_RESERVED_MASK, SVM_EXIT_VMMCALL, "(PCIDE=1) ");
2232 
2233 		vmcb->save.cr3 = cr3_saved & ~SVM_CR3_LONG_RESERVED_MASK;
2234 		report(svm_vmrun() == SVM_EXIT_VMMCALL, "Test CR3 63:0: %lx",
2235 		    vmcb->save.cr3);
2236 	}
2237 
2238 	vmcb->save.cr4 = cr4_saved & ~X86_CR4_PCIDE;
2239 
2240 	/* Clear P (Present) bit in NPT in order to trigger #NPF */
2241 	pdpe[0] &= ~1ULL;
2242 
2243 	SVM_TEST_CR_RESERVED_BITS(0, 11, 1, 3, cr3_saved,
2244 	    SVM_CR3_LONG_RESERVED_MASK, SVM_EXIT_NPF, "(PCIDE=0) ");
2245 
2246 	pdpe[0] |= 1ULL;
2247 	vmcb->save.cr3 = cr3_saved;
2248 
2249 	/*
2250 	 * PAE legacy
2251 	 */
2252 	pdpe[0] &= ~1ULL;
2253 	vmcb->save.cr4 = cr4_saved | X86_CR4_PAE;
2254 	SVM_TEST_CR_RESERVED_BITS(0, 2, 1, 3, cr3_saved,
2255 	    SVM_CR3_PAE_LEGACY_RESERVED_MASK, SVM_EXIT_NPF, "(PAE) ");
2256 
2257 	pdpe[0] |= 1ULL;
2258 	vmcb->save.cr3 = cr3_saved;
2259 	vmcb->save.cr4 = cr4_saved;
2260 }
2261 
2262 static void test_cr4(void)
2263 {
2264 	/*
2265 	 * CR4 MBZ bits based on different modes:
2266 	 *   [15:12], 17, 19, [31:22] - legacy mode
2267 	 *   [15:12], 17, 19, [63:22] - long mode
2268 	 */
2269 	u64 cr4_saved = vmcb->save.cr4;
2270 	u64 efer_saved = vmcb->save.efer;
2271 	u64 efer = efer_saved;
2272 
2273 	efer &= ~EFER_LME;
2274 	vmcb->save.efer = efer;
2275 	SVM_TEST_CR_RESERVED_BITS(12, 31, 1, 4, cr4_saved,
2276 	    SVM_CR4_LEGACY_RESERVED_MASK, SVM_EXIT_ERR, "");
2277 
2278 	efer |= EFER_LME;
2279 	vmcb->save.efer = efer;
2280 	SVM_TEST_CR_RESERVED_BITS(12, 31, 1, 4, cr4_saved,
2281 	    SVM_CR4_RESERVED_MASK, SVM_EXIT_ERR, "");
2282 	SVM_TEST_CR_RESERVED_BITS(32, 63, 4, 4, cr4_saved,
2283 	    SVM_CR4_RESERVED_MASK, SVM_EXIT_ERR, "");
2284 
2285 	vmcb->save.cr4 = cr4_saved;
2286 	vmcb->save.efer = efer_saved;
2287 }
2288 
2289 static void test_dr(void)
2290 {
2291 	/*
2292 	 * DR6[63:32] and DR7[63:32] are MBZ
2293 	 */
2294 	u64 dr_saved = vmcb->save.dr6;
2295 
2296 	SVM_TEST_REG_RESERVED_BITS(32, 63, 4, "DR6", vmcb->save.dr6, dr_saved,
2297 	    SVM_DR6_RESERVED_MASK);
2298 	vmcb->save.dr6 = dr_saved;
2299 
2300 	dr_saved = vmcb->save.dr7;
2301 	SVM_TEST_REG_RESERVED_BITS(32, 63, 4, "DR7", vmcb->save.dr7, dr_saved,
2302 	    SVM_DR7_RESERVED_MASK);
2303 
2304 	vmcb->save.dr7 = dr_saved;
2305 }
2306 
2307 static void svm_guest_state_test(void)
2308 {
2309 	test_set_guest(basic_guest_main);
2310 
2311 	test_efer();
2312 	test_cr0();
2313 	test_cr3();
2314 	test_cr4();
2315 	test_dr();
2316 }
2317 
2318 
2319 static bool volatile svm_errata_reproduced = false;
2320 static unsigned long volatile physical = 0;
2321 
2322 
2323 /*
2324  *
2325  * Test the following errata:
2326  * If the VMRUN/VMSAVE/VMLOAD are attempted by the nested guest,
2327  * the CPU would first check the EAX against host reserved memory
2328  * regions (so far only SMM_ADDR/SMM_MASK are known to cause it),
2329  * and only then signal #VMexit
2330  *
2331  * Try to reproduce this by trying vmsave on each possible 4K aligned memory
2332  * address in the low 4G where the SMM area has to reside.
2333  */
2334 
2335 static void gp_isr(struct ex_regs *r)
2336 {
2337     svm_errata_reproduced = true;
2338     /* skip over the vmsave instruction*/
2339     r->rip += 3;
2340 }
2341 
2342 static void svm_vmrun_errata_test(void)
2343 {
2344     unsigned long *last_page = NULL;
2345 
2346     handle_exception(GP_VECTOR, gp_isr);
2347 
2348     while (!svm_errata_reproduced) {
2349 
2350         unsigned long *page = alloc_pages(1);
2351 
2352         if (!page) {
2353             report(true, "All guest memory tested, no bug found");;
2354             break;
2355         }
2356 
2357         physical = virt_to_phys(page);
2358 
2359         asm volatile (
2360             "mov %[_physical], %%rax\n\t"
2361             "vmsave %%rax\n\t"
2362 
2363             : [_physical] "=m" (physical)
2364             : /* no inputs*/
2365             : "rax" /*clobbers*/
2366         );
2367 
2368         if (svm_errata_reproduced) {
2369             report(false, "Got #GP exception - svm errata reproduced at 0x%lx",
2370                    physical);
2371             break;
2372         }
2373 
2374         *page = (unsigned long)last_page;
2375         last_page = page;
2376     }
2377 
2378     while (last_page) {
2379         unsigned long *page = last_page;
2380         last_page = (unsigned long *)*last_page;
2381         free_pages_by_order(page, 1);
2382     }
2383 }
2384 
2385 struct svm_test svm_tests[] = {
2386     { "null", default_supported, default_prepare,
2387       default_prepare_gif_clear, null_test,
2388       default_finished, null_check },
2389     { "vmrun", default_supported, default_prepare,
2390       default_prepare_gif_clear, test_vmrun,
2391        default_finished, check_vmrun },
2392     { "ioio", default_supported, prepare_ioio,
2393        default_prepare_gif_clear, test_ioio,
2394        ioio_finished, check_ioio },
2395     { "vmrun intercept check", default_supported, prepare_no_vmrun_int,
2396       default_prepare_gif_clear, null_test, default_finished,
2397       check_no_vmrun_int },
2398     { "rsm", default_supported,
2399       prepare_rsm_intercept, default_prepare_gif_clear,
2400       test_rsm_intercept, finished_rsm_intercept, check_rsm_intercept },
2401     { "cr3 read intercept", default_supported,
2402       prepare_cr3_intercept, default_prepare_gif_clear,
2403       test_cr3_intercept, default_finished, check_cr3_intercept },
2404     { "cr3 read nointercept", default_supported, default_prepare,
2405       default_prepare_gif_clear, test_cr3_intercept, default_finished,
2406       check_cr3_nointercept },
2407     { "cr3 read intercept emulate", smp_supported,
2408       prepare_cr3_intercept_bypass, default_prepare_gif_clear,
2409       test_cr3_intercept_bypass, default_finished, check_cr3_intercept },
2410     { "dr intercept check", default_supported, prepare_dr_intercept,
2411       default_prepare_gif_clear, test_dr_intercept, dr_intercept_finished,
2412       check_dr_intercept },
2413     { "next_rip", next_rip_supported, prepare_next_rip,
2414       default_prepare_gif_clear, test_next_rip,
2415       default_finished, check_next_rip },
2416     { "msr intercept check", default_supported, prepare_msr_intercept,
2417       default_prepare_gif_clear, test_msr_intercept,
2418       msr_intercept_finished, check_msr_intercept },
2419     { "mode_switch", default_supported, prepare_mode_switch,
2420       default_prepare_gif_clear, test_mode_switch,
2421        mode_switch_finished, check_mode_switch },
2422     { "asid_zero", default_supported, prepare_asid_zero,
2423       default_prepare_gif_clear, test_asid_zero,
2424        default_finished, check_asid_zero },
2425     { "sel_cr0_bug", default_supported, sel_cr0_bug_prepare,
2426       default_prepare_gif_clear, sel_cr0_bug_test,
2427        sel_cr0_bug_finished, sel_cr0_bug_check },
2428     { "npt_nx", npt_supported, npt_nx_prepare,
2429       default_prepare_gif_clear, null_test,
2430       default_finished, npt_nx_check },
2431     { "npt_np", npt_supported, npt_np_prepare,
2432       default_prepare_gif_clear, npt_np_test,
2433       default_finished, npt_np_check },
2434     { "npt_us", npt_supported, npt_us_prepare,
2435       default_prepare_gif_clear, npt_us_test,
2436       default_finished, npt_us_check },
2437     { "npt_rsvd", npt_supported, npt_rsvd_prepare,
2438       default_prepare_gif_clear, null_test,
2439       default_finished, npt_rsvd_check },
2440     { "npt_rw", npt_supported, npt_rw_prepare,
2441       default_prepare_gif_clear, npt_rw_test,
2442       default_finished, npt_rw_check },
2443     { "npt_rsvd_pfwalk", npt_supported, npt_rsvd_pfwalk_prepare,
2444       default_prepare_gif_clear, null_test,
2445       default_finished, npt_rsvd_pfwalk_check },
2446     { "npt_rw_pfwalk", npt_supported, npt_rw_pfwalk_prepare,
2447       default_prepare_gif_clear, null_test,
2448       default_finished, npt_rw_pfwalk_check },
2449     { "npt_l1mmio", npt_supported, npt_l1mmio_prepare,
2450       default_prepare_gif_clear, npt_l1mmio_test,
2451       default_finished, npt_l1mmio_check },
2452     { "npt_rw_l1mmio", npt_supported, npt_rw_l1mmio_prepare,
2453       default_prepare_gif_clear, npt_rw_l1mmio_test,
2454       default_finished, npt_rw_l1mmio_check },
2455     { "tsc_adjust", tsc_adjust_supported, tsc_adjust_prepare,
2456       default_prepare_gif_clear, tsc_adjust_test,
2457       default_finished, tsc_adjust_check },
2458     { "latency_run_exit", default_supported, latency_prepare,
2459       default_prepare_gif_clear, latency_test,
2460       latency_finished, latency_check },
2461     { "latency_svm_insn", default_supported, lat_svm_insn_prepare,
2462       default_prepare_gif_clear, null_test,
2463       lat_svm_insn_finished, lat_svm_insn_check },
2464     { "exc_inject", default_supported, exc_inject_prepare,
2465       default_prepare_gif_clear, exc_inject_test,
2466       exc_inject_finished, exc_inject_check },
2467     { "pending_event", default_supported, pending_event_prepare,
2468       default_prepare_gif_clear,
2469       pending_event_test, pending_event_finished, pending_event_check },
2470     { "pending_event_cli", default_supported, pending_event_cli_prepare,
2471       pending_event_cli_prepare_gif_clear,
2472       pending_event_cli_test, pending_event_cli_finished,
2473       pending_event_cli_check },
2474     { "interrupt", default_supported, interrupt_prepare,
2475       default_prepare_gif_clear, interrupt_test,
2476       interrupt_finished, interrupt_check },
2477     { "nmi", default_supported, nmi_prepare,
2478       default_prepare_gif_clear, nmi_test,
2479       nmi_finished, nmi_check },
2480     { "nmi_hlt", smp_supported, nmi_prepare,
2481       default_prepare_gif_clear, nmi_hlt_test,
2482       nmi_hlt_finished, nmi_hlt_check },
2483     { "virq_inject", default_supported, virq_inject_prepare,
2484       default_prepare_gif_clear, virq_inject_test,
2485       virq_inject_finished, virq_inject_check },
2486     { "reg_corruption", default_supported, reg_corruption_prepare,
2487       default_prepare_gif_clear, reg_corruption_test,
2488       reg_corruption_finished, reg_corruption_check },
2489     { "svm_init_startup_test", smp_supported, init_startup_prepare,
2490       default_prepare_gif_clear, null_test,
2491       init_startup_finished, init_startup_check },
2492     { "svm_init_intercept_test", smp_supported, init_intercept_prepare,
2493       default_prepare_gif_clear, init_intercept_test,
2494       init_intercept_finished, init_intercept_check, .on_vcpu = 2 },
2495     TEST(svm_cr4_osxsave_test),
2496     TEST(svm_guest_state_test),
2497     TEST(svm_vmrun_errata_test),
2498     { NULL, NULL, NULL, NULL, NULL, NULL, NULL }
2499 };
2500