Re: [PATCH v2 06/17] x86/virt/tdx: Re-initialize the extensions on runtime TDX module update

From: Xu Yilun

Date: Thu Jul 30 2026 - 07:20:58 EST


On Mon, Jul 27, 2026 at 06:37:39PM +0000, Edgecombe, Rick P wrote:
> On Mon, 2026-06-29 at 16:12 +0800, Chao Gao wrote:
> > Will tdx_ext_init() return an error if more memory is needed?
> >
> > If yes, we can leave this check to the module. And with ext_required
> > removed (per my earlier comment), this function simplifies to:
> >
> > int update_tdx_module_extensions(void)
> > {
> > if (!(tdx_sysinfo.features.tdx_features0 & TDX_FEATURES0_EXT))
> > return 0;
> >
> > return tdx_ext_init();
> > }
>
> Oh, it can be simplified and not share so much with the init side. Please ignore
> my other question.

It can't be simplified like that. If extensions are supported but no
extension feature is configured at boot up time. tdx_ext_init() would
fail and the runtime update failed.

I've found issue in my implementation. If extensions are required at
boot up time but somehow not required after update, the code just skip
tdx_ext_init() and the update succeed, but after that the extension
features will break.

IOW, we should not update the metadata, we should follow the boot up
time metadata to ensure no feature changes. We should store the
extension metadata in global tdx_sysinfo, and that eliminate the
duplicate code.

----8<----

diff --git a/arch/x86/include/asm/tdx_global_metadata.h b/arch/x86/include/asm/tdx_global_metadata.h
index b3442b7c88bb..43b8761c0854 100644
--- a/arch/x86/include/asm/tdx_global_metadata.h
+++ b/arch/x86/include/asm/tdx_global_metadata.h
@@ -44,17 +44,18 @@ struct tdx_sys_info_handoff {
u16 module_hv;
};

+struct tdx_sys_info_ext {
+ u32 memory_pool_required_pages;
+ bool ext_required;
+};
+
struct tdx_sys_info {
struct tdx_sys_info_version version;
struct tdx_sys_info_features features;
struct tdx_sys_info_tdmr tdmr;
struct tdx_sys_info_td_ctrl td_ctrl;
struct tdx_sys_info_td_conf td_conf;
-};
-
-struct tdx_sys_info_ext {
- u32 memory_pool_required_pages;
- bool ext_required;
+ struct tdx_sys_info_ext ext;
};

#endif
diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
index f03141f51840..90fbd22acb5e 100644
--- a/arch/x86/virt/vmx/tdx/tdx.c
+++ b/arch/x86/virt/vmx/tdx/tdx.c
@@ -1304,13 +1304,13 @@ static int tdx_ext_init(void)

static __init int init_tdx_module_extensions(void)
{
- struct tdx_sys_info_ext sysinfo_ext;
+ struct tdx_sys_info_ext *sysinfo_ext = &tdx_sysinfo.ext;
int ret;

if (!(tdx_sysinfo.features.tdx_features0 & TDX_FEATURES0_EXT))
return 0;

- ret = get_tdx_sys_info_ext(&sysinfo_ext);
+ ret = get_tdx_sys_info_ext(sysinfo_ext);
if (ret)
return ret;

@@ -1319,10 +1319,10 @@ static __init int init_tdx_module_extensions(void)
* extensions are configured via TDH.SYS.CONFIG. If none, skip the
* initialization.
*/
- if (!sysinfo_ext.ext_required)
+ if (!sysinfo_ext->ext_required)
return 0;

- ret = tdx_ext_mem_setup(sysinfo_ext.memory_pool_required_pages);
+ ret = tdx_ext_mem_setup(sysinfo_ext->memory_pool_required_pages);
if (ret)
return ret;

@@ -1330,23 +1330,14 @@ static __init int init_tdx_module_extensions(void)
}

/*
- * Mostly the same flow as init_tdx_module_extensions(), but won't check and
- * add more memory. Let the extensions re-initialization fail when more memory
- * is actually needed.
+ * Don't update the extensions metadata, just follow the requirement originated
+ * on TDX module initialization. Let the extensions re-initialization fail when
+ * more memory is needed, or when the ext_required is accidentally flipped after
+ * update.
*/
static int update_tdx_module_extensions(void)
{
- struct tdx_sys_info_ext sysinfo_ext;
- int ret;
-
- if (!(tdx_sysinfo.features.tdx_features0 & TDX_FEATURES0_EXT))
- return 0;
-
- ret = get_tdx_sys_info_ext(&sysinfo_ext);
- if (ret)
- return ret;
-
- if (!sysinfo_ext.ext_required)
+ if (!tdx_sysinfo.ext.ext_required)
return 0;

return tdx_ext_init();