Skip to content

Commit 1cdad67

Browse files
committed
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.
2 parents 916b7f4 + 3855a7b commit 1cdad67

File tree

4 files changed

+39
-27
lines changed

4 files changed

+39
-27
lines changed

arch/arm64/include/asm/el2_setup.h

+26-5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,32 @@
1616
#include <asm/sysreg.h>
1717
#include <linux/irqchip/arm-gic-v3.h>
1818

19+
.macro init_el2_hcr val
20+
mov_q x0, \val
21+
22+
/*
23+
* Compliant CPUs advertise their VHE-onlyness with
24+
* ID_AA64MMFR4_EL1.E2H0 < 0. On such CPUs HCR_EL2.E2H is RES1, but it
25+
* can reset into an UNKNOWN state and might not read as 1 until it has
26+
* been initialized explicitly.
27+
*
28+
* Fruity CPUs seem to have HCR_EL2.E2H set to RAO/WI, but
29+
* don't advertise it (they predate this relaxation).
30+
*
31+
* Initalize HCR_EL2.E2H so that later code can rely upon HCR_EL2.E2H
32+
* indicating whether the CPU is running in E2H mode.
33+
*/
34+
mrs_s x1, SYS_ID_AA64MMFR4_EL1
35+
sbfx x1, x1, #ID_AA64MMFR4_EL1_E2H0_SHIFT, #ID_AA64MMFR4_EL1_E2H0_WIDTH
36+
cmp x1, #0
37+
b.ge .LnVHE_\@
38+
39+
orr x0, x0, #HCR_E2H
40+
.LnVHE_\@:
41+
msr hcr_el2, x0
42+
isb
43+
.endm
44+
1945
.macro __init_el2_sctlr
2046
mov_q x0, INIT_SCTLR_EL2_MMU_OFF
2147
msr sctlr_el2, x0
@@ -244,11 +270,6 @@
244270
.Lskip_gcs_\@:
245271
.endm
246272

247-
.macro __init_el2_nvhe_prepare_eret
248-
mov x0, #INIT_PSTATE_EL1
249-
msr spsr_el2, x0
250-
.endm
251-
252273
.macro __init_el2_mpam
253274
/* Memory Partitioning And Monitoring: disable EL2 traps */
254275
mrs x1, id_aa64pfr0_el1

arch/arm64/kernel/head.S

+3-19
Original file line numberDiff line numberDiff line change
@@ -298,25 +298,8 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL)
298298
msr sctlr_el2, x0
299299
isb
300300
0:
301-
mov_q x0, HCR_HOST_NVHE_FLAGS
302-
303-
/*
304-
* Compliant CPUs advertise their VHE-onlyness with
305-
* ID_AA64MMFR4_EL1.E2H0 < 0. HCR_EL2.E2H can be
306-
* RES1 in that case. Publish the E2H bit early so that
307-
* it can be picked up by the init_el2_state macro.
308-
*
309-
* Fruity CPUs seem to have HCR_EL2.E2H set to RAO/WI, but
310-
* don't advertise it (they predate this relaxation).
311-
*/
312-
mrs_s x1, SYS_ID_AA64MMFR4_EL1
313-
tbz x1, #(ID_AA64MMFR4_EL1_E2H0_SHIFT + ID_AA64MMFR4_EL1_E2H0_WIDTH - 1), 1f
314-
315-
orr x0, x0, #HCR_E2H
316-
1:
317-
msr hcr_el2, x0
318-
isb
319301

302+
init_el2_hcr HCR_HOST_NVHE_FLAGS
320303
init_el2_state
321304

322305
/* Hypervisor stub */
@@ -339,7 +322,8 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL)
339322
msr sctlr_el1, x1
340323
mov x2, xzr
341324
3:
342-
__init_el2_nvhe_prepare_eret
325+
mov x0, #INIT_PSTATE_EL1
326+
msr spsr_el2, x0
343327

344328
mov w0, #BOOT_CPU_MODE_EL2
345329
orr x0, x0, x2

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

+7-3
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,12 @@ __do_hyp_init:
7373
eret
7474
SYM_CODE_END(__kvm_hyp_init)
7575

76+
/*
77+
* Initialize EL2 CPU state to sane values.
78+
*
79+
* HCR_EL2.E2H must have been initialized already.
80+
*/
7681
SYM_CODE_START_LOCAL(__kvm_init_el2_state)
77-
/* Initialize EL2 CPU state to sane values. */
7882
init_el2_state // Clobbers x0..x2
7983
finalise_el2_state
8084
ret
@@ -206,9 +210,9 @@ SYM_CODE_START_LOCAL(__kvm_hyp_init_cpu)
206210

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

209-
bl __kvm_init_el2_state
213+
init_el2_hcr 0
210214

211-
__init_el2_nvhe_prepare_eret
215+
bl __kvm_init_el2_state
212216

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

arch/arm64/kvm/hyp/nvhe/psci-relay.c

+3
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,9 @@ asmlinkage void __noreturn __kvm_host_psci_cpu_entry(bool is_cpu_on)
218218
if (is_cpu_on)
219219
release_boot_args(boot_args);
220220

221+
write_sysreg_el1(INIT_SCTLR_EL1_MMU_OFF, SYS_SCTLR);
222+
write_sysreg(INIT_PSTATE_EL1, SPSR_EL2);
223+
221224
__host_enter(host_ctxt);
222225
}
223226

0 commit comments

Comments
 (0)