Instead of hardcoding the root check against vm->pgd, pass the root_gpa into virt_get_pte(). There's a subtle change here, instead of checking that the parent pointer has the address of vm->pgd, check if the value pointed at by the parent pointer is the root_gpa. No change in behavior expected, but this will be required for following changes that generalize __virt_pg_map() to other MMUs. Signed-off-by: Yosry Ahmed --- tools/testing/selftests/kvm/lib/x86/processor.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testing/selftests/kvm/lib/x86/processor.c index 8a838f208abe4..92a2b5aefd880 100644 --- a/tools/testing/selftests/kvm/lib/x86/processor.c +++ b/tools/testing/selftests/kvm/lib/x86/processor.c @@ -179,15 +179,15 @@ const struct pte_masks x86_pte_masks = { .nx = BIT_ULL(63), }; -static void *virt_get_pte(struct kvm_vm *vm, uint64_t *parent_pte, - uint64_t vaddr, int level, +static void *virt_get_pte(struct kvm_vm *vm, vm_paddr_t root_gpa, + uint64_t *parent_pte, uint64_t vaddr, int level, const struct pte_masks *masks) { uint64_t pt_gpa = PTE_GET_PA(*parent_pte); uint64_t *page_table = addr_gpa2hva(vm, pt_gpa); int index = (vaddr >> PG_LEVEL_SHIFT(level)) & 0x1ffu; - TEST_ASSERT((*parent_pte & masks->present) || parent_pte == &vm->pgd, + TEST_ASSERT((*parent_pte == root_gpa) || (*parent_pte & masks->present), "Parent PTE (level %d) not PRESENT for gva: 0x%08lx", level + 1, vaddr); @@ -195,6 +195,7 @@ static void *virt_get_pte(struct kvm_vm *vm, uint64_t *parent_pte, } static uint64_t *virt_create_upper_pte(struct kvm_vm *vm, + vm_paddr_t root_gpa, uint64_t *parent_pte, uint64_t vaddr, uint64_t paddr, @@ -202,7 +203,8 @@ static uint64_t *virt_create_upper_pte(struct kvm_vm *vm, int target_level, const struct pte_masks *masks) { - uint64_t *pte = virt_get_pte(vm, parent_pte, vaddr, current_level, masks); + uint64_t *pte = virt_get_pte(vm, root_gpa, parent_pte, + vaddr, current_level, masks); paddr = vm_untag_gpa(vm, paddr); @@ -259,13 +261,14 @@ void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, * early if a hugepage was created. */ for (current_level = vm->pgtable_levels; current_level > PG_LEVEL_4K; current_level--) { - pte = virt_create_upper_pte(vm, pte, vaddr, paddr, current_level, level, masks); + pte = virt_create_upper_pte(vm, vm->pgd, pte, vaddr, paddr, + current_level, level, masks); if (*pte & masks->large) return; } /* Fill in page table entry. */ - pte = virt_get_pte(vm, pte, vaddr, PG_LEVEL_4K, masks); + pte = virt_get_pte(vm, vm->pgd, pte, vaddr, PG_LEVEL_4K, masks); TEST_ASSERT(!(*pte & masks->present), "PTE already present for 4k page at vaddr: 0x%lx", vaddr); *pte = masks->present | masks->writeable | (paddr & PHYSICAL_PAGE_MASK); @@ -348,7 +351,7 @@ static uint64_t *__vm_get_page_table_entry(struct kvm_vm *vm, "Canonical check failed. The virtual address is invalid."); for (current_level = vm->pgtable_levels; current_level >= PG_LEVEL_4K; current_level--) { - pte = virt_get_pte(vm, pte, vaddr, current_level, masks); + pte = virt_get_pte(vm, vm->pgd, pte, vaddr, current_level, masks); if (vm_is_target_pte(pte, level, current_level, masks)) return pte; } -- 2.51.0.869.ge66316f041-goog