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:13 UTC|newest]
Thread overview: 27+ 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-06 9:35 ` sashiko-bot
2026-08-06 11:53 ` 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:27 ` sashiko-bot
2026-08-06 9:10 ` [PATCH v2 4/8] KVM: arm64: Correctly handle end of VA space TLBI invalidation Marc Zyngier
2026-08-06 9:30 ` sashiko-bot
2026-08-06 11:51 ` 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-06 9:25 ` sashiko-bot
2026-08-06 9:52 ` 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-06 9:35 ` sashiko-bot
2026-08-06 11:54 ` 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.