All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chao Gao <chao.gao@intel.com>
To: "Edgecombe, Rick P" <rick.p.edgecombe@intel.com>
Cc: "kvm@vger.kernel.org" <kvm@vger.kernel.org>,
	"linux-coco@lists.linux.dev" <linux-coco@lists.linux.dev>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"Van De Ven, Arjan" <arjan.van.de.ven@intel.com>,
	"Xu, Yilun" <yilun.xu@intel.com>,
	"dave.hansen@linux.intel.com" <dave.hansen@linux.intel.com>,
	"x86@kernel.org" <x86@kernel.org>,
	"kas@kernel.org" <kas@kernel.org>,
	"hpa@zytor.com" <hpa@zytor.com>,
	"mingo@redhat.com" <mingo@redhat.com>,
	"bp@alien8.de" <bp@alien8.de>,
	"tglx@kernel.org" <tglx@kernel.org>
Subject: Re: [RFC PATCH v1 2/3] x86/virt/seamldr: Support large TDX module binaries
Date: Wed, 4 Nov 2026 21:12:31 +0800	[thread overview]
Message-ID: <ausvP4vrZ3PiXFT8@intel.com> (raw)
In-Reply-To: <aumh_q8olQPwH0pe@intel.com>

On Tue, Nov 03, 2026 at 04:57:44PM +0800, Chao Gao wrote:
>Most of the complexity came from sizing the allocation exactly. If we
>over-allocate a little instead, the size calculation becomes much
>simpler. Making module_pages_pa_list[] a flexible array also removes
>the need to treat its entries differently from those in the chain
>pages. And linking the pages while filling in the module page addresses
>removes the separate linking loop.

After an offline chat, Rick suggested going one step further. Instead
of sizing the allocation from header->module_nr_pages at all, make
module_pages_pa_list[] a fixed size that fits any module in practice,
and let the existing header check reject anything bigger.

That removes the size calculation entirely, and the prep patch that
moved the allocation after header validation is no longer needed. The
updated patch is below.

commit f7f4359f4106df373449c0cf821f098453e36b9c
Author: Chao Gao <chao.gao@intel.com>
Date:   Tue Sep 29 23:20:35 2026 -0700

    x86/virt/seamldr: Support large TDX module binaries
    
    The module binary is handed to P-SEAMLDR as a list of page physical
    addresses in 'struct seamldr_params'. The list has 496 entries, which
    caps a module at 496 pages.
    
    TDX modules are gaining features and are about to outgrow that limit.
    
    The P-SEAMLDR ABI was extended to chain the list across 4KB pages. For
    a module over 495 pages, the last of the 496 entries points to another
    page of entries instead of to a module page. The last entry of that
    page can point to yet another page, and so on, until every module page
    is listed.
    
    Grow module_pages_pa_list[] so that 'struct seamldr_params' spans
    multiple pages (16 for now), and use the extra pages as the chained
    pages. The last entry of each page then points to the entry right after
    it, which starts the next page. These link entries do not hold module
    pages, so leave them out of the maximum module page count.
    
    The 16-page size is somewhat arbitrary. It fits modules of up to about
    32MB, far above the roughly 2MB of current modules. It wastes 60KB for
    today's modules, which is fine because the memory is freed right after
    the update.
    
    Use a fixed size for module_pages_pa_list[] instead of sizing it to
    each module. Sizing it per module would mean either moving the
    allocation after the image header is validated, or allocating from an
    unvalidated page count. Either way it is more code churn.
    
    Do not query P-SEAMLDR for chaining support. Userspace selects the update
    image and is responsible for ensuring the module is compatible with
    P-SEAMLDR.
    
    Thanks to Yilun for the idea of allocating the chain pages together
    with 'struct seamldr_params'.
    
    AI was used under supervision to review code and workshop logs.
    
    Signed-off-by: Chao Gao <chao.gao@intel.com>
    ---
    v2:
     - Make 'struct seamldr_params' a fixed 16 pages instead of sizing it
       to each module, capping modules at about 32MB. [Rick]
     - Drop the patch that moved the allocation after image validation. [Rick]

diff --git a/arch/x86/virt/vmx/tdx/seamldr.c b/arch/x86/virt/vmx/tdx/seamldr.c
index b1137ca6150d..087bdf10a9a7 100644
--- a/arch/x86/virt/vmx/tdx/seamldr.c
+++ b/arch/x86/virt/vmx/tdx/seamldr.c
@@ -24,7 +24,18 @@
 #define P_SEAMLDR_INFO			0x8000000000000000
 #define P_SEAMLDR_INSTALL		0x8000000000000001
 
