Skip to content

Commit 1700f89

Browse files
Marc Zyngieroupton
authored andcommitted
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>
1 parent ad744e8 commit 1700f89

3 files changed

Lines changed: 14 additions & 8 deletions

File tree

arch/arm64/include/asm/el2_setup.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,6 @@
205205
__init_el2_nvhe_idregs
206206
__init_el2_cptr
207207
__init_el2_fgt
208-
__init_el2_nvhe_prepare_eret
209208
.endm
210209

211210
#ifndef __KVM_NVHE_HYPERVISOR__

arch/arm64/kernel/head.S

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,8 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL)
603603
msr sctlr_el1, x1
604604
mov x2, xzr
605605
2:
606+
__init_el2_nvhe_prepare_eret
607+
606608
mov w0, #BOOT_CPU_MODE_EL2
607609
orr x0, x0, x2
608610
eret

arch/arm64/kvm/hyp/nvhe/hyp-init.S

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,6 @@ SYM_CODE_END(__kvm_hyp_init)
8383
* x0: struct kvm_nvhe_init_params PA
8484
*/
8585
SYM_CODE_START_LOCAL(___kvm_hyp_init)
86-
ldr x1, [x0, #NVHE_INIT_TPIDR_EL2]
87-
msr tpidr_el2, x1
88-
8986
ldr x1, [x0, #NVHE_INIT_STACK_HYP_VA]
9087
mov sp, x1
9188

@@ -99,11 +96,18 @@ SYM_CODE_START_LOCAL(___kvm_hyp_init)
9996
and x2, x1, x2
10097
cbz x2, 1f
10198

102-
mrs x1, cnthctl_el2
103-
and x1, x1, #~(BIT(0) | BIT(1))
104-
orr x1, x1, #(BIT(10) | BIT(11))
105-
msr cnthctl_el2, x1
99+
// hVHE: Replay the EL2 setup to account for the E2H bit
100+
// TPIDR_EL2 is used to preserve x0 across the macro maze...
101+
isb
102+
msr tpidr_el2, x0
103+
init_el2_state
104+
finalise_el2_state
105+
mrs x0, tpidr_el2
106+
106107
1:
108+
ldr x1, [x0, #NVHE_INIT_TPIDR_EL2]
109+
msr tpidr_el2, x1
110+
107111
ldr x1, [x0, #NVHE_INIT_VTTBR]
108112
msr vttbr_el2, x1
109113

@@ -193,6 +197,7 @@ SYM_CODE_START_LOCAL(__kvm_hyp_init_cpu)
193197
/* Initialize EL2 CPU state to sane values. */
194198
init_el2_state // Clobbers x0..x2
195199
finalise_el2_state
200+
__init_el2_nvhe_prepare_eret
196201

197202
/* Enable MMU, set vectors and stack. */
198203
mov x0, x28

0 commit comments

Comments
 (0)