KVM: selftests: arm64: Fix ttbr0_el1 encoding for PA bits > 48
authorRyan Roberts <ryan.roberts@arm.com>
Wed, 8 Mar 2023 11:09:48 +0000 (11:09 +0000)
committerMarc Zyngier <maz@kernel.org>
Thu, 30 Mar 2023 18:27:56 +0000 (19:27 +0100)
Bits [51:48] of the pgd address are stored at bits [5:2] of ttbr0_el1.
page_table_test stores its page tables at the far end of IPA space so
was tripping over this when run on a system that supports FEAT_LPA (or
FEAT_LPA2).

Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
Reviewed-by: Oliver Upton <oliver.upton@linux.dev>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20230308110948.1820163-4-ryan.roberts@arm.com
tools/testing/selftests/kvm/lib/aarch64/processor.c

index c413085d58b73421bccd454c643b3d0df3758387..233357d2f1ccf4bec9e9deb7d4462b7551e21b1f 100644 (file)
@@ -242,7 +242,7 @@ void aarch64_vcpu_setup(struct kvm_vcpu *vcpu, struct kvm_vcpu_init *init)
 {
        struct kvm_vcpu_init default_init = { .target = -1, };
        struct kvm_vm *vm = vcpu->vm;
-       uint64_t sctlr_el1, tcr_el1;
+       uint64_t sctlr_el1, tcr_el1, ttbr0_el1;
 
        if (!init)
                init = &default_init;
@@ -293,10 +293,13 @@ void aarch64_vcpu_setup(struct kvm_vcpu *vcpu, struct kvm_vcpu_init *init)
                TEST_FAIL("Unknown guest mode, mode: 0x%x", vm->mode);
        }
 
+       ttbr0_el1 = vm->pgd & GENMASK(47, vm->page_shift);
+
        /* Configure output size */
        switch (vm->mode) {
        case VM_MODE_P52V48_64K:
                tcr_el1 |= 6ul << 32; /* IPS = 52 bits */
+               ttbr0_el1 |= FIELD_GET(GENMASK(51, 48), vm->pgd) << 2;
                break;
        case VM_MODE_P48V48_4K:
        case VM_MODE_P48V48_16K:
@@ -326,7 +329,7 @@ void aarch64_vcpu_setup(struct kvm_vcpu *vcpu, struct kvm_vcpu_init *init)
        vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_SCTLR_EL1), sctlr_el1);
        vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_TCR_EL1), tcr_el1);
        vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_MAIR_EL1), DEFAULT_MAIR_EL1);
-       vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_TTBR0_EL1), vm->pgd);
+       vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_TTBR0_EL1), ttbr0_el1);
        vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_TPIDR_EL1), vcpu->id);
 }