From: Oliver Upton <oupton@kernel.org>
To: Marc Zyngier <maz@kernel.org>
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>,
Zenghui Yu <yuzenghui@huawei.com>,
Hyunwoo Kim <imv4bel@gmail.com>,
stable@vger.kernel.org
Subject: Re: [PATCH] KVM: arm64: Add kvm_for_each_vncr_tlb() helper
Date: Mon, 8 Jun 2026 09:33:43 -0700 [thread overview]
Message-ID: <aibu532apl5w0lXU@kernel.org> (raw)
In-Reply-To: <20260607175745.297793-1-maz@kernel.org>
Hey Marc,
Especially since this is a stable-worthy fix, it might be worth calling
out the bug in the shortlog, e.g.
KVM: arm64: nv: Avoid dereferencing NULL VNCR pseudo-TLB
On Sun, Jun 07, 2026 at 06:57:45PM +0100, Marc Zyngier wrote:
> VNCR TLB invalidation occurs from MMU notifiers or TLBI instructions,
> and either can race against a vcpu not being onlined yet (no pseudo-TLB
> allocated). Similarly, the TLB might be invalid, and the invalidation
> should be skipped in this case.
>
> Both kvm_invalidate_vncr_ipa() and kvm_invalidate_vncr_va() are
> expected to perform the same checks, except that the latter doesn't
> check for the allocation and blindly dereferences the pointer.
>
> Solve this by introducing a new iterator built on top of the usual
> kvm_for_each_vcpu() that checks for both of the above conditions,
> and convert the two users to it.
>
> Reported-by: Hyunwoo Kim <imv4bel@gmail.com>
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> Link: https://lore.kernel.org/r/aiUvSbrWndQeUPc8@v4bel
> Fixes: 4ffa72ad8f37 ("KVM: arm64: nv: Add S1 TLB invalidation primitive for VNCR_EL2")
> Cc: stable@vger.kernel.org
Looks good
Reviewed-by: Oliver Upton <oupton@kernel.org>
Thanks,
Oliver
> ---
> arch/arm64/kvm/nested.c | 36 +++++++++++++++---------------------
> 1 file changed, 15 insertions(+), 21 deletions(-)
>
> diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
> index f8d3f3a723282..690b8e8564166 100644
> --- a/arch/arm64/kvm/nested.c
> +++ b/arch/arm64/kvm/nested.c
> @@ -908,9 +908,21 @@ static void invalidate_vncr(struct vncr_tlb *vt)
> clear_fixmap(vncr_fixmap(vt->cpu));
> }
>
> +/*
> + * VNCR TLB invalidation occurs from MMU notifiers or TLBI instructions, and
> + * either can race against a vcpu not being onlined yet (no pseudo-TLB
> + * allocated). Similarly, the TLB might be invalid. Skip those, as they
> + * obviously don't participate in the invalidation at this stage.
> + */
> +#define kvm_for_each_vncr_tlb(idx, vcpup, tlbp, kvm) \
> + kvm_for_each_vcpu(idx, vcpup, kvm) \
> + if (((tlbp) = vcpup->arch.vncr_tlb) && \
> + (tlbp)->valid)
> +
> static void kvm_invalidate_vncr_ipa(struct kvm *kvm, u64 start, u64 end)
> {
> struct kvm_vcpu *vcpu;
> + struct vncr_tlb *vt;
> unsigned long i;
>
> lockdep_assert_held_write(&kvm->mmu_lock);
> @@ -918,24 +930,9 @@ static void kvm_invalidate_vncr_ipa(struct kvm *kvm, u64 start, u64 end)
> if (!kvm_has_feat(kvm, ID_AA64MMFR4_EL1, NV_frac, NV2_ONLY))
> return;
>
> - kvm_for_each_vcpu(i, vcpu, kvm) {
> - struct vncr_tlb *vt = vcpu->arch.vncr_tlb;
> + kvm_for_each_vncr_tlb(i, vcpu, vt, kvm) {
> u64 ipa_start, ipa_end, ipa_size;
>
> - /*
> - * Careful here: We end-up here from an MMU notifier,
> - * and this can race against a vcpu not being onlined
> - * yet, without the pseudo-TLB being allocated.
> - *
> - * Skip those, as they obviously don't participate in
> - * the invalidation at this stage.
> - */
> - if (!vt)
> - continue;
> -
> - if (!vt->valid)
> - continue;
> -
> ipa_size = ttl_to_size(pgshift_level_to_ttl(vt->wi.pgshift,
> vt->wr.level));
> ipa_start = vt->wr.pa & ~(ipa_size - 1);
> @@ -965,17 +962,14 @@ static void invalidate_vncr_va(struct kvm *kvm,
> struct s1e2_tlbi_scope *scope)
> {
> struct kvm_vcpu *vcpu;
> + struct vncr_tlb *vt;
> unsigned long i;
>
> lockdep_assert_held_write(&kvm->mmu_lock);
>
> - kvm_for_each_vcpu(i, vcpu, kvm) {
> - struct vncr_tlb *vt = vcpu->arch.vncr_tlb;
> + kvm_for_each_vncr_tlb(i, vcpu, vt, kvm) {
> u64 va_start, va_end, va_size;
>
> - if (!vt->valid)
> - continue;
> -
> va_size = ttl_to_size(pgshift_level_to_ttl(vt->wi.pgshift,
> vt->wr.level));
> va_start = vt->gva & ~(va_size - 1);
> --
> 2.47.3
>
prev parent reply other threads:[~2026-06-08 16:33 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-07 17:57 [PATCH] KVM: arm64: Add kvm_for_each_vncr_tlb() helper Marc Zyngier
2026-06-07 18:08 ` sashiko-bot
2026-06-07 20:47 ` Marc Zyngier
2026-06-08 16:33 ` Oliver Upton [this message]
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=aibu532apl5w0lXU@kernel.org \
--to=oupton@kernel.org \
--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=maz@kernel.org \
--cc=seiden@linux.ibm.com \
--cc=stable@vger.kernel.org \
--cc=suzuki.poulose@arm.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.