[PATCH v5 4/6] x86/virt/tdx: Support DPAMT when adding memory for the extensions

From: Xu Yilun

Date: Tue Nov 10 2026 - 22:57:45 EST


The TDX module uses PAMT to track some state for private pages. The
memory for the extensions needs PAMT backing cause the TDX module
transitions it to private pages when accepting it.

The Dynamic PAMT (DPAMT) feature allows saving memory by allocating
4KB-level PAMT dynamically. The kernel must install DPAMT before adding
any 4KB pages to the TDX module. Although the memory for the extensions
is tens of megabytes and the kernel allocates it in a large chunk, the
TDX module accepts it in the form of an HPA array, which specifies each
page at 4KB granularity. Thus the kernel still needs to install DPAMT
for this memory, otherwise TDH.EXT.MEM.ADD would fail to execute.

That said, don't worry about bisectability cause the extensions can't be
enabled yet without a feature that uses them.

The kernel has helpers to install DPAMT for a 4KB page. Call
tdx_pamt_get() for each extension page before adding it to the TDX
module. Normally, these operations should not fail, and if they do,
intentionally keep the error handling as simple as before - leak all
pages, including the installed DPAMT.

The original changelog was written by hand. AI was used to help correct
grammatical errors and polish individual sentences for better
readability.

Signed-off-by: Xu Yilun <yilun.xu@xxxxxxxxxxxxxxx>
Reviewed-by: Kiryl Shutsemau (Meta) <kas@xxxxxxxxxx>
Reviewed-by: Rick Edgecombe <rick.p.edgecombe@xxxxxxxxx>
Reviewed-by: Tony Lindgren <tony.lindgren@xxxxxxxxxxxxxxx>
---
v5:
- Clarify that the bisectability won't be hurt
- Refactor the first 2 paragraphs.
- Collect Reviewed-by tags
- Better clarify the AI usage

v4:
- Explain in changelog that TDH.EXT.MEM.ADD won't work without this
patch when DPAMT is on by default. (Tony)
- Move this patch right after the one that implements TDH.EXT.MEM.ADD
- Collect Reviewed-by tags

v3:
- New patch
---
arch/x86/virt/vmx/tdx/tdx.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
index 865d8089d343..3440f1878978 100644
--- a/arch/x86/virt/vmx/tdx/tdx.c
+++ b/arch/x86/virt/vmx/tdx/tdx.c
@@ -1318,8 +1318,15 @@ static __init int tdx_ext_mem_setup(void)
struct page *chunk = page + added_pages;
unsigned int i;

- for (i = 0; i < chunk_pages; i++)
+ for (i = 0; i < chunk_pages; i++) {
+ ret = tdx_pamt_get(page_to_pfn(chunk + i), NULL);
+ if (ret) {
+ WARN(1, "DPAMT setup error for extensions, stranded all pages\n");
+ goto out_free_hpa_list;
+ }
+
hpa_list->phys[i] = page_to_phys(chunk + i);
+ }

ret = tdx_ext_mem_add(hpa_list, chunk_pages);
if (ret) {

--
2.25.1