aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Upton <oliver.upton@linux.dev>2025-07-08 10:25:28 -0700
committerOliver Upton <oliver.upton@linux.dev>2025-07-08 11:36:36 -0700
commitbfb7a30b19861e559d64b7f2c3202d948fbf93ea (patch)
treea94fde29f9c07313cd71ffbf60eaafe259134423
parentKVM: arm64: Advertise support for FEAT_DoubleFault2 (diff)
downloadlinux-bfb7a30b19861e559d64b7f2c3202d948fbf93ea.tar.gz
linux-bfb7a30b19861e559d64b7f2c3202d948fbf93ea.zip
KVM: arm64: Don't retire MMIO instruction w/ pending (emulated) SError
KVM might have an emulated SError queued for the guest if userspace returned an abort for MMIO. Better yet, it could actually be a *synchronous* exception in disguise if SCTLR2_ELx.EASE is set. Don't advance PC if KVM owes an emulated SError, just like the handling of emulated SEA injection. Reviewed-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20250708172532.1699409-24-oliver.upton@linux.dev Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
-rw-r--r--arch/arm64/kvm/mmio.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/arch/arm64/kvm/mmio.c b/arch/arm64/kvm/mmio.c
index 573a6ade2f4e..54f9358c9e0e 100644
--- a/arch/arm64/kvm/mmio.c
+++ b/arch/arm64/kvm/mmio.c
@@ -72,7 +72,7 @@ unsigned long kvm_mmio_read_buf(const void *buf, unsigned int len)
return data;
}
-static bool kvm_pending_sync_exception(struct kvm_vcpu *vcpu)
+static bool kvm_pending_external_abort(struct kvm_vcpu *vcpu)
{
if (!vcpu_get_flag(vcpu, PENDING_EXCEPTION))
return false;
@@ -90,6 +90,8 @@ static bool kvm_pending_sync_exception(struct kvm_vcpu *vcpu)
switch (vcpu_get_flag(vcpu, EXCEPT_MASK)) {
case unpack_vcpu_flag(EXCEPT_AA64_EL1_SYNC):
case unpack_vcpu_flag(EXCEPT_AA64_EL2_SYNC):
+ case unpack_vcpu_flag(EXCEPT_AA64_EL1_SERR):
+ case unpack_vcpu_flag(EXCEPT_AA64_EL2_SERR):
return true;
default:
return false;
@@ -113,7 +115,7 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu)
* Detect if the MMIO return was already handled or if userspace aborted
* the MMIO access.
*/
- if (unlikely(!vcpu->mmio_needed || kvm_pending_sync_exception(vcpu)))
+ if (unlikely(!vcpu->mmio_needed || kvm_pending_external_abort(vcpu)))
return 1;
vcpu->mmio_needed = 0;