[PATCH 07/12] KVM: selftests: Pass the root HVA directly to nested mapping functions

Yosry Ahmed
2025-10-01T14:58:53Z

From: Yosry Ahmed <yosryahmed@google.com>

The nested mapping functions used to create EPT mappings currently
accept a struct vmx_pages argument, only to get the EPT root from it
later. In preparation for generalizing these functions to work for NPTs,
pass the EPT root HVA directly instead.

Signed-off-by: Yosry Ahmed <yosry.ahmed@linux.dev>
---
tools/testing/selftests/kvm/include/x86/vmx.h | 8 +++----
.../testing/selftests/kvm/lib/x86/memstress.c | 4 ++--
tools/testing/selftests/kvm/lib/x86/vmx.c | 24 +++++++++----------
.../selftests/kvm/x86/vmx_dirty_log_test.c | 6 ++---
4 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/x86/vmx.h b/tools/testing/selftests/kvm/include/x86/vmx.h
index edb3c391b9824..06ae68cf9635c 100644
--- a/tools/testing/selftests/kvm/include/x86/vmx.h
+++ b/tools/testing/selftests/kvm/include/x86/vmx.h
@@ -559,13 +559,13 @@ bool load_vmcs(struct vmx_pages *vmx);

bool ept_1g_pages_supported(void);

