Commit 1700f89c authored by Marc Zyngier's avatar Marc Zyngier Committed by Oliver Upton
Browse files

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: default avatarOliver Upton <oliver.upton@linux.dev>
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20230614155129.2697388-1-maz@kernel.org


Signed-off-by: default avatarOliver Upton <oliver.upton@linux.dev>
parent ad744e8c
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -205,7 +205,6 @@
	__init_el2_nvhe_idregs
	__init_el2_cptr
	__init_el2_fgt
	__init_el2_nvhe_prepare_eret
.endm

#ifndef __KVM_NVHE_HYPERVISOR__
+2 −0
Original line number Diff line number Diff line
@@ -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
+12 −7
Original line number Diff line number Diff line
@@ -83,9 +83,6 @@ SYM_CODE_END(__kvm_hyp_init)
 * x0: struct kvm_nvhe_init_params PA
 */
SYM_CODE_START_LOCAL(___kvm_hyp_init)
	ldr	x1, [x0, #NVHE_INIT_TPIDR_EL2]
	msr	tpidr_el2, x1

	ldr	x1, [x0, #NVHE_INIT_STACK_HYP_VA]
	mov	sp, x1

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

	mrs	x1, cnthctl_el2
	and	x1, x1, #~(BIT(0) | BIT(1))
	orr	x1, x1, #(BIT(10) | BIT(11))
	msr	cnthctl_el2, x1
	// hVHE: Replay the EL2 setup to account for the E2H bit
	// TPIDR_EL2 is used to preserve x0 across the macro maze...
	isb
	msr	tpidr_el2, x0
	init_el2_state
	finalise_el2_state
	mrs	x0, tpidr_el2

1:
	ldr	x1, [x0, #NVHE_INIT_TPIDR_EL2]
	msr	tpidr_el2, x1

	ldr	x1, [x0, #NVHE_INIT_VTTBR]
	msr	vttbr_el2, x1

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

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