[PATCH] KVM: arm64: Don't livelock when AT can't resolve a fault IPA

Fuad Tabba fuad.tabba at linux.dev
Mon Nov 2 07:57:51 PST 2026


Hi Will,

On Mon, 02 Nov 2026 14:17:10 +0000, Will Deacon <will at kernel.org> wrote:
> On Mon, Nov 02, 2026 at 02:09:25PM +0000, Marc Zyngier wrote:
> > On Mon, 02 Nov 2026 13:59:12 +0000,
> > Will Deacon <will at kernel.org> wrote:
[...]
> > > > diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
[...]
> > > >  static inline bool kvm_hyp_handle_memory_fault(struct kvm_vcpu *vcpu,
> > > >                                                 u64 *exit_code)
> > > >  {
> > > > -        if (!__populate_fault_info(vcpu))
> > > > +        if (!__populate_fault_info(vcpu)) {
> > >
> > > Presumably we need a barrier (DSB?) here, to ensure that the TLBI happens
> > > after the AT instruction?

I don't think the TLBI requires a barrier before it, because it
doesn't matter if the AT's walk allocates entries after the TLBI.
Anything it allocates matches memory, and the stage-2 descriptor the
AT faulted on has AF clear, so that descriptor can't be cached:

R_XCLRD: Translation table entries that generate a Translation
fault, an Address size fault, or an Access flag fault are never cached
in a TLB.

The stale entries the guest keeps hitting were already there before
the TLBI, and the dsb(nsh) and isb after it are what complete it
against them.

[... your other reply ... ]
> > Alternatively, VMALLE1 or even VAE1 should be enough to get rid of the
> > S1 TLB.
>
> Ah, sorry, VMALLE1 is what I meant to ask about. I basically haven't
> understood the need to invalidate the stage-2.

The guest's walk can also go through a stage-2 entry for its
page-table page, cached before the aging cleared that page's AF, and
nothing requires the AT to use that entry:

R_NPZWX: When an address translation instruction is executed, it is
IMPLEMENTATION DEFINED whether the result can be returned from a TLB,
or a translation table walk occurs.

So if my reading is correct, on a CPU whose AT walks memory instead,
the AT keeps failing while the guest's walk goes through the stale
entry, and the guest takes the same permission fault again. VMALLE1
and VAE1 only cover stage 1, so they'd leave that loop in place.

Cheers,
/fuad



More information about the linux-arm-kernel mailing list