All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Marc Zyngier" <maz@kernel.org>
Cc: kvmarm@lists.linux.dev, "Marc Zyngier" <maz@kernel.org>,
	"Oliver Upton" <oupton@kernel.org>
Subject: Re: [PATCH v3 1/2] KVM: arm64: nv: Fix life cycle of the nested_mmus array
Date: Fri, 21 Aug 2026 16:48:08 +0000	[thread overview]
Message-ID: <20260821164808.78A591F00AC4@smtp.kernel.org> (raw)
In-Reply-To: <20260821161829.1032561-2-maz@kernel.org>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

New issues:
- [High] Lockless iteration in `kvm_arch_flush_shadow_all` races with `kvm_vcpu_init_nested`, causing a garbage/NULL pointer dereference.

Pre-existing issues:
- [High] Memory leak of nested MMU stage-2 page tables (`mmu->pgt`) and per-CPU data when VM is destroyed after `mmu_notifier_release` has been bypassed.
--

--- Patch [1]: [PATCH v3 1/2] KVM: arm64: nv: Fix life cycle of the nested_mmus array ---
commit 2f4c64e5fe4ce7a7346ea83c7e69ecaa68ee9290
Author: Marc Zyngier <maz@kernel.org>
Date:   Fri Aug 21 16:18:28 2026 +0000

    KVM: arm64: nv: Fix life cycle of the nested_mmus array
    
This commit modifies the life cycle of the nested_mmus array by turning it 
from an array of structures into an array of pointers allocated at VM creation. 
It prevents issues where reallocation during VCPU_INIT could leave running 
vCPUs with freed pointers, ensuring S2 MMUs are incrementally allocated without 
reallocation.

Link: https://lore.kernel.org/r/20260803224405.41468-1-kmehltretter@gmail.com

> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index 8b080804bc90b..b53219e048bdf 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
[ ... ]
> @@ -337,6 +340,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
>  
>  	kvm_unshare_hyp(kvm, kvm + 1);
>  
> +	kvfree(kvm->arch.nested_mmus);

[Severity: High]
This is a pre-existing issue, but does this teardown path leak the nested MMU 
stage-2 page tables?

When a VM file descriptor is shared with a child process and the parent exits,
the parent's exit_mmap() calls mmu_notifier_release() which unhashes the
notifier. If the child process then initializes vCPUs, it allocates new nested
MMU PGDs via init_nested_s2_mmu().

When the child exits, kvm_arch_destroy_vm() is called. Because the notifier is
already unhashed, it bypasses the release callback, skipping
kvm_arch_flush_shadow_all().

Since the cleanup path fails to call kvm_free_stage2_pgd() for the MMUs before
freeing the nested_mmus array, the page tables (mmu->pgt) and per-CPU
allocations (mmu->last_vcpu_ran) appear to be permanently leaked.

>  	kvm_arm_teardown_hypercalls(kvm);
>  }
>  
> diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
> index 17123f0b6daba..9070d5bc5af03 100644
> --- a/arch/arm64/kvm/nested.c
> +++ b/arch/arm64/kvm/nested.c
[ ... ]
> @@ -84,51 +89,40 @@ int kvm_vcpu_init_nested(struct kvm_vcpu *vcpu)
[ ... ]
> +		guard(write_lock)(&kvm->mmu_lock);
>  
> -		for (int i = kvm->arch.nested_mmus_size; i < num_mmus; i++)
> -			kvm_free_stage2_pgd(&kvm->arch.nested_mmus[i]);
> +		for (i = 0; i < S2_MMU_PER_VCPU; i++)
> -		free_page((unsigned long)vcpu->arch.ctxt.vncr_array);
> -		vcpu->arch.ctxt.vncr_array = NULL;
> +			kvm->arch.nested_mmus[i + kvm->arch.nested_mmus_size] = &tmp[i];
>  
> -		return ret;
> +		kvm->arch.nested_mmus_size += S2_MMU_PER_VCPU;

[Severity: High]
Could this result in a data race on weakly ordered architectures?

Here in kvm_vcpu_init_nested(), nested_mmus_size is incremented immediately
after storing the new MMU pointers in the array. Since there are no memory
barriers between the pointer stores and the size increment, the CPU could
reorder the size increment to be visible before the array elements.

If kvm_arch_flush_shadow_all() concurrently iterates over the array locklessly
(for example, during process exit via mmu_notifier_release), it could read the
updated size but observe uninitialized array memory. This would result in
reading a garbage pointer, leading to a kernel panic when it dereferences it
in atomic_read(&mmu->refcnt).

>  	}
>  
> -	kvm->arch.nested_mmus_size = num_mmus;
> -
>  	return 0;
>  }

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260821161829.1032561-1-maz@kernel.org?part=1

  reply	other threads:[~2026-08-21 16:48 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-21 16:18 [PATCH v3 0/2] KVM: arm64: nv: Shadow S2 life-cycle fixes Marc Zyngier
2026-08-21 16:18 ` [PATCH v3 1/2] KVM: arm64: nv: Fix life cycle of the nested_mmus array Marc Zyngier
2026-08-21 16:48   ` sashiko-bot [this message]
2026-08-21 16:18 ` [PATCH v3 2/2] KVM: arm64: nv: Delay freeing of shadow S2 structures until VM destruction Marc Zyngier
2026-08-21 16:45   ` sashiko-bot
2026-08-21 18:15   ` Lorenzo Stoakes (ARM)
2026-08-22  8:12     ` Marc Zyngier
2026-08-24 11:18       ` Lorenzo Stoakes (ARM)
2026-08-23 14:11   ` Wei-Lin Chang
2026-08-24 11:07     ` Lorenzo Stoakes (ARM)
2026-08-24 11:09       ` Lorenzo Stoakes (ARM)
2026-08-23 14:07 ` [PATCH v3 0/2] KVM: arm64: nv: Shadow S2 life-cycle fixes Wei-Lin Chang

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=20260821164808.78A591F00AC4@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=kvmarm@lists.linux.dev \
    --cc=maz@kernel.org \
    --cc=oupton@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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.