From: Chao Gao <chao.gao@intel.com>
To: linux-kernel@vger.kernel.org, linux-coco@lists.linux.dev,
kvm@vger.kernel.org
Cc: binbin.wu@linux.intel.com, dan.j.williams@intel.com,
dave.hansen@linux.intel.com, ira.weiny@intel.com,
kai.huang@intel.com, kas@kernel.org, nik.borisov@suse.com,
paulmck@kernel.org, pbonzini@redhat.com,
reinette.chatre@intel.com, rick.p.edgecombe@intel.com,
sagis@google.com, seanjc@google.com,
tony.lindgren@linux.intel.com, vannapurve@google.com,
vishal.l.verma@intel.com, yilun.xu@linux.intel.com,
xiaoyao.li@intel.com, yan.y.zhao@intel.com,
Chao Gao <chao.gao@intel.com>, Thomas Gleixner <tglx@kernel.org>,
Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
x86@kernel.org, "H. Peter Anvin" <hpa@zytor.com>
Subject: [PATCH v7 16/22] x86/virt/tdx: Update tdx_sysinfo and check features post-update
Date: Tue, 31 Mar 2026 05:41:29 -0700 [thread overview]
Message-ID: <20260331124214.117808-17-chao.gao@intel.com> (raw)
In-Reply-To: <20260331124214.117808-1-chao.gao@intel.com>
tdx_sysinfo contains all metadata of the active TDX module, including
versions, supported features, and TDMR/TDCS/TDVPS information etc. These
values may change over updates. Blindly refreshing the entire tdx_sysinfo
could disrupt running software, as it may subtly rely on the previous state
unless proven otherwise.
Adopt a conservative approach, like microcode updates, by only refreshing
version information that does not affect functionality, while ignoring
all other changes. This is acceptable as new modules are required to
maintain backward compatibility.
Any updates to metadata beyond versions should be justified and reviewed on
a case-by-case basis.
Note that preallocating a tdx_sys_info buffer before updates is to avoid
having to handle -ENOMEM when updating tdx_sysinfo after a successful
update.
Also note that TDX module updates are supported only between releases
with different update versions but identical major and minor versions.
So, major and minor versions are not refreshed.
Signed-off-by: Chao Gao <chao.gao@intel.com>
Reviewed-by: Xu Yilun <yilun.xu@linux.intel.com>
Reviewed-by: Tony Lindgren <tony.lindgren@linux.intel.com>
Reviewed-by: Kai Huang <kai.huang@intel.com>
Reviewed-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
Reviewed-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
---
Sashiko flagged a potential torn-read concern: update_version is read
via sysfs while it is refreshed post-update. But, update_version is a
naturally-aligned u16, and on x86, the compiler won't split aligned u16
accesses. So READ_ONCE/WRITE_ONCE() aren't needed for update_version.
v7:
- use TDX_VERSION_FMT
- only update update_version and add a comment to explain why
v5:
- Drop the comment above tdx_module_post_update() [Kai]
v3:
- use 'old' instead of 'cur' as the local variable to represent the
sysinfo of the previous module [Binbin]
- combine if(ret) and WARN_ONCE(1, ...) to WARN_ONCE(ret, ...) [Binbin]
- Improve the print log messages after detecting new features from updates.
[Binbin]
v2:
- don't add a separate function for version and feature checks. Do them
directly in tdx_module_post_update()
- add a comment about preallocating a tdx_sys_info buffer in
seamldr_install_module().
---
arch/x86/virt/vmx/tdx/seamldr.c | 18 ++++++++++++++++-
arch/x86/virt/vmx/tdx/tdx.c | 36 +++++++++++++++++++++++++++++++++
arch/x86/virt/vmx/tdx/tdx.h | 3 +++
3 files changed, 56 insertions(+), 1 deletion(-)
diff --git a/arch/x86/virt/vmx/tdx/seamldr.c b/arch/x86/virt/vmx/tdx/seamldr.c
index a907b34d40c5..b3f3b40627c3 100644
--- a/arch/x86/virt/vmx/tdx/seamldr.c
+++ b/arch/x86/virt/vmx/tdx/seamldr.c
@@ -316,6 +316,18 @@ DEFINE_FREE(free_seamldr_params, struct seamldr_params *,
*/
int seamldr_install_module(const u8 *data, u32 size)
{
+ int ret;
+
+ /*
+ * Preallocating a tdx_sys_info buffer before an update is to avoid
+ * having to handle -ENOMEM when updating tdx_sysinfo after a
+ * successful update.
+ */
+ struct tdx_sys_info *sysinfo __free(kfree) = kzalloc(sizeof(*sysinfo),
+ GFP_KERNEL);
+ if (!sysinfo)
+ return -ENOMEM;
+
struct seamldr_params *params __free(free_seamldr_params) =
init_seamldr_params(data, size);
if (IS_ERR(params))
@@ -330,6 +342,10 @@ int seamldr_install_module(const u8 *data, u32 size)
guard(cpus_read_lock)();
update_data.failed = false;
set_target_state(MODULE_UPDATE_START + 1);
- return stop_machine_cpuslocked(do_seamldr_install_module, params, cpu_online_mask);
+ ret = stop_machine_cpuslocked(do_seamldr_install_module, params, cpu_online_mask);
+ if (ret)
+ return ret;
+
+ return tdx_module_post_update(sysinfo);
}
EXPORT_SYMBOL_FOR_MODULES(seamldr_install_module, "tdx-host");
diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
index 60caceb1baa7..08d9f4cb32f9 100644
--- a/arch/x86/virt/vmx/tdx/tdx.c
+++ b/arch/x86/virt/vmx/tdx/tdx.c
@@ -1232,6 +1232,42 @@ int tdx_module_run_update(void)
return 0;
}
+int tdx_module_post_update(struct tdx_sys_info *info)
+{
+ struct tdx_sys_info_version *old, *new;
+ int ret;
+
+ /* Shouldn't fail as the update has succeeded. */
+ ret = get_tdx_sys_info(info);
+ if (WARN_ONCE(ret, "version retrieval failed after update, replace the TDX module\n"))
+ return ret;
+
+ old = &tdx_sysinfo.version;
+ new = &info->version;
+ pr_info("version " TDX_VERSION_FMT " -> " TDX_VERSION_FMT "\n",
+ old->major_version, old->minor_version, old->update_version,
+ new->major_version, new->minor_version, new->update_version);
+
+ /*
+ * Blindly refreshing the entire tdx_sysinfo could disrupt running
+ * software, as it may subtly rely on the previous state unless
+ * proven otherwise.
+ *
+ * Only refresh update_version and handoff version. They don't
+ * affect TDX functionality. Major/minor versions do not change
+ * across updates, so no refresh is needed.
+ */
+ tdx_sysinfo.version.update_version = info->version.update_version;
+ tdx_sysinfo.handoff = info->handoff;
+
+ if (!memcmp(&tdx_sysinfo, info, sizeof(*info)))
+ return 0;
+
+ pr_info("TDX module features have changed after updates, but might not take effect.\n");
+ pr_info("Please consider updating your BIOS to install the TDX module.\n");
+ return 0;
+}
+
static bool is_pamt_page(unsigned long phys)
{
struct tdmr_info_list *tdmr_list = &tdx_tdmr_list;
diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h
index c62874b87d7a..f8686247c660 100644
--- a/arch/x86/virt/vmx/tdx/tdx.h
+++ b/arch/x86/virt/vmx/tdx/tdx.h
@@ -4,6 +4,8 @@
#include <linux/bits.h>
+#include <asm/tdx_global_metadata.h>
+
/*
* This file contains both macros and data structures defined by the TDX
* architecture and Linux defined software data structures and functions.
@@ -122,5 +124,6 @@ struct tdmr_info_list {
int tdx_module_shutdown(void);
int tdx_module_run_update(void);
+int tdx_module_post_update(struct tdx_sys_info *info);
#endif
--
2.47.3
next prev parent reply other threads:[~2026-03-31 12:43 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-31 12:41 [PATCH v7 00/22] Runtime TDX module update support Chao Gao
2026-03-31 12:41 ` [PATCH v7 01/22] x86/virt/tdx: Move low level SEAMCALL helpers out of <asm/tdx.h> Chao Gao
2026-03-31 12:41 ` [PATCH v7 02/22] coco/tdx-host: Introduce a "tdx_host" device Chao Gao
2026-03-31 12:41 ` [PATCH v7 03/22] coco/tdx-host: Expose TDX module version Chao Gao
2026-03-31 12:41 ` [PATCH v7 04/22] x86/virt/seamldr: Introduce a wrapper for P-SEAMLDR SEAMCALLs Chao Gao
2026-03-31 12:41 ` [PATCH v7 05/22] x86/virt/seamldr: Add a helper to retrieve P-SEAMLDR information Chao Gao
2026-03-31 12:41 ` [PATCH v7 06/22] coco/tdx-host: Expose P-SEAMLDR information via sysfs Chao Gao
2026-03-31 14:58 ` Dave Hansen
2026-04-01 1:57 ` Chao Gao
2026-03-31 14:58 ` Dave Hansen
2026-04-01 2:25 ` Chao Gao
2026-03-31 12:41 ` [PATCH v7 07/22] coco/tdx-host: Implement firmware upload sysfs ABI for TDX module updates Chao Gao
2026-03-31 15:04 ` Dave Hansen
2026-04-01 3:10 ` Chao Gao
2026-03-31 15:11 ` Dave Hansen
2026-04-01 7:49 ` Chao Gao
2026-03-31 12:41 ` [PATCH v7 08/22] x86/virt/seamldr: Allocate and populate a module update request Chao Gao
2026-03-31 15:44 ` Dave Hansen
2026-04-01 8:27 ` Chao Gao
2026-03-31 12:41 ` [PATCH v7 09/22] x86/virt/seamldr: Introduce skeleton for TDX module updates Chao Gao
2026-04-07 11:49 ` Chao Gao
2026-04-07 15:55 ` Dave Hansen
2026-03-31 12:41 ` [PATCH v7 10/22] x86/virt/seamldr: Abort updates if errors occurred midway Chao Gao
2026-03-31 12:41 ` [PATCH v7 11/22] x86/virt/seamldr: Shut down the current TDX module Chao Gao
2026-04-07 11:51 ` Chao Gao
2026-03-31 12:41 ` [PATCH v7 12/22] x86/virt/tdx: Reset software states during TDX module shutdown Chao Gao
2026-04-07 12:02 ` Chao Gao
2026-03-31 12:41 ` [PATCH v7 13/22] x86/virt/seamldr: Install a new TDX module Chao Gao
2026-03-31 12:41 ` [PATCH v7 14/22] x86/virt/seamldr: Do TDX per-CPU initialization after updates Chao Gao
2026-03-31 12:41 ` [PATCH v7 15/22] x86/virt/tdx: Restore TDX module state Chao Gao
2026-04-07 12:07 ` Chao Gao
2026-03-31 12:41 ` Chao Gao [this message]
2026-04-07 12:15 ` [PATCH v7 16/22] x86/virt/tdx: Update tdx_sysinfo and check features post-update Chao Gao
2026-04-07 15:53 ` Dave Hansen
2026-03-31 12:41 ` [PATCH v7 17/22] x86/virt/tdx: Avoid updates during update-sensitive operations Chao Gao
2026-04-06 22:29 ` Sean Christopherson
2026-03-31 12:41 ` [PATCH v7 18/22] coco/tdx-host: Don't expose P-SEAMLDR features on CPUs with erratum Chao Gao
2026-03-31 12:41 ` [PATCH v7 19/22] x86/virt/tdx: Enable TDX module runtime updates Chao Gao
2026-03-31 12:41 ` [PATCH v7 20/22] coco/tdx-host: Document TDX module update compatibility criteria Chao Gao
2026-03-31 12:41 ` [PATCH v7 21/22] x86/virt/tdx: Document TDX module update Chao Gao
2026-03-31 12:41 ` [PATCH v7 22/22] x86/virt/seamldr: Log TDX module update failures Chao Gao
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260331124214.117808-17-chao.gao@intel.com \
--to=chao.gao@intel.com \
--cc=binbin.wu@linux.intel.com \
--cc=bp@alien8.de \
--cc=dan.j.williams@intel.com \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=ira.weiny@intel.com \
--cc=kai.huang@intel.com \
--cc=kas@kernel.org \
--cc=kvm@vger.kernel.org \
--cc=linux-coco@lists.linux.dev \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=nik.borisov@suse.com \
--cc=paulmck@kernel.org \
--cc=pbonzini@redhat.com \
--cc=reinette.chatre@intel.com \
--cc=rick.p.edgecombe@intel.com \
--cc=sagis@google.com \
--cc=seanjc@google.com \
--cc=tglx@kernel.org \
--cc=tony.lindgren@linux.intel.com \
--cc=vannapurve@google.com \
--cc=vishal.l.verma@intel.com \
--cc=x86@kernel.org \
--cc=xiaoyao.li@intel.com \
--cc=yan.y.zhao@intel.com \
--cc=yilun.xu@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox