From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.8]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3573935FF79 for ; Thu, 12 Feb 2026 14:36:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.8 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770906992; cv=none; b=iRjmgy+qBxm3YWBQpGKRBKTb4XskppBZlvsQAw4F3J0LhZm8vxzBokrl5LVvn8dWDc489LCUHoE1BjEfx8ycuyGyXFwKhopuBiAcOzJxSskrjsbhs1h+2T27Heq9L3fPWGYXiSVv+6MDsLQwF7BIWtbMq4f6a/lewxoU2zZz7Rw= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770906992; c=relaxed/simple; bh=GhJFERFArGCOjhBsVl6u1CHbRHCytZerbvEqOSuaS6I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=D6zNrvKPGy8Qth+iPtd98SL0Ar/5oyqYDP5iuHYKWIRWgGyjNboEm5+QpnGEpuPOnJuOQahxoXK2V/pEAN1+ZFLpJLbg1hcZanjAFHMt+9R1QvBEnyp827x8CR4G33I6MR/YoFWr2NELMHGZZUEIYv0E41aYHd7vFFZclQIJrK8= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=G2FujIFV; arc=none smtp.client-ip=192.198.163.8 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="G2FujIFV" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1770906990; x=1802442990; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=GhJFERFArGCOjhBsVl6u1CHbRHCytZerbvEqOSuaS6I=; b=G2FujIFVwsY/EM+vmn90dYqCWba3WB5FZRnilPaUEzQ0wsiLpzAmHIjt bUZ5wj5sUIRdhCM1cHbu3Ss01y7ALNNjRMlK9zQrdLBGyXSjjPMECPuX3 krbqG7VuMcBcf38afVlqUvYmLrzYl/0iXozKg966ROMzhPJlSVpvFPWzx b8u80t7xl8QEGDfHQIyggU8QygJZvrc+2dftNw13umvmLUJW0l4BE6VT5 sw04/EDSR2WvYcliGDlV4nCKCM7sOz1dj5Thej50ZuAkzYdBPu3CxVJ8v K06j6NqlO2xaPTtVBDu9rAphF7a4vb3l6HXu9DXs/U7RBP/gHLSHldLdV Q==; X-CSE-ConnectionGUID: xmGdYeLrSsOQZfA4edzAsA== X-CSE-MsgGUID: IR/efc3aRH+gpWR74GB9+A== X-IronPort-AV: E=McAfee;i="6800,10657,11699"; a="89662896" X-IronPort-AV: E=Sophos;i="6.21,286,1763452800"; d="scan'208";a="89662896" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Feb 2026 06:36:29 -0800 X-CSE-ConnectionGUID: v6peFe1NS0KdIC17xkjjQw== X-CSE-MsgGUID: mc/I73T0QYO0otBEHLMjJA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,286,1763452800"; d="scan'208";a="211428290" Received: from 984fee019967.jf.intel.com ([10.23.153.244]) by fmviesa006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Feb 2026 06:36:28 -0800 From: Chao Gao To: linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, x86@kernel.org Cc: reinette.chatre@intel.com, ira.weiny@intel.com, kai.huang@intel.com, dan.j.williams@intel.com, yilun.xu@linux.intel.com, sagis@google.com, vannapurve@google.com, paulmck@kernel.org, nik.borisov@suse.com, zhenzhong.duan@intel.com, seanjc@google.com, rick.p.edgecombe@intel.com, kas@kernel.org, dave.hansen@linux.intel.com, vishal.l.verma@intel.com, binbin.wu@linux.intel.com, tony.lindgren@linux.intel.com, Chao Gao , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v4 19/24] x86/virt/tdx: Update tdx_sysinfo and check features post-update Date: Thu, 12 Feb 2026 06:35:22 -0800 Message-ID: <20260212143606.534586-20-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260212143606.534586-1-chao.gao@intel.com> References: <20260212143606.534586-1-chao.gao@intel.com> Precedence: bulk X-Mailing-List: linux-coco@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit tdx_sysinfo contains all metadata of the active TDX module, including versions, supported features, and TDMR/TDCS/TDVPS information. 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. Signed-off-by: Chao Gao Reviewed-by: Xu Yilun Reviewed-by: Tony Lindgren --- 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 | 11 ++++++++- arch/x86/virt/vmx/tdx/tdx.c | 43 +++++++++++++++++++++++++++++++++ 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 0ca802234695..3f37cc6c68ff 100644 --- a/arch/x86/virt/vmx/tdx/seamldr.c +++ b/arch/x86/virt/vmx/tdx/seamldr.c @@ -315,6 +315,15 @@ int seamldr_install_module(const u8 *data, u32 size) if (WARN_ON_ONCE(!is_vmalloc_addr(data))) return -EINVAL; + /* + * Preallocating a tdx_sys_info buffer before updates 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)) @@ -332,6 +341,6 @@ int seamldr_install_module(const u8 *data, u32 size) if (ret) return ret; - return 0; + 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 a8adb2c97e2f..3f5edbc33a4f 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -1218,6 +1218,49 @@ int tdx_module_run_update(void) return 0; } +/* + * Update tdx_sysinfo and check if any TDX module features changed after + * updates + */ +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 TDX Module\n")) + return ret; + + old = &tdx_sysinfo.version; + new = &info->version; + pr_info("version %u.%u.%02u -> %u.%u.%02u\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 version information (including handoff version) + * that does not affect functionality, and ignore all other + * changes. + */ + tdx_sysinfo.version = info->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 0887debfd139..d1807a476d3b 100644 --- a/arch/x86/virt/vmx/tdx/tdx.h +++ b/arch/x86/virt/vmx/tdx/tdx.h @@ -4,6 +4,8 @@ #include +#include + /* * 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