From: Alex Bennée Date: Thu, 28 Apr 2022 10:34:10 +0000 (+0100) Subject: xen/arm: p2m don't fall over on FEAT_LPA enabled hw X-Git-Tag: archive/raspbian/4.16.2-1+rpi1^2~34^2~16 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=fe02a5342d3ef372ac8eea12dcdbdf3ff7c47379;p=xen.git xen/arm: p2m don't fall over on FEAT_LPA enabled hw When we introduced FEAT_LPA to QEMU's -cpu max we discovered older kernels had a bug where the physical address was copied directly from ID_AA64MMFR0_EL1.PARange field. The early cpu_init code of Xen commits the same error by blindly copying across the max supported range. Unsurprisingly when the page tables aren't set up for these greater ranges hilarity ensues and the hypervisor crashes fairly early on in the boot-up sequence. This happens when we write to the control register in enable_mmu(). Attempt to fix this the same way as the Linux kernel does by gating PARange to the maximum the hypervisor can handle. I also had to fix up code in p2m which panics when it sees an "invalid" entry in PARange. Signed-off-by: Alex Bennée Cc: Richard Henderson Cc: Stefano Stabellini Cc: Julien Grall Cc: Volodymyr Babchuk Cc: Bertrand Marquis Tested-by: Luca Fancellu Acked-by: Julien Grall (cherry picked from commit 407b13a71e324aba76b11e5f66f59ce4a304a088) --- diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S index aa1f88c764..057dd5d925 100644 --- a/xen/arch/arm/arm64/head.S +++ b/xen/arch/arm/arm64/head.S @@ -473,6 +473,12 @@ cpu_init: ldr x0, =(TCR_RES1|TCR_SH0_IS|TCR_ORGN0_WBWA|TCR_IRGN0_WBWA|TCR_T0SZ(64-48)) /* ID_AA64MMFR0_EL1[3:0] (PARange) corresponds to TCR_EL2[18:16] (PS) */ mrs x1, ID_AA64MMFR0_EL1 + /* Limit to 48 bits, 256TB PA range (#5) */ + ubfm x1, x1, #0, #3 + mov x2, #5 + cmp x1, x2 + csel x1, x1, x2, lt + bfi x0, x1, #16, #3 msr tcr_el2, x0 diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c index fb71fa4c1c..3349b464a3 100644 --- a/xen/arch/arm/p2m.c +++ b/xen/arch/arm/p2m.c @@ -32,10 +32,10 @@ static unsigned int __read_mostly max_vmid = MAX_VMID_8_BIT; #define P2M_ROOT_PAGES (1<= ARRAY_SIZE(pa_range_info) || !pa_range_info[pa_range].pabits ) panic("Unknown encoding of ID_AA64MMFR0_EL1.PARange %x\n", pa_range);