From: Marc Zyngier <maz@kernel.org>
To: Wei-Lin Chang <weilin.chang@arm.com>
Cc: kvmarm@lists.linux.dev, kvm@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
Steffen Eiden <seiden@linux.ibm.com>,
Joey Gouly <joey.gouly@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Oliver Upton <oupton@kernel.org>,
Zenghui Yu <yuzenghui@huawei.com>,
Fuad Tabba <fuad.tabba@linux.dev>,
Hyunwoo Kim <imv4bel@gmail.com>,
Yao Yuan <yaoyuan@linux.alibaba.com>,
ljs@kernel.org, stable@vger.kernel.org
Subject: Re: [PATCH v2 4/8] KVM: arm64: Correctly handle end of VA space TLBI invalidation
Date: Sun, 09 Aug 2026 19:13:45 +0100 [thread overview]
Message-ID: <86wltz9n6u.wl-maz@kernel.org> (raw)
In-Reply-To: <yifz3wn5gk5sr6mapi32trgk5m5kp33bquctsjmkifebnsnndt@fix6u4rthx4g>
On Sat, 08 Aug 2026 22:41:31 +0100,
Wei-Lin Chang <weilin.chang@arm.com> wrote:
>
> Hi Marc,
>
> On Thu, Aug 06, 2026 at 10:10:22AM +0100, Marc Zyngier wrote:
> > Our TLB invalidation by VA code is based on comparing two ranges,
> > one defined by the TLB, and one defined by the TLBI instruction.
> >
> > Each range is defined by a start and a size. However, the way the
> > comparison is done doesn't account for address rollover, as it
> > compares an address with (base + size). This works nicely until
> > this expression represent the last page/block in the TTBR1 VA space,
> > as the result is a big fat 0. And a failed TLB invalidation.
> >
> > Rewrite the comparison in a way that is immune to the address
> > rollover (making the end address inclusive instead of exclusive),
> > and move this into a common helper that is used by both VA and IPA
> > invalidations, as suggested by Hyunwoo Kim (although the IPA version
> > didn't suffer from this particular problem, obviously).
> >
> > Fixes: 4ffa72ad8f37e ("KVM: arm64: nv: Add S1 TLB invalidation primitive for VNCR_EL2")
> > Reviewed-by: Yuan Yao <yaoyuan@linux.alibaba.com>
> > Signed-off-by: Marc Zyngier <maz@kernel.org>
> > Cc: stable@vger.kernel.org
> > ---
> > arch/arm64/kvm/nested.c | 43 ++++++++++++++++++-----------------------
> > 1 file changed, 19 insertions(+), 24 deletions(-)
> >
> > diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
> > index 27bc7ee4b3382..8a602d074dbb4 100644
> > --- a/arch/arm64/kvm/nested.c
> > +++ b/arch/arm64/kvm/nested.c
> > @@ -999,6 +999,20 @@ static void invalidate_vncr(struct vncr_tlb *vt)
> > clear_fixmap(vncr_fixmap(vt->cpu));
> > }
> >
> > +static bool vncr_tlb_intersects(struct vncr_tlb *vt, u64 addr,
> > + u64 scope_start, u64 scope_size)
> > +{
> > + u64 tlb_size, tlb_start, tlb_end, scope_end;
> > +
> > + tlb_size = ttl_to_size(pgshift_level_to_ttl(vt->wi.pgshift, vt->wr.level));
> > +
> > + tlb_start = addr & ~(tlb_size - 1);
> > + tlb_end = tlb_start + tlb_size - 1;
> > + scope_end = scope_start + scope_size - 1;
>
> I think if scope_end overflows,
>
> > +
> > + return !(tlb_end < scope_start || tlb_start > scope_end);
>
> tlb_start > scope_end can evaluate to true and we return false even when
> there is overlap near the end of the TTBR1 address space.
I assume that you are implicitly talking about TLB Range Invalidation,
right? Because we otherwise align base on size, making overflows
impossible with this patch.
> Therefore I think we need to saturate scope_end to ULONG_MAX when overflow
> happens. This is also what the architecture does when looking at the
> pseudocode J1.2.3.442 TLBIRange (M.c).
That's one possible implementation, because the pseudocode is dealing
with start/end directly, but that's not how our scope works (it deals
with start and size).
For that we need to cap the *size*, similarly to what is done in
handle_ripas2e1is() (see patch #6). Something like the hack below.
M.
diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index 21d0f4cbe07f1..5b8edb2e8a87d 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -305,6 +305,12 @@ static inline u64 decode_range_tlbi(u64 val, u64 *range, u16 *asid)
num = FIELD_GET(GENMASK(43, 39), val);
*range = __TLBI_RANGE_PAGES(num, scale) << shift;
+ /* Cap the range to the correct half of the address space */
+ if (!(base & BIT(48)))
+ *range = min(*range, (BIT(48) - base));
+ else
+ *range = min(*range, ~base + 1);
+
return base;
}
--
Without deviation from the norm, progress is not possible.
next prev parent reply other threads:[~2026-08-09 18:14 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-06 9:10 [PATCH v2 0/8] KVM: arm64: VNCR TLB invalidation fixes Marc Zyngier
2026-08-06 9:10 ` [PATCH v2 1/8] KVM: arm64: Remove VM-wide VNCR mapping counter Marc Zyngier
2026-08-07 16:45 ` Lorenzo Stoakes (ARM)
2026-08-08 8:43 ` Marc Zyngier
2026-08-06 9:10 ` [PATCH v2 2/8] KVM: arm64: Handle negative S1 walk levels in VNCR TLB size evaluation Marc Zyngier
2026-08-07 17:12 ` Lorenzo Stoakes (ARM)
2026-08-08 9:06 ` Marc Zyngier
2026-08-06 9:10 ` [PATCH v2 3/8] KVM: arm64: Consider SCTLR_EL2.M when mapping the L1 VNCR page Marc Zyngier
2026-08-06 9:10 ` [PATCH v2 4/8] KVM: arm64: Correctly handle end of VA space TLBI invalidation Marc Zyngier
2026-08-08 21:41 ` Wei-Lin Chang
2026-08-09 18:13 ` Marc Zyngier [this message]
2026-08-09 21:10 ` Wei-Lin Chang
2026-08-06 9:10 ` [PATCH v2 5/8] KVM: arm64: Handle VNCR TLB invalidation race with vcpu_put() VNCR unmapping Marc Zyngier
2026-08-07 6:03 ` Yao Yuan
2026-08-06 9:10 ` [PATCH v2 6/8] KVM: arm64: Sign-extend VA for range-based TLBI invalidation Marc Zyngier
2026-08-06 9:10 ` [PATCH v2 7/8] KVM: arm64: Make VNCR invalidation participate in MMU invalidation retry Marc Zyngier
2026-08-06 9:10 ` [PATCH v2 8/8] KVM: arm64: Add VNCR TLB tracking again Marc Zyngier
2026-08-08 18:35 ` [PATCH v2 0/8] KVM: arm64: VNCR TLB invalidation fixes Oliver Upton
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=86wltz9n6u.wl-maz@kernel.org \
--to=maz@kernel.org \
--cc=fuad.tabba@linux.dev \
--cc=imv4bel@gmail.com \
--cc=joey.gouly@arm.com \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=ljs@kernel.org \
--cc=oupton@kernel.org \
--cc=seiden@linux.ibm.com \
--cc=stable@vger.kernel.org \
--cc=suzuki.poulose@arm.com \
--cc=weilin.chang@arm.com \
--cc=yaoyuan@linux.alibaba.com \
--cc=yuzenghui@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox