All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Rick Edgecombe" <rick.p.edgecombe@intel.com>
Cc: kvm@vger.kernel.org
Subject: Re: [PATCH v10 08/11] KVM: TDX: Get/put PAMT pages when (un)mapping private memory
Date: Thu, 03 Sep 2026 02:14:04 +0000	[thread overview]
Message-ID: <20260903021405.0DA101F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260903015113.93343-9-rick.p.edgecombe@intel.com>

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

New issues:
- [High] The retry loop in kvm_tdp_mmu_map_private_pfn() fails to top up memory caches, causing PAMT cache exhaustion and a fatal KVM_BUG_ON when S-EPT mapping encounters contention.

Pre-existing issues:
- [High] cpus_read_lock() is acquired while kvm->lock is already held during KVM_TDX_INIT_VM initialization and teardown, violating lock hierarchy.
--

commit bab02cc7c6ddf1559b28e6bffce54a70e3531bc9
Author: Kiryl Shutsemau <kas@kernel.org>

KVM: TDX: Get/put PAMT pages when (un)mapping private memory
    
This patch adds Dynamic PAMT support to KVM's S-EPT MMU by allocating PAMT
pages on demand when adding guest memory and balancing releases via
tdx_pamt_put() when removing it or on error paths.

> diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
> index 957078e8656ef..09573112540e9 100644
> --- a/arch/x86/kvm/vmx/tdx.c
> +++ b/arch/x86/kvm/vmx/tdx.c
[ ... ]
> @@ -1679,16 +1694,28 @@ static struct page *tdx_spte_to_sept_pt(struct kvm *kvm, gfn_t gfn,
>  static int tdx_sept_map_nonleaf_spte(struct kvm *kvm, gfn_t gfn,
>  				     enum pg_level level, u64 new_spte)
>  {
> +	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
>  	gpa_t gpa = gfn_to_gpa(gfn);
>  	u64 err, entry, level_state;
>  	struct page *sept_pt;
> +	int ret;
> +
> +	if (KVM_BUG_ON(!vcpu, kvm))
> +		return -EIO;
>  
>  	sept_pt = tdx_spte_to_sept_pt(kvm, gfn, new_spte, level);
>  	if (!sept_pt)
>  		return -EIO;
>  
> +	ret = tdx_pamt_get(page_to_pfn(sept_pt), &to_tdx(vcpu)->pamt_cache);
> +	if (KVM_BUG_ON(ret, kvm))
> +		return ret;

[Severity: High]
Does this error path lead to PAMT cache exhaustion and a fatal VM BUG if
mapping encounters contention?

When tdh_mem_sept_add() below encounters lock contention, which can occur
during parallel setups, it returns TDX_OPERAND_BUSY (-EBUSY/RET_PF_RETRY).

The error path calls tdx_pamt_put(), which drops the refcount and calls
free_pamt_array(). Crucially, free_pamt_array() returns the memory to the
kernel buddy allocator instead of returning it to the vCPU cache:

arch/x86/virt/vmx/tdx/tdx.c:tdx_pamt_put() {
	...
	atomic_set(dpamt_refcount, 0);
	spin_unlock(&dpamt_lock);
	free_pamt_array(pamt_pages);
}

The failure propagates as RET_PF_RETRY, and the page fault loop in
kvm_tdp_mmu_map_private_pfn() retries without calling
mmu_topup_memory_caches():

arch/x86/kvm/mmu/mmu.c:kvm_tdp_mmu_map_private_pfn() {
	...
		r = kvm_tdp_mmu_map(vcpu, &fault);
	} while (r == RET_PF_RETRY);
}

This causes a net loss of cache entries. When the unreplenished cache runs
out of memory, tdx_pamt_get() returns -ENOMEM, causing KVM to BUG the VM
here. Could tdx_pamt_put() restore pages to the cache, or could the
retry loop be updated to replenish caches?

> +
>  	err = tdh_mem_sept_add(&to_kvm_tdx(kvm)->td, gpa, level, sept_pt,
>  			       &entry, &level_state);
> +	if (err)
> +		tdx_pamt_put(page_to_pfn(sept_pt));
> +
>  	if (unlikely(tdx_operand_busy(err)))
>  		return -EBUSY;
[ ... ]

[Severity: High]
This is a pre-existing issue, but does acquiring cpus_read_lock() while
kvm->lock is already held violate the KVM lock hierarchy?

During KVM_TDX_INIT_VM initialization, kvm->lock is acquired via the state
guard before handling the init ioctl:

arch/x86/kvm/vmx/tdx.c:tdx_vm_ioctl() {
	CLASS(tdx_vm_state_guard, guard)(kvm);
	if (IS_ERR(guard))
		return PTR_ERR(guard);

	switch (tdx_cmd.id) {
	case KVM_TDX_INIT_VM:
		r = tdx_td_init(kvm, &tdx_cmd);
	...
}

Then cpus_read_lock() is acquired inside __tdx_td_init() while kvm->lock
is held:

arch/x86/kvm/vmx/tdx.c:__tdx_td_init() {
	...
	if (!zalloc_cpumask_var(&packages, GFP_KERNEL))
		goto free_tdcs;

	cpus_read_lock();
	...
}

Similarly, it is acquired on the teardown path in tdx_mmu_release_hkid()
while kvm->lock is held:

arch/x86/kvm/vmx/tdx.c:tdx_mmu_release_hkid() {
	packages_allocated = zalloc_cpumask_var(&packages, GFP_KERNEL);
	targets_allocated = zalloc_cpumask_var(&targets, GFP_KERNEL);
	cpus_read_lock();
	...
}

The KVM guidelines explicitly state that cpus_read_lock() must be the
outermost lock. Could this cause an ABBA deadlock against other paths that
acquire cpus_read_lock() before taking kvm->lock, resulting in system hangs?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260903015113.93343-1-rick.p.edgecombe@intel.com?part=8

  reply	other threads:[~2026-09-03  2:14 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-03  1:51 [PATCH v10 00/11] Dynamic PAMT Rick Edgecombe
2026-09-03  1:51 ` [PATCH v10 01/11] x86/virt/tdx: Simplify PAMT layout calculation Rick Edgecombe
2026-09-03  1:51 ` [PATCH v10 02/11] x86/virt/tdx: Allocate page bitmap for Dynamic PAMT Rick Edgecombe
2026-09-03  1:51 ` [PATCH v10 03/11] x86/virt/tdx: Add __tdx_pamt_get/put() helpers Rick Edgecombe
2026-09-03 15:28   ` Dave Hansen
2026-09-03  1:51 ` [PATCH v10 04/11] x86/virt/tdx: Allocate refcounts for Dynamic PAMT memory Rick Edgecombe
2026-09-03 15:30   ` Dave Hansen
2026-09-03 18:33     ` Edgecombe, Rick P
2026-09-03  1:51 ` [PATCH v10 05/11] x86/virt/tdx: Handle multiple callers in tdx_pamt_get/put() Rick Edgecombe
2026-09-03  2:03   ` sashiko-bot
2026-09-03 23:16     ` Edgecombe, Rick P
2026-09-03  1:51 ` [PATCH v10 06/11] KVM: TDX: Allocate PAMT memory for TD and vCPU control structures Rick Edgecombe
2026-09-03  1:51 ` [PATCH v10 07/11] x86/virt/tdx: Add APIs to support Dynamic PAMT ops from KVM's fault path Rick Edgecombe
2026-09-03  1:51 ` [PATCH v10 08/11] KVM: TDX: Get/put PAMT pages when (un)mapping private memory Rick Edgecombe
2026-09-03  2:14   ` sashiko-bot [this message]
2026-09-03 22:44     ` Edgecombe, Rick P
2026-09-03  1:51 ` [PATCH v10 09/11] x86/virt/tdx: Enable Dynamic PAMT Rick Edgecombe
2026-09-03 15:38   ` Dave Hansen
2026-09-03  1:51 ` [PATCH v10 10/11] Documentation/x86: Add documentation for TDX's " Rick Edgecombe
2026-09-03 15:47   ` Dave Hansen
2026-09-03 19:31     ` Edgecombe, Rick P
2026-09-03 19:36       ` Dave Hansen
2026-09-03 20:39         ` Edgecombe, Rick P
2026-09-03 20:45           ` Dave Hansen
2026-09-03  1:51 ` [PATCH v10 11/11] x86/virt/tdx: Optimize tdx_pamt_get/put() Rick Edgecombe

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=20260903021405.0DA101F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=kvm@vger.kernel.org \
    --cc=rick.p.edgecombe@intel.com \
    --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.