mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
arm64: Fix early handling of FEAT_E2H0 not being implemented
Commit3944382fa6
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:3944382fa6
("arm64: Treat HCR_EL2.E2H as RES1 when ID_AA64MMFR4_EL1.E2H0 is negative") Signed-off-by: Marc Zyngier <maz@kernel.org> Acked-by: Catalin Marinas <catalin.marinas@arm.com> Link: https://lore.kernel.org/r/20240321115414.3169115-1-maz@kernel.org Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
This commit is contained in:
parent
4c36a15673
commit
b3320142f3
1 changed files with 16 additions and 13 deletions
|
@ -291,6 +291,21 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL)
|
||||||
blr x2
|
blr x2
|
||||||
0:
|
0:
|
||||||
mov_q x0, HCR_HOST_NVHE_FLAGS
|
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
|
msr hcr_el2, x0
|
||||||
isb
|
isb
|
||||||
|
|
||||||
|
@ -303,22 +318,10 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL)
|
||||||
|
|
||||||
mov_q x1, INIT_SCTLR_EL1_MMU_OFF
|
mov_q x1, INIT_SCTLR_EL1_MMU_OFF
|
||||||
|
|
||||||
/*
|
|
||||||
* Compliant CPUs advertise their VHE-onlyness with
|
|
||||||
* ID_AA64MMFR4_EL1.E2H0 < 0. HCR_EL2.E2H can be
|
|
||||||
* RES1 in that case.
|
|
||||||
*
|
|
||||||
* Fruity CPUs seem to have HCR_EL2.E2H set to RES1, but
|
|
||||||
* don't advertise it (they predate this relaxation).
|
|
||||||
*/
|
|
||||||
mrs_s x0, SYS_ID_AA64MMFR4_EL1
|
|
||||||
ubfx x0, x0, #ID_AA64MMFR4_EL1_E2H0_SHIFT, #ID_AA64MMFR4_EL1_E2H0_WIDTH
|
|
||||||
tbnz x0, #(ID_AA64MMFR4_EL1_E2H0_SHIFT + ID_AA64MMFR4_EL1_E2H0_WIDTH - 1), 1f
|
|
||||||
|
|
||||||
mrs x0, hcr_el2
|
mrs x0, hcr_el2
|
||||||
and x0, x0, #HCR_E2H
|
and x0, x0, #HCR_E2H
|
||||||
cbz x0, 2f
|
cbz x0, 2f
|
||||||
1:
|
|
||||||
/* Set a sane SCTLR_EL1, the VHE way */
|
/* Set a sane SCTLR_EL1, the VHE way */
|
||||||
pre_disable_mmu_workaround
|
pre_disable_mmu_workaround
|
||||||
msr_s SYS_SCTLR_EL12, x1
|
msr_s SYS_SCTLR_EL12, x1
|
||||||
|
|
Loading…
Add table
Reference in a new issue