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

Xu Yilun <[email protected]> Fri, 31 Jul 2026 00:01:04 +0800
Newsgroups dev.linux.lists.linux-coco,org.kernel.vger.kvm,org.kernel.vger.linux-kernel
Message-ID <amt1QNCBQas95XYB@yilunxu-OptiPlex-7050>
On Thu, Jul 30, 2026 at 07:10:02PM +0800, Xu Yilun wrote:
> 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.

Sorry, I changed my mind. I remember TDX module architector said "the
host should not assume any feature/SEAMCALL must be associated with any
extension, it is hidden from the host. Today a SEAMCALL is backed by an
extension, tomorrow it may not".

So in this case, ext_required may flip across updates and we should
honor the runtime metadata.

I made another effort to combine common routines for ext init and
update, but don't like how it turns out. If no one wants it that much,
I'd rather stay unchanged:

----8<----

diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
index cec266f76dc0..448d0ab76d05 100644
--- a/arch/x86/virt/vmx/tdx/tdx.c
+++ b/arch/x86/virt/vmx/tdx/tdx.c
@@ -1302,15 +1302,22 @@ static int tdx_ext_init(void)
        return 0;
 }

+static int get_tdx_sys_info_extensions(struct tdx_sys_info_ext *sysinfo_ext)
+{
+       if (!(tdx_sysinfo.features.tdx_features0 & TDX_FEATURES0_EXT)) {
+               memset(sysinfo_ext, 0, sizeof(*sysinfo_ext));
+               return 0;
+       }
+
+       return get_tdx_sys_info_ext(sysinfo_ext);
+}
+
 static __init int init_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);
+       ret = get_tdx_sys_info_extensions(&sysinfo_ext);
        if (ret)
                return ret;

@@ -1339,10 +1346,7 @@ 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);
+       ret = get_tdx_sys_info_extensions(&sysinfo_ext);
        if (ret)
                return ret;