1*63a180cbSSean Christopherson #include "apic.h" 262f5db4bSSean Christopherson #include "svm.h" 362f5db4bSSean Christopherson #include "vm.h" 462f5db4bSSean Christopherson #include "alloc_page.h" 562f5db4bSSean Christopherson #include "vmalloc.h" 662f5db4bSSean Christopherson 762f5db4bSSean Christopherson static void *scratch_page; 862f5db4bSSean Christopherson 962f5db4bSSean Christopherson static void null_test(struct svm_test *test) 1062f5db4bSSean Christopherson { 1162f5db4bSSean Christopherson } 1262f5db4bSSean Christopherson 1362f5db4bSSean Christopherson static void npt_np_prepare(struct svm_test *test) 1462f5db4bSSean Christopherson { 1562f5db4bSSean Christopherson u64 *pte; 1662f5db4bSSean Christopherson 1762f5db4bSSean Christopherson scratch_page = alloc_page(); 1862f5db4bSSean Christopherson pte = npt_get_pte((u64) scratch_page); 1962f5db4bSSean Christopherson 2062f5db4bSSean Christopherson *pte &= ~1ULL; 2162f5db4bSSean Christopherson } 2262f5db4bSSean Christopherson 2362f5db4bSSean Christopherson static void npt_np_test(struct svm_test *test) 2462f5db4bSSean Christopherson { 2562f5db4bSSean Christopherson (void)*(volatile u64 *)scratch_page; 2662f5db4bSSean Christopherson } 2762f5db4bSSean Christopherson 2862f5db4bSSean Christopherson static bool npt_np_check(struct svm_test *test) 2962f5db4bSSean Christopherson { 3062f5db4bSSean Christopherson u64 *pte = npt_get_pte((u64) scratch_page); 3162f5db4bSSean Christopherson 3262f5db4bSSean Christopherson *pte |= 1ULL; 3362f5db4bSSean Christopherson 3462f5db4bSSean Christopherson return (vmcb->control.exit_code == SVM_EXIT_NPF) 3562f5db4bSSean Christopherson && (vmcb->control.exit_info_1 == 0x100000004ULL); 3662f5db4bSSean Christopherson } 3762f5db4bSSean Christopherson 3862f5db4bSSean Christopherson static void npt_nx_prepare(struct svm_test *test) 3962f5db4bSSean Christopherson { 4062f5db4bSSean Christopherson u64 *pte; 4162f5db4bSSean Christopherson 4262f5db4bSSean Christopherson test->scratch = rdmsr(MSR_EFER); 4362f5db4bSSean Christopherson wrmsr(MSR_EFER, test->scratch | EFER_NX); 4462f5db4bSSean Christopherson 4562f5db4bSSean Christopherson /* Clear the guest's EFER.NX, it should not affect NPT behavior. */ 4662f5db4bSSean Christopherson vmcb->save.efer &= ~EFER_NX; 4762f5db4bSSean Christopherson 4862f5db4bSSean Christopherson pte = npt_get_pte((u64) null_test); 4962f5db4bSSean Christopherson 5062f5db4bSSean Christopherson *pte |= PT64_NX_MASK; 5162f5db4bSSean Christopherson } 5262f5db4bSSean Christopherson 5362f5db4bSSean Christopherson static bool npt_nx_check(struct svm_test *test) 5462f5db4bSSean Christopherson { 5562f5db4bSSean Christopherson u64 *pte = npt_get_pte((u64) null_test); 5662f5db4bSSean Christopherson 5762f5db4bSSean Christopherson wrmsr(MSR_EFER, test->scratch); 5862f5db4bSSean Christopherson 5962f5db4bSSean Christopherson *pte &= ~PT64_NX_MASK; 6062f5db4bSSean Christopherson 6162f5db4bSSean Christopherson return (vmcb->control.exit_code == SVM_EXIT_NPF) 6262f5db4bSSean Christopherson && (vmcb->control.exit_info_1 == 0x100000015ULL); 6362f5db4bSSean Christopherson } 6462f5db4bSSean Christopherson 6562f5db4bSSean Christopherson static void npt_us_prepare(struct svm_test *test) 6662f5db4bSSean Christopherson { 6762f5db4bSSean Christopherson u64 *pte; 6862f5db4bSSean Christopherson 6962f5db4bSSean Christopherson scratch_page = alloc_page(); 7062f5db4bSSean Christopherson pte = npt_get_pte((u64) scratch_page); 7162f5db4bSSean Christopherson 7262f5db4bSSean Christopherson *pte &= ~(1ULL << 2); 7362f5db4bSSean Christopherson } 7462f5db4bSSean Christopherson 7562f5db4bSSean Christopherson static void npt_us_test(struct svm_test *test) 7662f5db4bSSean Christopherson { 7762f5db4bSSean Christopherson (void)*(volatile u64 *)scratch_page; 7862f5db4bSSean Christopherson } 7962f5db4bSSean Christopherson 8062f5db4bSSean Christopherson static bool npt_us_check(struct svm_test *test) 8162f5db4bSSean Christopherson { 8262f5db4bSSean Christopherson u64 *pte = npt_get_pte((u64) scratch_page); 8362f5db4bSSean Christopherson 8462f5db4bSSean Christopherson *pte |= (1ULL << 2); 8562f5db4bSSean Christopherson 8662f5db4bSSean Christopherson return (vmcb->control.exit_code == SVM_EXIT_NPF) 8762f5db4bSSean Christopherson && (vmcb->control.exit_info_1 == 0x100000005ULL); 8862f5db4bSSean Christopherson } 8962f5db4bSSean Christopherson 9062f5db4bSSean Christopherson static void npt_rw_prepare(struct svm_test *test) 9162f5db4bSSean Christopherson { 9262f5db4bSSean Christopherson 9362f5db4bSSean Christopherson u64 *pte; 9462f5db4bSSean Christopherson 9562f5db4bSSean Christopherson pte = npt_get_pte(0x80000); 9662f5db4bSSean Christopherson 9762f5db4bSSean Christopherson *pte &= ~(1ULL << 1); 9862f5db4bSSean Christopherson } 9962f5db4bSSean Christopherson 10062f5db4bSSean Christopherson static void npt_rw_test(struct svm_test *test) 10162f5db4bSSean Christopherson { 10262f5db4bSSean Christopherson u64 *data = (void *)(0x80000); 10362f5db4bSSean Christopherson 10462f5db4bSSean Christopherson *data = 0; 10562f5db4bSSean Christopherson } 10662f5db4bSSean Christopherson 10762f5db4bSSean Christopherson static bool npt_rw_check(struct svm_test *test) 10862f5db4bSSean Christopherson { 10962f5db4bSSean Christopherson u64 *pte = npt_get_pte(0x80000); 11062f5db4bSSean Christopherson 11162f5db4bSSean Christopherson *pte |= (1ULL << 1); 11262f5db4bSSean Christopherson 11362f5db4bSSean Christopherson return (vmcb->control.exit_code == SVM_EXIT_NPF) 11462f5db4bSSean Christopherson && (vmcb->control.exit_info_1 == 0x100000007ULL); 11562f5db4bSSean Christopherson } 11662f5db4bSSean Christopherson 11762f5db4bSSean Christopherson static void npt_rw_pfwalk_prepare(struct svm_test *test) 11862f5db4bSSean Christopherson { 11962f5db4bSSean Christopherson 12062f5db4bSSean Christopherson u64 *pte; 12162f5db4bSSean Christopherson 12262f5db4bSSean Christopherson pte = npt_get_pte(read_cr3()); 12362f5db4bSSean Christopherson 12462f5db4bSSean Christopherson *pte &= ~(1ULL << 1); 12562f5db4bSSean Christopherson } 12662f5db4bSSean Christopherson 12762f5db4bSSean Christopherson static bool npt_rw_pfwalk_check(struct svm_test *test) 12862f5db4bSSean Christopherson { 12962f5db4bSSean Christopherson u64 *pte = npt_get_pte(read_cr3()); 13062f5db4bSSean Christopherson 13162f5db4bSSean Christopherson *pte |= (1ULL << 1); 13262f5db4bSSean Christopherson 13362f5db4bSSean Christopherson return (vmcb->control.exit_code == SVM_EXIT_NPF) 13462f5db4bSSean Christopherson && (vmcb->control.exit_info_1 == 0x200000007ULL) 13562f5db4bSSean Christopherson && (vmcb->control.exit_info_2 == read_cr3()); 13662f5db4bSSean Christopherson } 13762f5db4bSSean Christopherson 138*63a180cbSSean Christopherson static bool was_x2apic; 139*63a180cbSSean Christopherson 140*63a180cbSSean Christopherson static void npt_apic_prepare(void) 141*63a180cbSSean Christopherson { 142*63a180cbSSean Christopherson was_x2apic = is_x2apic_enabled(); 143*63a180cbSSean Christopherson 144*63a180cbSSean Christopherson if (was_x2apic) 145*63a180cbSSean Christopherson reset_apic(); 146*63a180cbSSean Christopherson } 147*63a180cbSSean Christopherson 148*63a180cbSSean Christopherson static void npt_apic_restore(void) 149*63a180cbSSean Christopherson { 150*63a180cbSSean Christopherson if (was_x2apic) 151*63a180cbSSean Christopherson enable_x2apic(); 152*63a180cbSSean Christopherson 153*63a180cbSSean Christopherson was_x2apic = false; 154*63a180cbSSean Christopherson } 155*63a180cbSSean Christopherson 15662f5db4bSSean Christopherson static void npt_l1mmio_prepare(struct svm_test *test) 15762f5db4bSSean Christopherson { 158*63a180cbSSean Christopherson npt_apic_prepare(); 15962f5db4bSSean Christopherson } 16062f5db4bSSean Christopherson 16162f5db4bSSean Christopherson u32 nested_apic_version1; 16262f5db4bSSean Christopherson u32 nested_apic_version2; 16362f5db4bSSean Christopherson 16462f5db4bSSean Christopherson static void npt_l1mmio_test(struct svm_test *test) 16562f5db4bSSean Christopherson { 16662f5db4bSSean Christopherson volatile u32 *data = (volatile void *)(0xfee00030UL); 16762f5db4bSSean Christopherson 16862f5db4bSSean Christopherson nested_apic_version1 = *data; 16962f5db4bSSean Christopherson nested_apic_version2 = *data; 17062f5db4bSSean Christopherson } 17162f5db4bSSean Christopherson 17262f5db4bSSean Christopherson static bool npt_l1mmio_check(struct svm_test *test) 17362f5db4bSSean Christopherson { 17462f5db4bSSean Christopherson volatile u32 *data = (volatile void *)(0xfee00030); 17562f5db4bSSean Christopherson u32 lvr = *data; 17662f5db4bSSean Christopherson 177*63a180cbSSean Christopherson /* Restore APIC state *after* reading LVR. */ 178*63a180cbSSean Christopherson npt_apic_restore(); 179*63a180cbSSean Christopherson 18062f5db4bSSean Christopherson return nested_apic_version1 == lvr && nested_apic_version2 == lvr; 18162f5db4bSSean Christopherson } 18262f5db4bSSean Christopherson 18362f5db4bSSean Christopherson static void npt_rw_l1mmio_prepare(struct svm_test *test) 18462f5db4bSSean Christopherson { 18562f5db4bSSean Christopherson 18662f5db4bSSean Christopherson u64 *pte; 18762f5db4bSSean Christopherson 188*63a180cbSSean Christopherson npt_apic_prepare(); 189*63a180cbSSean Christopherson 19062f5db4bSSean Christopherson pte = npt_get_pte(0xfee00080); 19162f5db4bSSean Christopherson 19262f5db4bSSean Christopherson *pte &= ~(1ULL << 1); 19362f5db4bSSean Christopherson } 19462f5db4bSSean Christopherson 19562f5db4bSSean Christopherson static void npt_rw_l1mmio_test(struct svm_test *test) 19662f5db4bSSean Christopherson { 19762f5db4bSSean Christopherson volatile u32 *data = (volatile void *)(0xfee00080); 19862f5db4bSSean Christopherson 19962f5db4bSSean Christopherson *data = *data; 20062f5db4bSSean Christopherson } 20162f5db4bSSean Christopherson 20262f5db4bSSean Christopherson static bool npt_rw_l1mmio_check(struct svm_test *test) 20362f5db4bSSean Christopherson { 20462f5db4bSSean Christopherson u64 *pte = npt_get_pte(0xfee00080); 20562f5db4bSSean Christopherson 20662f5db4bSSean Christopherson *pte |= (1ULL << 1); 20762f5db4bSSean Christopherson 208*63a180cbSSean Christopherson npt_apic_restore(); 209*63a180cbSSean Christopherson 21062f5db4bSSean Christopherson return (vmcb->control.exit_code == SVM_EXIT_NPF) 21162f5db4bSSean Christopherson && (vmcb->control.exit_info_1 == 0x100000007ULL); 21262f5db4bSSean Christopherson } 21362f5db4bSSean Christopherson 21462f5db4bSSean Christopherson static void basic_guest_main(struct svm_test *test) 21562f5db4bSSean Christopherson { 21662f5db4bSSean Christopherson } 21762f5db4bSSean Christopherson 21862f5db4bSSean Christopherson static void __svm_npt_rsvd_bits_test(u64 * pxe, u64 rsvd_bits, u64 efer, 21962f5db4bSSean Christopherson ulong cr4, u64 guest_efer, ulong guest_cr4) 22062f5db4bSSean Christopherson { 22162f5db4bSSean Christopherson u64 pxe_orig = *pxe; 22262f5db4bSSean Christopherson int exit_reason; 22362f5db4bSSean Christopherson u64 pfec; 22462f5db4bSSean Christopherson 22562f5db4bSSean Christopherson wrmsr(MSR_EFER, efer); 22662f5db4bSSean Christopherson write_cr4(cr4); 22762f5db4bSSean Christopherson 22862f5db4bSSean Christopherson vmcb->save.efer = guest_efer; 22962f5db4bSSean Christopherson vmcb->save.cr4 = guest_cr4; 23062f5db4bSSean Christopherson 23162f5db4bSSean Christopherson *pxe |= rsvd_bits; 23262f5db4bSSean Christopherson 23362f5db4bSSean Christopherson exit_reason = svm_vmrun(); 23462f5db4bSSean Christopherson 23562f5db4bSSean Christopherson report(exit_reason == SVM_EXIT_NPF, 23662f5db4bSSean Christopherson "Wanted #NPF on rsvd bits = 0x%lx, got exit = 0x%x", rsvd_bits, 23762f5db4bSSean Christopherson exit_reason); 23862f5db4bSSean Christopherson 2396f5ce7c1SManali Shukla if (pxe == npt_get_pdpe((u64) basic_guest_main) || pxe == npt_get_pml4e()) { 24062f5db4bSSean Christopherson /* 24162f5db4bSSean Christopherson * The guest's page tables will blow up on a bad PDPE/PML4E, 24262f5db4bSSean Christopherson * before starting the final walk of the guest page. 24362f5db4bSSean Christopherson */ 24462f5db4bSSean Christopherson pfec = 0x20000000full; 24562f5db4bSSean Christopherson } else { 24662f5db4bSSean Christopherson /* RSVD #NPF on final walk of guest page. */ 24762f5db4bSSean Christopherson pfec = 0x10000000dULL; 24862f5db4bSSean Christopherson 24962f5db4bSSean Christopherson /* PFEC.FETCH=1 if NX=1 *or* SMEP=1. */ 25062f5db4bSSean Christopherson if ((cr4 & X86_CR4_SMEP) || (efer & EFER_NX)) 25162f5db4bSSean Christopherson pfec |= 0x10; 25262f5db4bSSean Christopherson 25362f5db4bSSean Christopherson } 25462f5db4bSSean Christopherson 25562f5db4bSSean Christopherson report(vmcb->control.exit_info_1 == pfec, 25662f5db4bSSean Christopherson "Wanted PFEC = 0x%lx, got PFEC = %lx, PxE = 0x%lx. " 25762f5db4bSSean Christopherson "host.NX = %u, host.SMEP = %u, guest.NX = %u, guest.SMEP = %u", 25862f5db4bSSean Christopherson pfec, vmcb->control.exit_info_1, *pxe, 25962f5db4bSSean Christopherson !!(efer & EFER_NX), !!(cr4 & X86_CR4_SMEP), 26062f5db4bSSean Christopherson !!(guest_efer & EFER_NX), !!(guest_cr4 & X86_CR4_SMEP)); 26162f5db4bSSean Christopherson 26262f5db4bSSean Christopherson *pxe = pxe_orig; 26362f5db4bSSean Christopherson } 26462f5db4bSSean Christopherson 26562f5db4bSSean Christopherson static void _svm_npt_rsvd_bits_test(u64 * pxe, u64 pxe_rsvd_bits, u64 efer, 26662f5db4bSSean Christopherson ulong cr4, u64 guest_efer, ulong guest_cr4) 26762f5db4bSSean Christopherson { 26862f5db4bSSean Christopherson u64 rsvd_bits; 26962f5db4bSSean Christopherson int i; 27062f5db4bSSean Christopherson 27162f5db4bSSean Christopherson /* 27262f5db4bSSean Christopherson * RDTSC or RDRAND can sometimes fail to generate a valid reserved bits 27362f5db4bSSean Christopherson */ 27462f5db4bSSean Christopherson if (!pxe_rsvd_bits) { 27562f5db4bSSean Christopherson report_skip 27662f5db4bSSean Christopherson ("svm_npt_rsvd_bits_test: Reserved bits are not valid"); 27762f5db4bSSean Christopherson return; 27862f5db4bSSean Christopherson } 27962f5db4bSSean Christopherson 28062f5db4bSSean Christopherson /* 28162f5db4bSSean Christopherson * Test all combinations of guest/host EFER.NX and CR4.SMEP. If host 28262f5db4bSSean Christopherson * EFER.NX=0, use NX as the reserved bit, otherwise use the passed in 28362f5db4bSSean Christopherson * @pxe_rsvd_bits. 28462f5db4bSSean Christopherson */ 28562f5db4bSSean Christopherson for (i = 0; i < 16; i++) { 28662f5db4bSSean Christopherson if (i & 1) { 28762f5db4bSSean Christopherson rsvd_bits = pxe_rsvd_bits; 28862f5db4bSSean Christopherson efer |= EFER_NX; 28962f5db4bSSean Christopherson } else { 29062f5db4bSSean Christopherson rsvd_bits = PT64_NX_MASK; 29162f5db4bSSean Christopherson efer &= ~EFER_NX; 29262f5db4bSSean Christopherson } 29362f5db4bSSean Christopherson if (i & 2) 29462f5db4bSSean Christopherson cr4 |= X86_CR4_SMEP; 29562f5db4bSSean Christopherson else 29662f5db4bSSean Christopherson cr4 &= ~X86_CR4_SMEP; 29762f5db4bSSean Christopherson if (i & 4) 29862f5db4bSSean Christopherson guest_efer |= EFER_NX; 29962f5db4bSSean Christopherson else 30062f5db4bSSean Christopherson guest_efer &= ~EFER_NX; 30162f5db4bSSean Christopherson if (i & 8) 30262f5db4bSSean Christopherson guest_cr4 |= X86_CR4_SMEP; 30362f5db4bSSean Christopherson else 30462f5db4bSSean Christopherson guest_cr4 &= ~X86_CR4_SMEP; 30562f5db4bSSean Christopherson 30662f5db4bSSean Christopherson __svm_npt_rsvd_bits_test(pxe, rsvd_bits, efer, cr4, 30762f5db4bSSean Christopherson guest_efer, guest_cr4); 30862f5db4bSSean Christopherson } 30962f5db4bSSean Christopherson } 31062f5db4bSSean Christopherson 31162f5db4bSSean Christopherson static u64 get_random_bits(u64 hi, u64 low) 31262f5db4bSSean Christopherson { 31362f5db4bSSean Christopherson unsigned retry = 5; 31462f5db4bSSean Christopherson u64 rsvd_bits = 0; 31562f5db4bSSean Christopherson 31662f5db4bSSean Christopherson if (this_cpu_has(X86_FEATURE_RDRAND)) { 31762f5db4bSSean Christopherson do { 31862f5db4bSSean Christopherson rsvd_bits = (rdrand() << low) & GENMASK_ULL(hi, low); 31962f5db4bSSean Christopherson retry--; 32062f5db4bSSean Christopherson } while (!rsvd_bits && retry); 32162f5db4bSSean Christopherson } 32262f5db4bSSean Christopherson 32362f5db4bSSean Christopherson if (!rsvd_bits) { 32462f5db4bSSean Christopherson retry = 5; 32562f5db4bSSean Christopherson do { 32662f5db4bSSean Christopherson rsvd_bits = (rdtsc() << low) & GENMASK_ULL(hi, low); 32762f5db4bSSean Christopherson retry--; 32862f5db4bSSean Christopherson } while (!rsvd_bits && retry); 32962f5db4bSSean Christopherson } 33062f5db4bSSean Christopherson 33162f5db4bSSean Christopherson return rsvd_bits; 33262f5db4bSSean Christopherson } 33362f5db4bSSean Christopherson 33462f5db4bSSean Christopherson static void svm_npt_rsvd_bits_test(void) 33562f5db4bSSean Christopherson { 33662f5db4bSSean Christopherson u64 saved_efer, host_efer, sg_efer, guest_efer; 33762f5db4bSSean Christopherson ulong saved_cr4, host_cr4, sg_cr4, guest_cr4; 33862f5db4bSSean Christopherson 33962f5db4bSSean Christopherson if (!npt_supported()) { 34062f5db4bSSean Christopherson report_skip("NPT not supported"); 34162f5db4bSSean Christopherson return; 34262f5db4bSSean Christopherson } 34362f5db4bSSean Christopherson 34462f5db4bSSean Christopherson saved_efer = host_efer = rdmsr(MSR_EFER); 34562f5db4bSSean Christopherson saved_cr4 = host_cr4 = read_cr4(); 34662f5db4bSSean Christopherson sg_efer = guest_efer = vmcb->save.efer; 34762f5db4bSSean Christopherson sg_cr4 = guest_cr4 = vmcb->save.cr4; 34862f5db4bSSean Christopherson 34962f5db4bSSean Christopherson test_set_guest(basic_guest_main); 35062f5db4bSSean Christopherson 35162f5db4bSSean Christopherson /* 35262f5db4bSSean Christopherson * 4k PTEs don't have reserved bits if MAXPHYADDR >= 52, just skip the 35362f5db4bSSean Christopherson * sub-test. The NX test is still valid, but the extra bit of coverage 35462f5db4bSSean Christopherson * isn't worth the extra complexity. 35562f5db4bSSean Christopherson */ 35662f5db4bSSean Christopherson if (cpuid_maxphyaddr() >= 52) 35762f5db4bSSean Christopherson goto skip_pte_test; 35862f5db4bSSean Christopherson 35962f5db4bSSean Christopherson _svm_npt_rsvd_bits_test(npt_get_pte((u64) basic_guest_main), 36062f5db4bSSean Christopherson get_random_bits(51, cpuid_maxphyaddr()), 36162f5db4bSSean Christopherson host_efer, host_cr4, guest_efer, guest_cr4); 36262f5db4bSSean Christopherson 36362f5db4bSSean Christopherson skip_pte_test: 36462f5db4bSSean Christopherson _svm_npt_rsvd_bits_test(npt_get_pde((u64) basic_guest_main), 36562f5db4bSSean Christopherson get_random_bits(20, 13) | PT_PAGE_SIZE_MASK, 36662f5db4bSSean Christopherson host_efer, host_cr4, guest_efer, guest_cr4); 36762f5db4bSSean Christopherson 3686f5ce7c1SManali Shukla _svm_npt_rsvd_bits_test(npt_get_pdpe((u64) basic_guest_main), 36962f5db4bSSean Christopherson PT_PAGE_SIZE_MASK | 37062f5db4bSSean Christopherson (this_cpu_has(X86_FEATURE_GBPAGES) ? 37162f5db4bSSean Christopherson get_random_bits(29, 13) : 0), host_efer, 37262f5db4bSSean Christopherson host_cr4, guest_efer, guest_cr4); 37362f5db4bSSean Christopherson 37462f5db4bSSean Christopherson _svm_npt_rsvd_bits_test(npt_get_pml4e(), BIT_ULL(8), 37562f5db4bSSean Christopherson host_efer, host_cr4, guest_efer, guest_cr4); 37662f5db4bSSean Christopherson 37762f5db4bSSean Christopherson wrmsr(MSR_EFER, saved_efer); 37862f5db4bSSean Christopherson write_cr4(saved_cr4); 37962f5db4bSSean Christopherson vmcb->save.efer = sg_efer; 38062f5db4bSSean Christopherson vmcb->save.cr4 = sg_cr4; 38162f5db4bSSean Christopherson } 38262f5db4bSSean Christopherson 383cf75a19cSSean Christopherson #define NPT_V1_TEST(name, prepare, guest_code, check) \ 384cf75a19cSSean Christopherson { #name, npt_supported, prepare, default_prepare_gif_clear, guest_code, \ 385cf75a19cSSean Christopherson default_finished, check } 386cf75a19cSSean Christopherson 387cf75a19cSSean Christopherson #define NPT_V2_TEST(name) { #name, .v2 = name } 38862f5db4bSSean Christopherson 38962f5db4bSSean Christopherson static struct svm_test npt_tests[] = { 390cf75a19cSSean Christopherson NPT_V1_TEST(npt_nx, npt_nx_prepare, null_test, npt_nx_check), 391cf75a19cSSean Christopherson NPT_V1_TEST(npt_np, npt_np_prepare, npt_np_test, npt_np_check), 392cf75a19cSSean Christopherson NPT_V1_TEST(npt_us, npt_us_prepare, npt_us_test, npt_us_check), 393cf75a19cSSean Christopherson NPT_V1_TEST(npt_rw, npt_rw_prepare, npt_rw_test, npt_rw_check), 394cf75a19cSSean Christopherson NPT_V1_TEST(npt_rw_pfwalk, npt_rw_pfwalk_prepare, null_test, npt_rw_pfwalk_check), 395cf75a19cSSean Christopherson NPT_V1_TEST(npt_l1mmio, npt_l1mmio_prepare, npt_l1mmio_test, npt_l1mmio_check), 396cf75a19cSSean Christopherson NPT_V1_TEST(npt_rw_l1mmio, npt_rw_l1mmio_prepare, npt_rw_l1mmio_test, npt_rw_l1mmio_check), 397cf75a19cSSean Christopherson NPT_V2_TEST(svm_npt_rsvd_bits_test), 39862f5db4bSSean Christopherson { NULL, NULL, NULL, NULL, NULL, NULL, NULL } 39962f5db4bSSean Christopherson }; 40062f5db4bSSean Christopherson 40162f5db4bSSean Christopherson int main(int ac, char **av) 40262f5db4bSSean Christopherson { 40362f5db4bSSean Christopherson pteval_t opt_mask = 0; 40462f5db4bSSean Christopherson 40562f5db4bSSean Christopherson __setup_vm(&opt_mask); 40662f5db4bSSean Christopherson return run_svm_tests(ac, av, npt_tests); 40762f5db4bSSean Christopherson } 408