From: sashiko-bot@kernel.org
To: "Rick Edgecombe" <rick.p.edgecombe@intel.com>
Cc: kvm@vger.kernel.org
Subject: Re: [PATCH v11 08/11] KVM: TDX: Get/put PAMT pages when (un)mapping private memory
Date: Fri, 04 Sep 2026 22:18:10 +0000 [thread overview]
Message-ID: <20260904221810.BE6111F00A3D@smtp.kernel.org> (raw)
In-Reply-To: <20260904215841.303070-9-rick.p.edgecombe@intel.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] The retry loop in `kvm_tdp_mmu_map_private_pfn` fails to top up memory caches on `RET_PF_RETRY`, leading to a permanent infinite loop when `pamt_cache` is depleted.
--
commit 346b744d7586de76e5cf17e0acaaeca78c9eea73
Author: Kiryl Shutsemau <kas@kernel.org>
KVM: TDX: Get/put PAMT pages when (un)mapping private memory
This commit adds Dynamic PAMT support to KVM's S-EPT MMU by getting PAMT
pages when adding guest memory and putting them when removing guest memory.
It uses per-vCPU PAMT caches topped up via a new topup_external_cache op.
> diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
> index 22cf222d30339..48e4cf91b77f6 100644
> --- a/arch/x86/kvm/mmu/mmu.c
> +++ b/arch/x86/kvm/mmu/mmu.c
> @@ -614,6 +614,10 @@ static int mmu_topup_memory_caches(struct kvm_vcpu *vcpu, bool maybe_indirect)
> PT64_ROOT_MAX_LEVEL);
> if (r)
> return r;
> +
> + r = kvm_x86_call(topup_external_cache)(vcpu, PT64_ROOT_MAX_LEVEL);
> + if (r)
> + return r;
> }
[Severity: High]
Does this code guarantee eventual cache exhaustion during page faults?
When a host userspace process initiates KVM_TDX_INIT_MEM_REGION, it calls
kvm_tdp_mmu_map_private_pfn() in arch/x86/kvm/mmu/mmu.c. In that function,
mmu_topup_memory_caches() is located outside the retry loop:
r = mmu_topup_memory_caches(vcpu, false);
if (r)
return r;
do {
if (signal_pending(current))
return -EINTR;
if (kvm_test_request(KVM_REQ_VM_DEAD, vcpu))
return -EIO;
cond_resched();
guard(read_lock)(&kvm->mmu_lock);
r = kvm_tdp_mmu_map(vcpu, &fault);
} while (r == RET_PF_RETRY);
During kvm_tdp_mmu_map(), if tdh_mem_page_add() or tdh_mem_sept_add()
encounters TDX_OPERAND_BUSY due to contention, tdx_pamt_put() frees the
just-allocated PAMT page to the generic kernel buddy allocator instead of
returning it to the cache.
kvm_tdp_mmu_map() then receives -EBUSY from tdp_mmu_set_spte_atomic() and
translates it to RET_PF_RETRY. Because the topup is outside the loop, the
pamt_cache is never replenished upon retry.
[ ... ]
> 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
[ ... ]
> @@ -1701,8 +1728,13 @@ static int tdx_sept_map_nonleaf_spte(struct kvm *kvm, gfn_t gfn,
> static int tdx_sept_map_leaf_spte(struct kvm *kvm, gfn_t gfn, enum pg_level level,
> u64 new_spte)
> {
> + struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
> struct kvm_tdx *kvm_tdx = to_kvm_tdx(kvm);
> kvm_pfn_t pfn = spte_to_pfn(new_spte);
> + int ret;
> +
> + if (KVM_BUG_ON(!vcpu, kvm))
> + return -EIO;
>
> /* TODO: handle large pages. */
> if (KVM_BUG_ON(level != PG_LEVEL_4K, kvm))
> @@ -1710,6 +1742,10 @@ static int tdx_sept_map_leaf_spte(struct kvm *kvm, gfn_t gfn, enum pg_level leve
>
> WARN_ON_ONCE((new_spte & VMX_EPT_RWX_MASK) != VMX_EPT_RWX_MASK);
>
> + ret = tdx_pamt_get(pfn, &to_tdx(vcpu)->pamt_cache);
> + if (KVM_BUG_ON(ret, kvm))
> + return ret;
[Severity: High]
Does this failure path cause a permanent infinite loop?
After the cache is completely drained due to the missing topups on retry,
alloc_dpamt_page() in arch/x86/virt/vmx/tdx/tdx.c returns NULL because it
lacks a GFP_ATOMIC fallback for a non-NULL cache:
static struct page *alloc_dpamt_page(struct tdx_pamt_cache *cache)
{
if (cache)
return tdx_alloc_page_pamt_cache(cache);
return alloc_page(GFP_KERNEL_ACCOUNT);
}
Consequently, tdx_pamt_get() fails with -ENOMEM. This is subsequently treated
as a retryable error by tdp_mmu_map_handle_target_level() which returns
RET_PF_RETRY.
This causes the host kernel thread executing the page population ioctl to
blindly repeat forever, creating a viable denial of service vector for
unprivileged host userspace.
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260904215841.303070-1-rick.p.edgecombe@intel.com?part=8
next prev parent reply other threads:[~2026-09-04 22:18 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-04 21:58 [PATCH v11 00/11] Dynamic PAMT Rick Edgecombe
2026-09-04 21:58 ` [PATCH v11 01/11] x86/virt/tdx: Simplify PAMT layout calculation Rick Edgecombe
2026-09-04 21:58 ` [PATCH v11 02/11] x86/virt/tdx: Allocate page bitmap for Dynamic PAMT Rick Edgecombe
2026-09-04 21:58 ` [PATCH v11 03/11] x86/virt/tdx: Add __tdx_pamt_get/put() helpers Rick Edgecombe
2026-09-04 21:58 ` [PATCH v11 04/11] x86/virt/tdx: Allocate refcounts for Dynamic PAMT memory Rick Edgecombe
2026-09-04 21:58 ` [PATCH v11 05/11] x86/virt/tdx: Handle multiple callers in tdx_pamt_get/put() Rick Edgecombe
2026-09-04 21:58 ` [PATCH v11 06/11] KVM: TDX: Allocate PAMT memory for TD and vCPU control structures Rick Edgecombe
2026-09-04 21:58 ` [PATCH v11 07/11] x86/virt/tdx: Add APIs to support Dynamic PAMT ops from KVM's fault path Rick Edgecombe
2026-09-04 21:58 ` [PATCH v11 08/11] KVM: TDX: Get/put PAMT pages when (un)mapping private memory Rick Edgecombe
2026-09-04 22:18 ` sashiko-bot [this message]
2026-09-04 21:58 ` [PATCH v11 09/11] x86/virt/tdx: Enable Dynamic PAMT Rick Edgecombe
2026-09-04 22:11 ` sashiko-bot
2026-09-04 21:58 ` [PATCH v11 10/11] Documentation/x86: Add documentation for TDX's " Rick Edgecombe
2026-09-04 21:58 ` [PATCH v11 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=20260904221810.BE6111F00A3D@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.