From: Xu Yilun <yilun.xu@linux.intel.com>
To: x86@kernel.org, linux-coco@lists.linux.dev,
linux-kernel@vger.kernel.org
Cc: Kiryl Shutsemau <kas@kernel.org>,
Rick Edgecombe <rick.p.edgecombe@intel.com>,
Dave Hansen <dave.hansen@linux.intel.com>,
dave.hansen@intel.com, kvm@vger.kernel.org, yilun.xu@intel.com,
yilun.xu@linux.intel.com, xiaoyao.li@intel.com,
sohil.mehta@intel.com, adrian.hunter@intel.com,
kishen.maloor@intel.com, tony.lindgren@linux.intel.com,
peter.fang@intel.com, baolu.lu@linux.intel.com,
zhenzhong.duan@intel.com, chao.gao@intel.com,
artem.bityutskiy@linux.intel.com, nik.borisov@suse.com
Subject: [PATCH v3 1/6] x86/virt/tdx: Move TDH.SYS.CONFIG operations into a wrapper
Date: Tue, 06 Oct 2026 01:41:45 +0800 [thread overview]
Message-ID: <20261006-tdx-module-ext-v3-1-db52cb05b918@linux.intel.com> (raw)
In-Reply-To: <20261006-tdx-module-ext-v3-0-db52cb05b918@linux.intel.com>
In Linux, SEAMCALL wrappers are introduced to avoid broad SEAMCALL
access by exposing only a selection of SEAMCALL leafs, but also to
abstract the SEAMCALL register ABIs. The abstraction improves
readability and reuse for SEAMCALL leafs that are called multiple times.
Some SEAMCALL leafs are not explicitly wrapped because the level of TDX
ABI details needed to perform the call is low enough to flow well with
the calling code.
For some of the currently unwrapped SEAMCALL leafs, the TDX architecture
has evolved the ABI to introduce new leaf versions. The host can select
the version to call based on what is supported by the loaded TDX module.
When future kernel implements this version selection, more ABI details
will leak into the surrounding caller code, which decreases the
readability of the caller logic. To keep the ABI details contained, move
the SEAMCALL leaf that will need version selection into a wrapper.
When defining the wrapper, the cleanest separation would be to have
kernel data types for the SEAMCALL wrapper arguments, and have them
marshaled into SEAMCALL leaf ABI types (often u64s) inside the wrapper.
This works for many SEAMCALL leafs but becomes cumbersome when the
register ABI type is a physical address which points to a buffer for an
in-memory ABI. If the SEAMCALL wrapper only accepts kernel data types,
it may need duplicate buffer allocation and copies to match the
in-memory ABI. Another solution is to define a named helper structure
that mirrors the in-memory ABI, populate it in a separate flow, then
pass it to the SEAMCALL wrapper. struct seamldr_params is an existing
example of this pattern.
TDH.SYS.CONFIG requires a list of TDMR information in the form of a PA
array. The PA array is the in-memory ABI. Create a structure for the PA
array, use it as the argument when creating the wrapper for
TDH.SYS.CONFIG.
For readability, adjust a bit of the existing PA array size calculation:
use the new PA array structure's element type instead of hardcoding u64.
Signed-off-by: Xu Yilun <yilun.xu@linux.intel.com>
Reviewed-by: Nikolay Borisov <nik.borisov@suse.com>
Reviewed-by: Tony Lindgren <tony.lindgren@linux.intel.com>
---
v3:
- sizeof(tdmr_pa_array->phys[0]) instead of sizeof(u64) (Rick)
- Re-phrase the code comments for struct tdmr_info_pa_array (Tony)
- Refactor the changelog
- Collect Reviewed-by tags
v2:
- Remove TDH.SYS.UPDATE wrapper (Dave & Rick)
- Talk about the handling of in-memory ABIs for SEAMCALL wrappers
(Rick)
- Refactor the entire changelog according to Rick's suggestion (Rick)
- Add code comment for struct tdmr_info_pa_array (AI nitpicker)
- Use kernel data type for nr_tdmr_pa parameter (AI nitpicker)
v1:
- This patch is split out from the last series (Rick)
---
arch/x86/virt/vmx/tdx/tdx.c | 46 +++++++++++++++++++++++++++++++--------------
1 file changed, 32 insertions(+), 14 deletions(-)
diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
index 96ced0494b68..b099aa4056f5 100644
--- a/arch/x86/virt/vmx/tdx/tdx.c
+++ b/arch/x86/virt/vmx/tdx/tdx.c
@@ -1033,11 +1033,36 @@ static __init int construct_tdmrs(struct list_head *tmb_list,
#define TDX_SYS_CONFIG_DYNAMIC_PAMT BIT(16)
+/*
+ * TDX module in-memory ABI to specify the TD Memory Regions (TDMRs) and their
+ * associated PAMT memory. An array of HPAs, each element points to a
+ * TDMR_INFO, see struct tdmr_info.
+ */
+struct tdmr_info_pa_array {
+ DECLARE_FLEX_ARRAY(u64, phys);
+};
+
+static __init int tdx_sys_config(struct tdmr_info_pa_array *tdmr_pa_array,
+ unsigned int nr_tdmr_pa, u64 global_keyid)
+{
+ struct tdx_module_args args = {
+ .rcx = __pa(tdmr_pa_array),
+ .rdx = nr_tdmr_pa,
+ .r8 = global_keyid,
+ };
+
+ if (tdx_supports_dynamic_pamt(&tdx_sysinfo)) {
+ pr_info("Enable Dynamic PAMT\n");
+ args.r8 |= TDX_SYS_CONFIG_DYNAMIC_PAMT;
+ }
+
+ return seamcall_prerr(TDH_SYS_CONFIG, &args);
+}
+
static __init int config_tdx_module(struct tdmr_info_list *tdmr_list,
u64 global_keyid)
{
- struct tdx_module_args args = {};
- u64 *tdmr_pa_array;
+ struct tdmr_info_pa_array *tdmr_pa_array;
size_t array_sz;
int i, ret;
@@ -1046,7 +1071,8 @@ static __init int config_tdx_module(struct tdmr_info_list *tdmr_list,
* addresses of each TDMR. The array itself also has certain
* alignment requirement.
*/
- array_sz = tdmr_list->nr_consumed_tdmrs * sizeof(u64);
+ array_sz = tdmr_list->nr_consumed_tdmrs *
+ sizeof(tdmr_pa_array->phys[0]);
array_sz = roundup_pow_of_two(array_sz);
if (array_sz < TDMR_INFO_PA_ARRAY_ALIGNMENT)
array_sz = TDMR_INFO_PA_ARRAY_ALIGNMENT;
@@ -1056,18 +1082,10 @@ static __init int config_tdx_module(struct tdmr_info_list *tdmr_list,
return -ENOMEM;
for (i = 0; i < tdmr_list->nr_consumed_tdmrs; i++)
- tdmr_pa_array[i] = __pa(tdmr_entry(tdmr_list, i));
-
- args.rcx = __pa(tdmr_pa_array);
- args.rdx = tdmr_list->nr_consumed_tdmrs;
- args.r8 = global_keyid;
-
- if (tdx_supports_dynamic_pamt(&tdx_sysinfo)) {
- pr_info("Enable Dynamic PAMT\n");
- args.r8 |= TDX_SYS_CONFIG_DYNAMIC_PAMT;
- }
+ tdmr_pa_array->phys[i] = __pa(tdmr_entry(tdmr_list, i));
- ret = seamcall_prerr(TDH_SYS_CONFIG, &args);
+ ret = tdx_sys_config(tdmr_pa_array, tdmr_list->nr_consumed_tdmrs,
+ global_keyid);
/* Free the array as it is not required anymore. */
kfree(tdmr_pa_array);
--
2.25.1
next prev parent reply other threads:[~2026-10-05 17:45 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-05 17:41 [PATCH v3 0/6] Enable TDX module extensions Xu Yilun
2026-10-05 17:41 ` Xu Yilun [this message]
2026-10-05 17:41 ` [PATCH v3 2/6] x86/virt/tdx: Configure add-on features on TDX module init Xu Yilun
2026-10-05 17:41 ` [PATCH v3 3/6] x86/virt/tdx: Add extra memory to TDX module for the extensions Xu Yilun
2026-10-05 17:41 ` [PATCH v3 4/6] x86/virt/tdx: Make TDX module initialize " Xu Yilun
2026-10-05 17:41 ` [PATCH v3 5/6] x86/virt/tdx: Re-initialize the extensions on runtime TDX module update Xu Yilun
2026-10-06 4:32 ` Tony Lindgren
2026-10-05 17:41 ` [PATCH v3 6/6] x86/virt/tdx: Support DPAMT when adding memory for the extensions Xu Yilun
2026-10-06 4:36 ` Tony Lindgren
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=20261006-tdx-module-ext-v3-1-db52cb05b918@linux.intel.com \
--to=yilun.xu@linux.intel.com \
--cc=adrian.hunter@intel.com \
--cc=artem.bityutskiy@linux.intel.com \
--cc=baolu.lu@linux.intel.com \
--cc=chao.gao@intel.com \
--cc=dave.hansen@intel.com \
--cc=dave.hansen@linux.intel.com \
--cc=kas@kernel.org \
--cc=kishen.maloor@intel.com \
--cc=kvm@vger.kernel.org \
--cc=linux-coco@lists.linux.dev \
--cc=linux-kernel@vger.kernel.org \
--cc=nik.borisov@suse.com \
--cc=peter.fang@intel.com \
--cc=rick.p.edgecombe@intel.com \
--cc=sohil.mehta@intel.com \
--cc=tony.lindgren@linux.intel.com \
--cc=x86@kernel.org \
--cc=xiaoyao.li@intel.com \
--cc=yilun.xu@intel.com \
--cc=zhenzhong.duan@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®