* [PATCH] arm/arm64: KVM: Fix VTTBR_BADDR_MASK and pgd alloc
@ 2014-09-25 18:32 Christoffer Dall
2014-09-26 11:18 ` Catalin Marinas
0 siblings, 1 reply; 2+ messages in thread
From: Christoffer Dall @ 2014-09-25 18:32 UTC (permalink / raw)
To: linux-arm-kernel
From: Joel Schopp <joel.schopp@amd.com>
The current aarch64 calculation for VTTBR_BADDR_MASK masks only 39 bits
and not all the bits in the PA range. This is clearly a bug that
manifests itself on systems that allocate memory in the higher address
space range.
[ Modified from Joel's original patch to be based on PHYS_MASK_SHIFT
instead of a hard-coded value and to move the alignment check of the
allocation to mmu.c. Also added a comment explaining why we hardcode
the IPA range and changed the stage-2 pgd allocation to be based on
the 40 bit IPA range instead of the maximum possible 48 bit PA range.
- Christoffer ]
Signed-off-by: Joel Schopp <joel.schopp@amd.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
arch/arm/kvm/arm.c | 4 ++--
arch/arm64/include/asm/kvm_arm.h | 13 ++++++++++++-
arch/arm64/include/asm/kvm_mmu.h | 5 ++---
3 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 40bc3df..7796051 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -410,9 +410,9 @@ static void update_vttbr(struct kvm *kvm)
/* update vttbr to be used with the new vmid */
pgd_phys = virt_to_phys(kvm->arch.pgd);
+ BUG_ON(pgd_phys & ~VTTBR_BADDR_MASK);
vmid = ((u64)(kvm->arch.vmid) << VTTBR_VMID_SHIFT) & VTTBR_VMID_MASK;
- kvm->arch.vttbr = pgd_phys & VTTBR_BADDR_MASK;
- kvm->arch.vttbr |= vmid;
+ kvm->arch.vttbr = pgd_phys | vmid;
spin_unlock(&kvm_vmid_lock);
}
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index cc83520..7fd3e27 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -122,6 +122,17 @@
#define VTCR_EL2_T0SZ_MASK 0x3f
#define VTCR_EL2_T0SZ_40B 24
+/*
+ * We configure the Stage-2 page tables to always restrict the IPA space to be
+ * 40 bits wide (T0SZ = 24). Systems with a PARange smaller than 40 bits are
+ * not known to exist and will break with this configuration.
+ *
+ * Note that when using 4K pages, we concatenate two first level page tables
+ * together.
+ *
+ * The magic numbers used for VTTBR_X in this patch can be found in Tables
+ * D4-23 and D4-25 in ARM DDI 0487A.b.
+ */
#ifdef CONFIG_ARM64_64K_PAGES
/*
* Stage2 translation configuration:
@@ -149,7 +160,7 @@
#endif
#define VTTBR_BADDR_SHIFT (VTTBR_X - 1)
-#define VTTBR_BADDR_MASK (((1LLU << (40 - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT)
+#define VTTBR_BADDR_MASK (((1LLU << (PHYS_MASK_SHIFT - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT)
#define VTTBR_VMID_SHIFT (48LLU)
#define VTTBR_VMID_MASK (0xffLLU << VTTBR_VMID_SHIFT)
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 737da74..a030d16 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -59,10 +59,9 @@
#define KERN_TO_HYP(kva) ((unsigned long)kva - PAGE_OFFSET + HYP_PAGE_OFFSET)
/*
- * Align KVM with the kernel's view of physical memory. Should be
- * 40bit IPA, with PGD being 8kB aligned in the 4KB page configuration.
+ * We currently only support a 40bit IPA.
*/
-#define KVM_PHYS_SHIFT PHYS_MASK_SHIFT
+#define KVM_PHYS_SHIFT (40)
#define KVM_PHYS_SIZE (1UL << KVM_PHYS_SHIFT)
#define KVM_PHYS_MASK (KVM_PHYS_SIZE - 1UL)
--
2.0.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH] arm/arm64: KVM: Fix VTTBR_BADDR_MASK and pgd alloc
2014-09-25 18:32 [PATCH] arm/arm64: KVM: Fix VTTBR_BADDR_MASK and pgd alloc Christoffer Dall
@ 2014-09-26 11:18 ` Catalin Marinas
0 siblings, 0 replies; 2+ messages in thread
From: Catalin Marinas @ 2014-09-26 11:18 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Sep 25, 2014 at 07:32:19PM +0100, Christoffer Dall wrote:
> From: Joel Schopp <joel.schopp@amd.com>
>
> The current aarch64 calculation for VTTBR_BADDR_MASK masks only 39 bits
> and not all the bits in the PA range. This is clearly a bug that
> manifests itself on systems that allocate memory in the higher address
> space range.
>
> [ Modified from Joel's original patch to be based on PHYS_MASK_SHIFT
> instead of a hard-coded value and to move the alignment check of the
> allocation to mmu.c. Also added a comment explaining why we hardcode
> the IPA range and changed the stage-2 pgd allocation to be based on
> the 40 bit IPA range instead of the maximum possible 48 bit PA range.
> - Christoffer ]
>
> Signed-off-by: Joel Schopp <joel.schopp@amd.com>
> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2014-09-26 11:18 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-09-25 18:32 [PATCH] arm/arm64: KVM: Fix VTTBR_BADDR_MASK and pgd alloc Christoffer Dall
2014-09-26 11:18 ` Catalin Marinas
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).