[PATCH] KVM: arm64: Pend host SErrors for protected vCPUs through HCR_EL2.VSE

From: Fuad Tabba

Date: Mon Oct 05 2026 - 01:04:32 EST


kvm_inject_serror_esr() reads PSTATE.A and SCTLR2_EL1.NMEA to decide
whether to emulate the SError's exception entry or pend it through
HCR_EL2.VSE. For a protected vCPU, the host's copy of those is stale,
and when it reads as unmasked KVM emulates the entry on that copy. EL2
never delivers it as an SError: its entry handler turns the pending
exception into an external abort on the trapped access, and an MMIO
completion still pending trips WARN_ON(INCREMENT_PC).

Always pend through HCR_EL2.VSE for a protected vCPU. EL2 forwards it,
and the guest's own masking decides when the SError is taken.

Fixes: 872383bd12e11 ("KVM: arm64: Add per-EC entry/exit state marshalling for protected guests")
Reported-by: Sashiko <sashiko-bot@xxxxxxxxxx>
Closes: https://lore.kernel.org/all/20261001142109.794CA1F000FF@xxxxxxxxxxxxxxx/
Signed-off-by: Fuad Tabba <fuad.tabba@xxxxxxxxx>
---
Applies on kvmarm/next. A follow-up to "KVM: arm64: Confine protected VM
vCPU state to EL2" [1], from Sashiko's review of its v4 patch 12.

[1] https://lore.kernel.org/all/20261001135711.1640520-1-fuad.tabba@xxxxxxxxx/

arch/arm64/kvm/inject_fault.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
index d6c4fc16f8795..49a342b078365 100644
--- a/arch/arm64/kvm/inject_fault.c
+++ b/arch/arm64/kvm/inject_fault.c
@@ -378,8 +378,11 @@ int kvm_inject_serror_esr(struct kvm_vcpu *vcpu, u64 esr)
*
* As we're emulating the SError injection we need to explicitly populate
* ESR_ELx.EC because hardware will not do it on our behalf.
+ *
+ * A protected vCPU's PSTATE and SCTLR2_EL1 live at EL2, so pend through
+ * HCR_EL2.VSE and let the guest's own masking apply.
*/
- if (!serror_is_masked(vcpu)) {
+ if (!vcpu_is_protected(vcpu) && !serror_is_masked(vcpu)) {
pend_serror_exception(vcpu);
esr |= FIELD_PREP(ESR_ELx_EC_MASK, ESR_ELx_EC_SERROR) | ESR_ELx_IL;
vcpu_write_sys_reg(vcpu, esr, exception_esr_elx(vcpu));

base-commit: fa22cd9947fc245d71bc40482f7f78eb0d5a4af0
--
2.39.5