From: Chao Gao Date: Wed, 20 May 2026 22:29:09 +0000 (-0700) Subject: x86/virt/seamldr: Initialize the newly-installed TDX module X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=bf7c0ed2c3621f4f0bf56efcd95e5a5372bf0ca6;p=thirdparty%2Fkernel%2Flinux.git x86/virt/seamldr: Initialize the newly-installed TDX module Continue fleshing out the update process. At this point the new module is sitting in memory but has never been called and is not usable. It is in a similar state to the when the system first boots. Leave the P-SEAMLDR behind. Stop making calls to it. Transition to calling the new TDX module itself to set up both global and per-cpu state. Share tdx_cpu_enable() with the fresh-boot module initialization code. Export it and invoke it on all CPUs. Note: "TDX global initialization" needs to be done once before "TDX per-CPU initialization". It would be a great fit for the new runtime update "is_lead_cpu" logic. But tdx_cpu_enable() already has some logic to do the global initialization properly. Just use it directly to maximize fresh-boot and runtime update code sharing. == Background == The boot-time and post-update initialization flows share the same first steps: - TDX global initialization - TDX per-CPU initialization After that, they diverge: - Fresh boot: Prepare TDMRs/PAMTs Configure the TDX module Configure the global KeyID Initialize TDMRs - Runtime update: Restore TDX module state from handoff data Future changes will consume the handoff data. [ dhansen: major changelog munging ] Signed-off-by: Chao Gao Signed-off-by: Dave Hansen Reviewed-by: Xu Yilun Reviewed-by: Tony Lindgren Reviewed-by: Kai Huang Reviewed-by: Kiryl Shutsemau (Meta) Reviewed-by: Rick Edgecombe Link: https://patch.msgid.link/20260520133909.409394-20-chao.gao@intel.com --- diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h index 27376db7ddaca..5d750fe53669c 100644 --- a/arch/x86/include/asm/tdx.h +++ b/arch/x86/include/asm/tdx.h @@ -107,6 +107,7 @@ static inline long tdx_kvm_hypercall(unsigned int nr, unsigned long p1, #ifdef CONFIG_INTEL_TDX_HOST void tdx_init(void); +int tdx_cpu_enable(void); const char *tdx_dump_mce_info(struct mce *m); const struct tdx_sys_info *tdx_get_sysinfo(void); diff --git a/arch/x86/virt/vmx/tdx/seamldr.c b/arch/x86/virt/vmx/tdx/seamldr.c index 54fa797a20191..5fdb36b50bf4e 100644 --- a/arch/x86/virt/vmx/tdx/seamldr.c +++ b/arch/x86/virt/vmx/tdx/seamldr.c @@ -209,6 +209,7 @@ enum module_update_state { MODULE_UPDATE_START, MODULE_UPDATE_SHUTDOWN, MODULE_UPDATE_CPU_INSTALL, + MODULE_UPDATE_CPU_INIT, MODULE_UPDATE_DONE, }; @@ -287,6 +288,9 @@ static int do_seamldr_install_module(void *seamldr_params) case MODULE_UPDATE_CPU_INSTALL: ret = seamldr_install(seamldr_params); break; + case MODULE_UPDATE_CPU_INIT: + ret = tdx_cpu_enable(); + break; default: break; } diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 37e52cd4a389f..080a2bccc19ab 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -113,7 +113,7 @@ out: * (and TDX module global initialization SEAMCALL if not done) on local cpu to * make this cpu be ready to run any other SEAMCALLs. */ -static int tdx_cpu_enable(void) +int tdx_cpu_enable(void) { struct tdx_module_args args = {}; int ret;