]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
KVM: arm64: Flush HCR_EL2.VSE to deliver SErrors to pKVM guests
authortabba@google.com <tabba@google.com>
Sun, 31 May 2026 15:45:48 +0000 (16:45 +0100)
committerMarc Zyngier <maz@kernel.org>
Sun, 7 Jun 2026 13:34:53 +0000 (14:34 +0100)
With pKVM enabled, the host injects a virtual SError by setting
HCR_EL2.VSE on its vCPU copy, but flush_hyp_vcpu() only flows TWI/TWE
into the hyp vCPU that runs, so VSE never reaches it and a deferred
(masked) SError is never delivered. VSE is a host-owned injection
control, not a trap-configuration bit, so restricting the host's
trap-register values should not have dropped it.

Flow it on entry; sync_hyp_vcpu() already copies hcr_el2 back, so
delivery is reflected to the host. THis makes it consistent with
the existing forwarding of VSESR_EL2, which qualifies the Serror.

Fixes: b56680de9c648 ("KVM: arm64: Initialize trap register values in hyp in pKVM")
Reported-by: Sashiko (local):gemini-3.1-pro
Signed-off-by: Fuad Tabba <tabba@google.com>
Reviewed-by: Oliver Upton <oupton@kernel.org>
Link: https://patch.msgid.link/20260531154548.1505799-1-tabba@google.com
Signed-off-by: Marc Zyngier <maz@kernel.org>
arch/arm64/kvm/hyp/nvhe/hyp-main.c

index a0da08caa6c27eee463063c2a6b24ba8bb9ec352..1d01c6e547f5d5c6f42860398e99075d967a47cd 100644 (file)
@@ -135,9 +135,14 @@ static void flush_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
        hyp_vcpu->vcpu.arch.ctxt.__hyp_running_vcpu = NULL;
 
        hyp_vcpu->vcpu.arch.mdcr_el2    = host_vcpu->arch.mdcr_el2;
-       hyp_vcpu->vcpu.arch.hcr_el2 &= ~(HCR_TWI | HCR_TWE);
+       /*
+        * HCR_EL2.VSE is host-owned (a pending virtual SError to inject), not a
+        * trap-control bit, so it must flow to the hyp vCPU alongside TWI/TWE
+        * for the vSError to be delivered. sync_hyp_vcpu() reflects it back.
+        */
+       hyp_vcpu->vcpu.arch.hcr_el2 &= ~(HCR_TWI | HCR_TWE | HCR_VSE);
        hyp_vcpu->vcpu.arch.hcr_el2 |= READ_ONCE(host_vcpu->arch.hcr_el2) &
-                                                (HCR_TWI | HCR_TWE);
+                                                (HCR_TWI | HCR_TWE | HCR_VSE);
 
        hyp_vcpu->vcpu.arch.iflags      = host_vcpu->arch.iflags;