-void nested_pg_map(struct vmx_pages *vmx, struct kvm_vm *vm,
+void nested_pg_map(void *root_hva, struct kvm_vm *vm,
uint64_t nested_paddr, uint64_t paddr);
-void nested_map(struct vmx_pages *vmx, struct kvm_vm *vm,
+void nested_map(void *root_hva, struct kvm_vm *vm,
uint64_t nested_paddr, uint64_t paddr, uint64_t size);
-void nested_map_memslot(struct vmx_pages *vmx, struct kvm_vm *vm,
+void nested_map_memslot(void *root_hva, struct kvm_vm *vm,
uint32_t memslot);
-void nested_identity_map_1g(struct vmx_pages *vmx, struct kvm_vm *vm,
+void nested_identity_map_1g(void *root_hva, struct kvm_vm *vm,
uint64_t addr, uint64_t size);
bool kvm_cpu_has_ept(void);
void prepare_eptp(struct vmx_pages *vmx, struct kvm_vm *vm,
diff --git a/tools/testing/selftests/kvm/lib/x86/memstress.c b/tools/testing/selftests/kvm/lib/x86/memstress.c
index 7f5d62a65c68a..7981e295cac70 100644
--- a/tools/testing/selftests/kvm/lib/x86/memstress.c
+++ b/tools/testing/selftests/kvm/lib/x86/memstress.c
@@ -70,11 +70,11 @@ void memstress_setup_ept(struct vmx_pages *vmx, struct kvm_vm *vm)
* KVM can shadow the EPT12 with the maximum huge page size supported
* by the backing source.
*/
- nested_identity_map_1g(vmx, vm, 0, 0x100000000ULL);
+ nested_identity_map_1g(vmx->eptp_hva, vm, 0, 0x100000000ULL);

start = align_down(memstress_args.gpa, PG_SIZE_1G);
end = align_up(memstress_args.gpa + memstress_args.size, PG_SIZE_1G);
- nested_identity_map_1g(vmx, vm, start, end - start);
+ nested_identity_map_1g(vmx->eptp_hva, vm, start, end - start);
}

void memstress_setup_nested(struct kvm_vm *vm, int nr_vcpus, struct kvm_vcpu *vcpus[])
diff --git a/tools/testing/selftests/kvm/lib/x86/vmx.c b/tools/testing/selftests/kvm/lib/x86/vmx.c
index d4d1208dd0238..04c4b97bcd1e7 100644
--- a/tools/testing/selftests/kvm/lib/x86/vmx.c
+++ b/tools/testing/selftests/kvm/lib/x86/vmx.c
@@ -394,11 +394,11 @@ static void nested_create_pte(struct kvm_vm *vm,
}

-void __nested_pg_map(struct vmx_pages *vmx, struct kvm_vm *vm,
+void __nested_pg_map(void *root_hva, struct kvm_vm *vm,
uint64_t nested_paddr, uint64_t paddr, int target_level)
{
const uint64_t page_size = PG_LEVEL_SIZE(target_level);
- struct eptPageTableEntry *pt = vmx->eptp_hva, *pte;
+ struct eptPageTableEntry *pt = root_hva, *pte;
uint16_t index;

TEST_ASSERT(vm->mode == VM_MODE_PXXV48_4K, "Attempt to use "
@@ -445,10 +445,10 @@ void __nested_pg_map(struct vmx_pages *vmx, struct kvm_vm *vm,

}

-void nested_pg_map(struct vmx_pages *vmx, struct kvm_vm *vm,
+void nested_pg_map(void *root_hva, struct kvm_vm *vm,
uint64_t nested_paddr, uint64_t paddr)
{
- __nested_pg_map(vmx, vm, nested_paddr, paddr, PG_LEVEL_4K);
+ __nested_pg_map(root_hva, vm, nested_paddr, paddr, PG_LEVEL_4K);
}

/*
@@ -468,7 +468,7 @@ void nested_pg_map(struct vmx_pages *vmx, struct kvm_vm *vm,
* Within the VM given by vm, creates a nested guest translation for the
* page range starting at nested_paddr to the page range starting at paddr.
*/
-void __nested_map(struct vmx_pages *vmx, struct kvm_vm *vm,
+void __nested_map(void *root_hva, struct kvm_vm *vm,
uint64_t nested_paddr, uint64_t paddr, uint64_t size,
int level)
{
@@ -479,22 +479,22 @@ void __nested_map(struct vmx_pages *vmx, struct kvm_vm *vm,
TEST_ASSERT(paddr + size > paddr, "Paddr overflow");

while (npages--) {
- __nested_pg_map(vmx, vm, nested_paddr, paddr, level);
+ __nested_pg_map(root_hva, vm, nested_paddr, paddr, level);
nested_paddr += page_size;
paddr += page_size;
}
}

-void nested_map(struct vmx_pages *vmx, struct kvm_vm *vm,
+void nested_map(void *root_hva, struct kvm_vm *vm,
uint64_t nested_paddr, uint64_t paddr, uint64_t size)
{
- __nested_map(vmx, vm, nested_paddr, paddr, size, PG_LEVEL_4K);
+ __nested_map(root_hva, vm, nested_paddr, paddr, size, PG_LEVEL_4K);
}

/* Prepare an identity extended page table that maps all the
* physical pages in VM.
*/
-void nested_map_memslot(struct vmx_pages *vmx, struct kvm_vm *vm,
+void nested_map_memslot(void *root_hva, struct kvm_vm *vm,
uint32_t memslot)
{
sparsebit_idx_t i, last;
@@ -508,7 +508,7 @@ void nested_map_memslot(struct vmx_pages *vmx, struct kvm_vm *vm,
if (i > last)
break;

- nested_map(vmx, vm,
+ nested_map(root_hva, vm,
(uint64_t)i << vm->page_shift,
(uint64_t)i << vm->page_shift,
1 << vm->page_shift);
@@ -516,10 +516,10 @@ void nested_map_memslot(struct vmx_pages *vmx, struct kvm_vm *vm,
}

/* Identity map a region with 1GiB Pages. */
-void nested_identity_map_1g(struct vmx_pages *vmx, struct kvm_vm *vm,
+void nested_identity_map_1g(void *root_hva, struct kvm_vm *vm,
uint64_t addr, uint64_t size)
{
- __nested_map(vmx, vm, addr, addr, size, PG_LEVEL_1G);
+ __nested_map(root_hva, vm, addr, addr, size, PG_LEVEL_1G);
}

bool kvm_cpu_has_ept(void)
diff --git a/tools/testing/selftests/kvm/x86/vmx_dirty_log_test.c b/tools/testing/selftests/kvm/x86/vmx_dirty_log_test.c
index fa512d033205f..21a57805e9780 100644
--- a/tools/testing/selftests/kvm/x86/vmx_dirty_log_test.c
+++ b/tools/testing/selftests/kvm/x86/vmx_dirty_log_test.c
@@ -121,9 +121,9 @@ static void test_vmx_dirty_log(bool enable_ept)
*/
if (enable_ept) {
prepare_eptp(vmx, vm, 0);
- nested_map_memslot(vmx, vm, 0);
- nested_map(vmx, vm, NESTED_TEST_MEM1, GUEST_TEST_MEM, 4096);
- nested_map(vmx, vm, NESTED_TEST_MEM2, GUEST_TEST_MEM, 4096);
+ nested_map_memslot(vmx->eptp_hva, vm, 0);
+ nested_map(vmx->eptp_hva, vm, NESTED_TEST_MEM1, GUEST_TEST_MEM, 4096);
+ nested_map(vmx->eptp_hva, vm, NESTED_TEST_MEM2, GUEST_TEST_MEM, 4096);
}

bmap = bitmap_zalloc(TEST_MEM_PAGES);
--
2.51.0.618.g983fd99d29-goog