Skip to content

Commit b332014

Browse files
Marc Zyngieroupton
authored andcommitted
arm64: Fix early handling of FEAT_E2H0 not being implemented
Commit 3944382 introduced checks for the FEAT_E2H0 not being implemented. However, the check is absolutely wrong and makes a point it testing a bit that is guaranteed to be zero. On top of that, the detection happens way too late, after the init_el2_state has done its job. This went undetected because the HW this was tested on has E2H being RAO/WI, and not RES1. However, the bug shows up when run as a nested guest, where HCR_EL2.E2H is not necessarily set to 1. As a result, booting the kernel in hVHE mode fails with timer accesses being cought in a trap loop (which was fun to debug). Fix the check for ID_AA64MMFR4_EL1.E2H0, and set the HCR_EL2.E2H bit early so that it can be checked by the rest of the init sequence. With this, hVHE works again in a NV environment that doesn't have FEAT_E2H0. Fixes: 3944382 ("arm64: Treat HCR_EL2.E2H as RES1 when ID_AA64MMFR4_EL1.E2H0 is negative") Signed-off-by: Marc Zyngier <[email protected]> Acked-by: Catalin Marinas <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Oliver Upton <[email protected]>
1 parent 4c36a15 commit b332014

File tree

1 file changed

+16
-13
lines changed

1 file changed

+16
-13
lines changed

arch/arm64/kernel/head.S

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,21 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL)
291291
blr x2
292292
0:
293293
mov_q x0, HCR_HOST_NVHE_FLAGS
294+
295+
/*
296+
* Compliant CPUs advertise their VHE-onlyness with
297+
* ID_AA64MMFR4_EL1.E2H0 < 0. HCR_EL2.E2H can be
298+
* RES1 in that case. Publish the E2H bit early so that
299+
* it can be picked up by the init_el2_state macro.
300+
*
301+
* Fruity CPUs seem to have HCR_EL2.E2H set to RAO/WI, but
302+
* don't advertise it (they predate this relaxation).
303+
*/
304+
mrs_s x1, SYS_ID_AA64MMFR4_EL1
305+
tbz x1, #(ID_AA64MMFR4_EL1_E2H0_SHIFT + ID_AA64MMFR4_EL1_E2H0_WIDTH - 1), 1f
306+
307+
orr x0, x0, #HCR_E2H
308+
1:
294309
msr hcr_el2, x0
295310
isb
296311

@@ -303,22 +318,10 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL)
303318

304319
mov_q x1, INIT_SCTLR_EL1_MMU_OFF
305320

306-
/*
307-
* Compliant CPUs advertise their VHE-onlyness with
308-
* ID_AA64MMFR4_EL1.E2H0 < 0. HCR_EL2.E2H can be
309-
* RES1 in that case.
310-
*
311-
* Fruity CPUs seem to have HCR_EL2.E2H set to RES1, but
312-
* don't advertise it (they predate this relaxation).
313-
*/
314-
mrs_s x0, SYS_ID_AA64MMFR4_EL1
315-
ubfx x0, x0, #ID_AA64MMFR4_EL1_E2H0_SHIFT, #ID_AA64MMFR4_EL1_E2H0_WIDTH
316-
tbnz x0, #(ID_AA64MMFR4_EL1_E2H0_SHIFT + ID_AA64MMFR4_EL1_E2H0_WIDTH - 1), 1f
317-
318321
mrs x0, hcr_el2
319322
and x0, x0, #HCR_E2H
320323
cbz x0, 2f
321-
1:
324+
322325
/* Set a sane SCTLR_EL1, the VHE way */
323326
pre_disable_mmu_workaround
324327
msr_s SYS_SCTLR_EL12, x1

0 commit comments

Comments
 (0)