[PATCH v1 04/10] KVM: arm64: nv: Return a failed stage-2 descriptor read as a fault
From: Fuad Tabba
Date: Mon Sep 28 2026 - 11:27:30 EST
When KVM walks an L1 guest's stage-2 tables and can't read a
descriptor, for example because the guest points a table at an IPA with
no memslot, it sets a synchronous external abort on the walk but
returns the -EFAULT from kvm_read_guest(). As with an invalid
VTCR_EL2, KVM then leaves AT S12E{0,1}{R,W} unretired, so the guest
retries it forever. On an L2 abort, KVM injects the abort and
returns -EFAULT from KVM_RUN.
Return 1, as the walk already does when it can't update a descriptor,
leaving -EAGAIN from a descriptor race as its only negative return.
The AT then retires with the external abort in PAR_EL1, which is what a
stage-1 walk records for a descriptor it can't read.
Fixes: fd276e71d1e7b ("KVM: arm64: nv: Handle shadow stage 2 page faults")
Fixes: 92c6443222ca4 ("KVM: arm64: Propagate PTW errors up to AT emulation")
Signed-off-by: Fuad Tabba <fuad.tabba@xxxxxxxxx>
---
arch/arm64/kvm/nested.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index a67be19e73250..f9a2e50c0b567 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -304,7 +304,7 @@ static int walk_nested_s2_pgd(struct kvm_vcpu *vcpu, phys_addr_t ipa,
ret = read_guest_s2_desc(vcpu, paddr, &desc, wi);
if (ret < 0) {
out->esr = ESR_ELx_FSC_SEA_TTW(level);
- return ret;
+ return 1;
}
new_desc = desc;
--
2.39.5