[PATCH v4 5/6] x86/virt/tdx: Make TDX module initialize the extensions
From: Xu Yilun
Date: Tue Oct 13 2026 - 12:52:33 EST
TDX module extensions use kernel-gifted memory for their execution
environment to serve SEAMCALL leafs. Several add-on features depend on
the extensions to execute their SEAMCALL leafs.
After providing all required memory to the TDX module, initialize TDX
module extensions via TDH.EXT.INIT. This process takes on the order of
100's of milliseconds, during which the TDX module loads its internal
extension image into this memory and builds the execution environment.
Once initialized, those add-on features can use their SEAMCALL leafs
normally.
AI was used under supervision to review code and workshop logs.
Signed-off-by: Xu Yilun <yilun.xu@xxxxxxxxxxxxxxx>
Reviewed-by: Xiaoyao Li <xiaoyao.li@xxxxxxxxx>
Reviewed-by: Tony Lindgren <tony.lindgren@xxxxxxxxxxxxxxx>
Reviewed-by: Adrian Hunter <adrian.hunter@xxxxxxxxx>
Reviewed-by: Kiryl Shutsemau (Meta) <kas@xxxxxxxxxx>
Reviewed-by: Rick Edgecombe <rick.p.edgecombe@xxxxxxxxx>
---
v4:
- Specify what TDH.EXT.INIT is doing in the changelog (Rick)
- Collect Reviewed-by tags
v1:
- Fix return value for SEAMCALL wrappers (Chao)
- Print SEAMCALL error code for SEAMCALL wrappers (Xiaoyao)
- Changelog & code comments
---
arch/x86/virt/vmx/tdx/tdx.h | 1 +
arch/x86/virt/vmx/tdx/tdx.c | 25 ++++++++++++++++++++++++-
2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h
index 2adc5d31d258..cac0a5abbff1 100644
--- a/arch/x86/virt/vmx/tdx/tdx.h
+++ b/arch/x86/virt/vmx/tdx/tdx.h
@@ -50,6 +50,7 @@
#define TDH_SYS_UPDATE 53
#define TDH_PHYMEM_PAMT_ADD 58
#define TDH_PHYMEM_PAMT_REMOVE 59
+#define TDH_EXT_INIT 60
#define TDH_EXT_MEM_ADD 61
#define TDH_SYS_DISABLE 69
diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
index 4908add631fa..f1cc0422d129 100644
--- a/arch/x86/virt/vmx/tdx/tdx.c
+++ b/arch/x86/virt/vmx/tdx/tdx.c
@@ -1353,12 +1353,35 @@ static __init int tdx_ext_mem_setup(void)
return ret;
}
+static __init int tdx_ext_init(void)
+{
+ struct tdx_module_args args = {};
+ u64 ret;
+
+ do {
+ ret = seamcall(TDH_EXT_INIT, &args);
+ } while (ret == TDX_INTERRUPTED_RESUMABLE);
+
+ if (ret != TDX_SUCCESS) {
+ pr_err("TDH.EXT.INIT failed: 0x%016llx\n", ret);
+ return -EIO;
+ }
+
+ return 0;
+}
+
static __init int init_tdx_module_extensions(void)
{
+ int ret;
+
if (!(tdx_sysinfo.features.tdx_features0 & TDX_FEATURES0_EXT))
return 0;
- return tdx_ext_mem_setup();
+ ret = tdx_ext_mem_setup();
+ if (ret)
+ return ret;
+
+ return tdx_ext_init();
}
static __init int init_tdx_module(void)
--
2.25.1