Re: [PATCH 1/8] KVM: arm64: Make EL2 exception entry and exit context-synchronization events

Will Deacon
2026-04-30T09:08:04Z

On Tue, Apr 28, 2026 at 11:30:01AM +0100, Fuad Tabba wrote:
> SCTLR_EL2.EIS and SCTLR_EL2.EOS control whether exception entry and
> exit at EL2 are Context Synchronisation Events (CSEs). Per ARM DDI
> 0487 M.b, EIS is governed by D1.4.2 rule RBBSRF (p. D1-7205) and EOS
> by D1.4.4.1 rule RBWCFK (p. D1-7209). D24.2.175 (p. D24-9754):
>
> - !FEAT_ExS: the bit is RES1, so the entry/exit is unconditionally
> a CSE.
> - FEAT_ExS: the reset value is architecturally UNKNOWN; software
> must set the bit to make the entry/exit a CSE.
>
> INIT_SCTLR_EL2_MMU_ON in arch/arm64/include/asm/sysreg.h sets neither
> bit. KVM/arm64 hot paths rely on ERET from EL2 being a CSE, and on
> synchronous EL1->EL2 entry being a CSE, to elide explicit ISBs after
> MSRs to context-switching system registers (HCR_EL2, HFGxTR_EL2,
> HCRX_EL2, ZCR_EL2, CPACR_EL1, CPTR_EL2, SCTLR_EL1, ptrauth keys,
> etc.); examples include the activate-traps path,
> ptrauth_switch_to_guest, and the FPSIMD trap re-enable in
> kvm_hyp_handle_fpsimd. On FEAT_ExS hardware those reliances are not
> architecturally backed unless EOS=1 (and, for entry, EIS=1), and
> whether they hold today depends on firmware initialisation outside
> the kernel's control.
>
> Make the guarantee explicit: include SCTLR_ELx_EIS | SCTLR_ELx_EOS in
> INIT_SCTLR_EL2_MMU_ON so that EL2 exception entry and exit are
> unconditionally CSEs regardless of whether FEAT_ExS is implemented.
> This matches the pairing in arch/arm64/kvm/config.c which treats EIS
> and EOS together as RES1 under !FEAT_ExS.
>
> INIT_SCTLR_EL2_MMU_OFF is left unchanged: that path is used during
> very early EL2 init and the EL2 MMU-off transition, neither of which
> relies on these bits in the same way.
>
> Fixes: fe2c8d19189e ("KVM: arm64: Turn SCTLR_ELx_FLAGS into INIT_SCTLR_EL2_MMU_ON")

I don't think this Fixes: tag is accurate:

1. That commit doesn't do anything with EIS/EOS afaict.
2. Back in 5.12 (when that thing landed), SCTLR_EL2_RES1 did actually
include EIS and EOS

so I think the issue here might be that the auto-generated sysreg file
quietly changes the RES1 definitions as bits get allocated, but the
macros using the RES1 definition don't get updated. That's a pretty
horrible pit that it feels like we might keep falling into :/

Looking at 0a35bd285f43 ("arm64: Convert SCTLR_EL2 to sysreg
infrastructure"), I think we ended up dropping a whole bunch of fields
from the RES1 mask (which became 0!). Have you checked all of those?

Will