Re: [PATCH 04/15] x86/virt/tdx: Enable the Extensions right after basic TDX Module init

From: Xiaoyao Li

Date: Mon May 25 2026 - 04:08:00 EST


On 5/22/2026 11:41 AM, Xu Yilun wrote:
The detailed initialization flow for TDX Module Extensions has been
fully implemented. Enable the flow after basic TDX Module
initialization.

Theoretically, the Extensions doesn't need to be enabled right after
basic TDX initialization. It could be enabled right before the first
Extension SEAMCALL is issued. That would save or postpone memory usage.
But it isn't worth the complexity, the needs for the Extensions are vast
but the savings are little for a typical TDX capable system (about
0.001% of memory). So the Linux decision is to just enable it along with
the basic TDX.



Note that the Extensions initialization flow will still not start if no
add-on features require Extensions. The enabling of add-on features will
be in later patches. Until then, the system hasn't consumed extra memory.

based on the above, how about putting this patch before patch 02 and 03? so that we can eliminate the churn of add "__init" and the "__maybe_unused " in patch 02.

To be more safer, we can even make the code as

static bool tdx_supports_extension(void)
{
/* To be enabled when kernel is ready. */
return false;
}

static __init int init_tdx_ext(void)
{
if (!tdx_supports_extension())
return 0;

/* No feature requires TDX Module Extensions. */
if (!tdx_sysinfo.ext.ext_required)
return 0;
}

and after all the pieces implemented, we can change tdx_supports_extension() to

static bool tdx_supports_extension(void)
{
/* To be enabled when kernel is ready. */
return !!(tdx_sysinfo.features.tdx_features0 & TDX_FEATURES0_EXT);
}

Signed-off-by: Xu Yilun <yilun.xu@xxxxxxxxxxxxxxx>
---
arch/x86/virt/vmx/tdx/tdx.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
index ff2b96c20d2b..dad5ec642723 100644
--- a/arch/x86/virt/vmx/tdx/tdx.c
+++ b/arch/x86/virt/vmx/tdx/tdx.c
@@ -1180,7 +1180,7 @@ static __init int init_tdmrs(struct tdmr_info_list *tdmr_list)
return 0;
}
-static void tdx_clflush_hpa_list(struct page *root, unsigned int nr_pages)
+static __init void tdx_clflush_hpa_list(struct page *root, unsigned int nr_pages)
{
u64 *entries = page_to_virt(root);
int i;
@@ -1193,7 +1193,7 @@ static void tdx_clflush_hpa_list(struct page *root, unsigned int nr_pages)
#define HPA_LIST_INFO_PFN GENMASK_U64(51, 12)
#define HPA_LIST_INFO_LAST_ENTRY GENMASK_U64(63, 55)
-static u64 to_hpa_list_info(struct page *root, unsigned int nr_pages)
+static __init u64 to_hpa_list_info(struct page *root, unsigned int nr_pages)
{
return FIELD_PREP(HPA_LIST_INFO_FIRST_ENTRY, 0) |
FIELD_PREP(HPA_LIST_INFO_PFN, page_to_pfn(root)) |
@@ -1201,7 +1201,7 @@ static u64 to_hpa_list_info(struct page *root, unsigned int nr_pages)
}
/* Initialize the TDX Module Extensions then Extension-SEAMCALLs can be used */
-static int tdx_ext_init(void)
+static __init int tdx_ext_init(void)
{
struct tdx_module_args args = {};
u64 r;
@@ -1216,7 +1216,7 @@ static int tdx_ext_init(void)
return 0;
}
-static int tdx_ext_mem_add(struct page *root, unsigned int nr_pages)
+static __init int tdx_ext_mem_add(struct page *root, unsigned int nr_pages)
{
struct tdx_module_args args = {
.rcx = to_hpa_list_info(root, nr_pages),
@@ -1240,7 +1240,7 @@ static int tdx_ext_mem_add(struct page *root, unsigned int nr_pages)
return 0;
}
-static int tdx_ext_mem_setup(void)
+static __init int tdx_ext_mem_setup(void)
{
unsigned int nr_pages;
struct page *page;
@@ -1301,7 +1301,7 @@ static int tdx_ext_mem_setup(void)
return ret;
}
-static int __maybe_unused init_tdx_ext(void)
+static __init int init_tdx_ext(void)
{
int ret;
@@ -1373,6 +1373,10 @@ static __init int init_tdx_module(void)
if (ret)
goto err_reset_pamts;
+ ret = init_tdx_ext();
+ if (ret)
+ goto err_reset_pamts;
+
pr_info("%lu KB allocated for PAMT\n", tdmrs_count_pamt_kb(&tdx_tdmr_list));
out_put_tdxmem: