[PATCH v1 03/10] KVM: arm64: nv: Don't loop on AT S12E{0,1}{R,W} with an invalid VTCR_EL2

From: Fuad Tabba

Date: Mon Sep 28 2026 - 11:26:49 EST


When KVM walks an L1 guest's stage-2 tables, a positive return means
the walk faulted with the syndrome in out->esr, and a negative one
means KVM couldn't complete it and the caller has to retry. The
VTCR_EL2.T0SZ and SL0 checks return -EFAULT for what is the guest's
own misconfiguration: an invalid SL0 is a stage-2 level 0 Translation
fault (AArch64_S2InvalidSL()), and so is an out of range T0SZ that the
implementation doesn't clamp (AArch64_S2TxSZFaults()).

An L1 guest that programs either value therefore executes
AT S12E{0,1}{R,W} forever, since the AT is never retired, and on an L2
abort KVM injects the fault and then returns -EFAULT from KVM_RUN. The
T0SZ check also left the syndrome unset, so where a fault was reported
at all, on an L2 abort or in PAR_EL1 after a stage-1 AT, it was an
Address size fault.

Return 1 with a level 0 Translation fault from both checks, as the walk
does for the guest's other stage-2 faults.

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 | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index 98c1f8c193319..a67be19e73250 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -275,13 +275,10 @@ static int walk_nested_s2_pgd(struct kvm_vcpu *vcpu, phys_addr_t ipa,

stride = wi->pgshift - 3;
input_size = get_ia_size(wi);
- if (input_size > 48 || input_size < 25)
- return -EFAULT;
-
- ret = check_base_s2_limits(vcpu, wi, level, input_size, stride);
- if (ret) {
+ if (input_size > 48 || input_size < 25 ||
+ check_base_s2_limits(vcpu, wi, level, input_size, stride)) {
out->esr = compute_fsc(0, ESR_ELx_FSC_FAULT);
- return ret;
+ return 1;
}

base_lower_bound = 3 + input_size - ((3 - level) * stride +
--
2.39.5