summaryrefslogtreecommitdiffstats
path: root/arch/arm64/kernel/head.S
diff options
context:
space:
mode:
authorMarc Zyngier <maz@kernel.org>2023-06-14 17:51:29 +0200
committerOliver Upton <oliver.upton@linux.dev>2023-06-15 11:27:51 +0200
commit1700f89cb99aae19e4f8ec38b1b59f3b7ae71b91 (patch)
tree7a6f04c6ee0b24f9b2d01197c9049866d3666ec4 /arch/arm64/kernel/head.S
parentarm64: Allow arm64_sw.hvhe on command line (diff)
downloadlinux-1700f89cb99aae19e4f8ec38b1b59f3b7ae71b91.tar.xz
linux-1700f89cb99aae19e4f8ec38b1b59f3b7ae71b91.zip
KVM: arm64: Fix hVHE init on CPUs where HCR_EL2.E2H is not RES1
On CPUs where E2H is RES1, we very quickly set the scene for running EL2 with a VHE configuration, as we do not have any other choice. However, CPUs that conform to the current writing of the architecture start with E2H=0, and only later upgrade with E2H=1. This is all good, but nothing there is actually reconfiguring EL2 to be able to correctly run the kernel at EL1. Huhuh... The "obvious" solution is not to just reinitialise the timer controls like we do, but to really intitialise *everything* unconditionally. This requires a bit of surgery, and is a good opportunity to remove the macro that messes with SPSR_EL2 in init_el2_state. With that, hVHE now works correctly on my trusted A55 machine! Reported-by: Oliver Upton <oliver.upton@linux.dev> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20230614155129.2697388-1-maz@kernel.org Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
Diffstat (limited to 'arch/arm64/kernel/head.S')
-rw-r--r--arch/arm64/kernel/head.S2
1 files changed, 2 insertions, 0 deletions
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index e92caebff46a..23955050da73 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -603,6 +603,8 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL)
msr sctlr_el1, x1
mov x2, xzr
2:
+ __init_el2_nvhe_prepare_eret
+
mov w0, #BOOT_CPU_MODE_EL2
orr x0, x0, x2
eret