-#define SEAMLDR_MAX_NR_MODULE_PAGES	496
+/*
+ * module_pages_pa_list[] spans multiple pages. The last entry of each
+ * page points to the next page and does not hold a module page, so the
+ * maximum number of module pages is the array size minus one entry per
+ * page.
+ *
+ * SEAMLDR_PARAMS_NR_PAGES is somewhat arbitrary. It allows modules of
+ * up to about 32MB. Increase it if modules outgrow that.
+ */
+#define SEAMLDR_PARAMS_NR_PAGES		16
+#define SEAMLDR_NR_MODULE_PA_ENTRIES	(496 + 512 * (SEAMLDR_PARAMS_NR_PAGES - 1))
+#define SEAMLDR_MAX_NR_MODULE_PAGES	(SEAMLDR_NR_MODULE_PA_ENTRIES - SEAMLDR_PARAMS_NR_PAGES)
 #define SEAMLDR_MAX_NR_SIG_PAGES	1
 
 /*
@@ -48,10 +59,10 @@ struct seamldr_params {
 	u64	sigstruct_pages_pa_list[SEAMLDR_MAX_NR_SIG_PAGES];
 	u8	reserved[104];
 	u64	module_nr_pages;
-	u64	module_pages_pa_list[SEAMLDR_MAX_NR_MODULE_PAGES];
+	u64	module_pages_pa_list[SEAMLDR_NR_MODULE_PA_ENTRIES];
 } __packed;
 
-static_assert(sizeof(struct seamldr_params) == 4096);
+static_assert(sizeof(struct seamldr_params) == SEAMLDR_PARAMS_NR_PAGES * PAGE_SIZE);
 
 /*
  * Serialize P-SEAMLDR calls since the hardware only allows a single CPU to
@@ -129,17 +140,24 @@ struct tdx_image {
 /*
  * Given a vmalloc() allocation, write all of the backing physical
  * addresses to pa_list[]. Caller guarantees that the array is big
- * enough.
+ * enough. If pa_list[] spans multiple pages, point the last entry
+ * of each page to the next page.
  */
 static void populate_pa_list(u64 *pa_list, const u8 *vmalloc_addr, u32 vmalloc_len_pages)
 {
-	int i;
+	int i, j;
 
-	for (i = 0; i < vmalloc_len_pages; i++) {
+	for (i = 0, j = 0; i < vmalloc_len_pages; i++) {
 		unsigned long offset = i * PAGE_SIZE;
 		unsigned long pfn = vmalloc_to_pfn(&vmalloc_addr[offset]);
 
-		pa_list[i] = pfn << PAGE_SHIFT;
+		if (PAGE_ALIGNED(&pa_list[j + 1])) {
+			pa_list[j] = __pa(&pa_list[j + 1]);
+			j++;
+		}
+
+		pa_list[j] = pfn << PAGE_SHIFT;
+		j++;
 	}
 }
 


  reply	other threads:[~2026-11-04 13:14 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-30  8:52 [RFC PATCH v1 0/3] TDX: P-SEAMLDR: Support large TDX modules and sigstructs Chao Gao
2026-10-30  8:52 ` [RFC PATCH v1 1/3] x86/virt/seamldr: Allocate 'struct seamldr_params' after image validation Chao Gao
2026-11-02 23:58   ` Edgecombe, Rick P
2026-11-03  6:30     ` Chao Gao
2026-11-03 18:55       ` Edgecombe, Rick P
2026-10-30  8:52 ` [RFC PATCH v1 2/3] x86/virt/seamldr: Support large TDX module binaries Chao Gao
2026-11-03  0:35   ` Edgecombe, Rick P
2026-11-03  8:57     ` Chao Gao
2026-11-04 13:12       ` Chao Gao [this message]
2026-10-30  8:53 ` [RFC PATCH v1 3/3] x86/virt/seamldr: Support multiple sigstruct pages Chao Gao
2026-11-02 23:50 ` [RFC PATCH v1 0/3] TDX: P-SEAMLDR: Support large TDX modules and sigstructs Edgecombe, Rick P

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=ausvP4vrZ3PiXFT8@intel.com \
    --to=chao.gao@intel.com \
    --cc=arjan.van.de.ven@intel.com \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=hpa@zytor.com \
    --cc=kas@kernel.org \
    --cc=kvm@vger.kernel.org \
    --cc=linux-coco@lists.linux.dev \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=rick.p.edgecombe@intel.com \
    --cc=tglx@kernel.org \
    --cc=x86@kernel.org \
    --cc=yilun.xu@intel.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.