Map the test's huge page region with 2MiB virtual mappings so that KVM can shadow the region with huge pages. This fixes nx_huge_pages_test on hosts where TDP hardware support is disabled. Purposely do not skip this test on TDP-disabled hosts. While we don't care about NX Huge Pages on TDP-disabled hosts from a security perspective, KVM does support it, and so we should test it. Signed-off-by: David Matlack <dmatlack@xxxxxxxxxx> --- .../selftests/kvm/include/x86_64/processor.h | 2 ++ tools/testing/selftests/kvm/lib/x86_64/processor.c | 13 +++++++++++++ .../selftests/kvm/x86_64/nx_huge_pages_test.c | 9 +++++++-- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/kvm/include/x86_64/processor.h b/tools/testing/selftests/kvm/include/x86_64/processor.h index 0cbc71b7af50..4ffaa79fd8d6 100644 --- a/tools/testing/selftests/kvm/include/x86_64/processor.h +++ b/tools/testing/selftests/kvm/include/x86_64/processor.h @@ -855,6 +855,8 @@ enum pg_level { #define PG_SIZE_1G PG_LEVEL_SIZE(PG_LEVEL_1G) void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, int level); +void virt_map_2m(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, + uint64_t nr_2m_pages); /* * Basic CPU control in CR0 diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c index 2e6e61bbe81b..df8a1498ea28 100644 --- a/tools/testing/selftests/kvm/lib/x86_64/processor.c +++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c @@ -214,6 +214,19 @@ void virt_arch_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr) __virt_pg_map(vm, vaddr, paddr, PG_LEVEL_4K); } +void virt_map_2m(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, + uint64_t nr_2m_pages) +{ + int i; + + for (i = 0; i < nr_2m_pages; i++) { + __virt_pg_map(vm, vaddr, paddr, PG_LEVEL_2M); + + vaddr += PG_SIZE_2M; + paddr += PG_SIZE_2M; + } +} + static uint64_t *_vm_get_page_table_entry(struct kvm_vm *vm, struct kvm_vcpu *vcpu, uint64_t vaddr) diff --git a/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.c b/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.c index cc6421716400..a850769692b7 100644 --- a/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.c +++ b/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.c @@ -22,7 +22,8 @@ #define HPAGE_GPA (4UL << 30) /* 4G prevents collision w/ slot 0 */ #define HPAGE_GVA HPAGE_GPA /* GVA is arbitrary, so use GPA. */ #define PAGES_PER_2MB_HUGE_PAGE 512 -#define HPAGE_SLOT_NPAGES (3 * PAGES_PER_2MB_HUGE_PAGE) +#define HPAGE_SLOT_2MB_PAGES 3 +#define HPAGE_SLOT_NPAGES (HPAGE_SLOT_2MB_PAGES * PAGES_PER_2MB_HUGE_PAGE) /* * Passed by nx_huge_pages_test.sh to provide an easy warning if this test is @@ -141,7 +142,11 @@ void run_test(int reclaim_period_ms, bool disable_nx_huge_pages, HPAGE_GPA, HPAGE_SLOT, HPAGE_SLOT_NPAGES, 0); - virt_map(vm, HPAGE_GVA, HPAGE_GPA, HPAGE_SLOT_NPAGES); + /* + * Use 2MiB virtual mappings so that KVM can map the region with huge + * pages even if TDP is disabled. + */ + virt_map_2m(vm, HPAGE_GVA, HPAGE_GPA, HPAGE_SLOT_2MB_PAGES); hva = addr_gpa2hva(vm, HPAGE_GPA); memset(hva, RETURN_OPCODE, HPAGE_SLOT_NPAGES * PAGE_SIZE); base-commit: 372d07084593dc7a399bf9bee815711b1fb1bcf2 prerequisite-patch-id: 2e3661ba8856c29b769499bac525b6943d9284b8 -- 2.37.3.998.g577e59143f-goog