From: Marc Zyngier Subject: [PATCH 2/4] Handle HCR_EL2.E2H RES1 behaviour To: tech@openbsd.org Cc: kettenis@openbsd.org Date: Sun, 12 Apr 2026 11:18:22 +0100 An implementation is allowed to make HCR_EL2.E2H RES1, which means that the CPU behaves as if this bit was 1, even if it reads as 0 or can be written with 0. While the architecture advertises this via ID_AA64MMFR4_EL1.E2H0, hypervisors cannot always expose this to a guest if the hardware doesn't implemtn FEAT_FGT. Instead, detect the effects of HCR_EL2.E2H being RES1 by checking for the aliasing property between accessors targetting the same register (FAR_ELx in this case). This gives a reliable litmus test for CPUs that are stuck in VHE mode. Signed-off-by: Marc Zyngier --- sys/arch/arm64/arm64/locore.S | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/sys/arch/arm64/arm64/locore.S b/sys/arch/arm64/arm64/locore.S index 03aa6f7d2..244ae086f 100644 --- a/sys/arch/arm64/arm64/locore.S +++ b/sys/arch/arm64/arm64/locore.S @@ -51,10 +51,23 @@ drop_to_el1: RETGUARD_CHECK(drop_to_el1, x15) ret 2: - /* Check for EL2 Host mode */ - mrs x2, hcr_el2 - tbz x2, #34, 3f /* HCR_E2H */ + /* + * Check for EL2 Host mode by testing aliasing between + * EL1 and EL2 accessors of the FAR_EL2 register. + */ + msr hcr_el2, xzr + isb + mov x2, #1 + msr far_el1, x2 + isb + mov x2, #2 + msr far_el2, x2 + isb + mrs x2, far_el1 + cmp x2, #2 + b.ne 3f + mov x2, #HCR_E2H orr x2, x2, #HCR_TGE msr hcr_el2, x2 isb -- 2.51.0