[tip: x86/tdx] coco/tdx-host: Lock out module updates when reading version

tip-bot2 for Dave Hansen posted 1 patch 2 days, 1 hour ago
drivers/virt/coco/tdx-host/tdx-host.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
[tip: x86/tdx] coco/tdx-host: Lock out module updates when reading version
Posted by tip-bot2 for Dave Hansen 2 days, 1 hour ago
The following commit has been merged into the x86/tdx branch of tip:

Commit-ID:     4df1ae579749ccc85ee46cc0caad04eb908ddd41
Gitweb:        https://git.kernel.org/tip/4df1ae579749ccc85ee46cc0caad04eb908ddd41
Author:        Dave Hansen <dave.hansen@linux.intel.com>
AuthorDate:    Fri, 22 May 2026 08:56:29 -07:00
Committer:     Dave Hansen <dave.hansen@linux.intel.com>
CommitterDate: Fri, 22 May 2026 10:20:09 -07:00

coco/tdx-host: Lock out module updates when reading version

The TDX module version is currently stashed in some global variables
and dumped out to sysfs without locking. This works fine when the
version is static and never changes.

But with runtime module updates, the TDX module version can change.
Some kind of locking is needed. Barring this, userspace could
theoretically see a strange torn module version that is some
Frankenstein version from from two different updates.

Use the new module update lock/unlock to prevent updates while
trying to read the version.

Don't be fussy about it. There's no need to snapshot the version or do
READ_ONCE(), or minimize lock holding times. sysfs_emit() does not
sleep. Also note that the lock/unlock are backed by
preempt_dis/enable() which are really cheap CPU-local operations.
This is not a heavyweight lock.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
---
 drivers/virt/coco/tdx-host/tdx-host.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/virt/coco/tdx-host/tdx-host.c b/drivers/virt/coco/tdx-host/tdx-host.c
index e5a672b..d489529 100644
--- a/drivers/virt/coco/tdx-host/tdx-host.c
+++ b/drivers/virt/coco/tdx-host/tdx-host.c
@@ -26,15 +26,24 @@ static ssize_t version_show(struct device *dev, struct device_attribute *attr,
 {
 	const struct tdx_sys_info *tdx_sysinfo = tdx_get_sysinfo();
 	const struct tdx_sys_info_version *ver;
+	int ret;
 
 	if (!tdx_sysinfo)
 		return -ENXIO;
 
+	/*
+	 * The version number can change during an update.
+	 * Lock out updates while printing the version.
+	 */
+	seamldr_lock_module_update();
+
 	ver = &tdx_sysinfo->version;
+	ret = sysfs_emit(buf, TDX_VERSION_FMT "\n", ver->major_version,
+						    ver->minor_version,
+						    ver->update_version);
+	seamldr_unlock_module_update();
 
-	return sysfs_emit(buf, TDX_VERSION_FMT "\n", ver->major_version,
-						     ver->minor_version,
-						     ver->update_version);
+	return ret;
 }
 static DEVICE_ATTR_RO(version);