Commit 1cdad678 authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

Merge tag 'kvmarm-fixes-6.14-4' of...

Merge tag 'kvmarm-fixes-6.14-4' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD

KVM/arm64 fixes for 6.14, take #4

- Fix a couple of bugs affecting pKVM's PSCI relay implementation
  when running in the hVHE mode, resulting in the host being entered
  with the MMU in an unknown state, and EL2 being in the wrong mode.
parents 916b7f42 3855a7b9
Loading
Loading
Loading
Loading
+26 −5
Original line number Diff line number Diff line
@@ -16,6 +16,32 @@
#include <asm/sysreg.h>
#include <linux/irqchip/arm-gic-v3.h>

.macro init_el2_hcr	val
	mov_q	x0, \val

	/*
	 * Compliant CPUs advertise their VHE-onlyness with
	 * ID_AA64MMFR4_EL1.E2H0 < 0. On such CPUs HCR_EL2.E2H is RES1, but it
	 * can reset into an UNKNOWN state and might not read as 1 until it has
	 * been initialized explicitly.
	 *
	 * Fruity CPUs seem to have HCR_EL2.E2H set to RAO/WI, but
	 * don't advertise it (they predate this relaxation).
	 *
	 * Initalize HCR_EL2.E2H so that later code can rely upon HCR_EL2.E2H
	 * indicating whether the CPU is running in E2H mode.
	 */
	mrs_s	x1, SYS_ID_AA64MMFR4_EL1
	sbfx	x1, x1, #ID_AA64MMFR4_EL1_E2H0_SHIFT, #ID_AA64MMFR4_EL1_E2H0_WIDTH
	cmp	x1, #0
	b.ge	.LnVHE_\@

	orr	x0, x0, #HCR_E2H
.LnVHE_\@:
	msr	hcr_el2, x0
	isb
.endm

.macro __init_el2_sctlr
	mov_q	x0, INIT_SCTLR_EL2_MMU_OFF
	msr	sctlr_el2, x0
@@ -244,11 +270,6 @@
.Lskip_gcs_\@:
.endm

.macro __init_el2_nvhe_prepare_eret
	mov	x0, #INIT_PSTATE_EL1
	msr	spsr_el2, x0
.endm

.macro __init_el2_mpam
	/* Memory Partitioning And Monitoring: disable EL2 traps */
	mrs	x1, id_aa64pfr0_el1
+3 −19
Original line number Diff line number Diff line
@@ -298,25 +298,8 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL)
	msr	sctlr_el2, x0
	isb
0:
	mov_q	x0, HCR_HOST_NVHE_FLAGS

	/*
	 * Compliant CPUs advertise their VHE-onlyness with
	 * ID_AA64MMFR4_EL1.E2H0 < 0. HCR_EL2.E2H can be
	 * RES1 in that case. Publish the E2H bit early so that
	 * it can be picked up by the init_el2_state macro.
	 *
	 * Fruity CPUs seem to have HCR_EL2.E2H set to RAO/WI, but
	 * don't advertise it (they predate this relaxation).
	 */
	mrs_s	x1, SYS_ID_AA64MMFR4_EL1
	tbz	x1, #(ID_AA64MMFR4_EL1_E2H0_SHIFT + ID_AA64MMFR4_EL1_E2H0_WIDTH - 1), 1f

	orr	x0, x0, #HCR_E2H
1:
	msr	hcr_el2, x0
	isb

	init_el2_hcr	HCR_HOST_NVHE_FLAGS
	init_el2_state

	/* Hypervisor stub */
@@ -339,7 +322,8 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL)
	msr	sctlr_el1, x1
	mov	x2, xzr
3:
	__init_el2_nvhe_prepare_eret
	mov	x0, #INIT_PSTATE_EL1
	msr	spsr_el2, x0

	mov	w0, #BOOT_CPU_MODE_EL2
	orr	x0, x0, x2
+7 −3
Original line number Diff line number Diff line
@@ -73,8 +73,12 @@ __do_hyp_init:
	eret
SYM_CODE_END(__kvm_hyp_init)

/*
 * Initialize EL2 CPU state to sane values.
 *
 * HCR_EL2.E2H must have been initialized already.
 */
SYM_CODE_START_LOCAL(__kvm_init_el2_state)
	/* Initialize EL2 CPU state to sane values. */
	init_el2_state				// Clobbers x0..x2
	finalise_el2_state
	ret
@@ -206,9 +210,9 @@ SYM_CODE_START_LOCAL(__kvm_hyp_init_cpu)

2:	msr	SPsel, #1			// We want to use SP_EL{1,2}

	bl	__kvm_init_el2_state
	init_el2_hcr	0

	__init_el2_nvhe_prepare_eret
	bl	__kvm_init_el2_state

	/* Enable MMU, set vectors and stack. */
	mov	x0, x28
+3 −0
Original line number Diff line number Diff line
@@ -218,6 +218,9 @@ asmlinkage void __noreturn __kvm_host_psci_cpu_entry(bool is_cpu_on)
	if (is_cpu_on)
		release_boot_args(boot_args);

	write_sysreg_el1(INIT_SCTLR_EL1_MMU_OFF, SYS_SCTLR);
	write_sysreg(INIT_PSTATE_EL1, SPSR_EL2);

	__host_enter(host_ctxt);
}