From nobody Sat Feb 7 08:27:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 C1BAF2E22AB; Fri, 23 Jan 2026 15:00:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180414; cv=none; b=Jbb0pn+JnAb4IU+9jE3e8S/s0CRX3P5UwOzGyTsi9cF5g7DtFBoF1o2apR7+HPu4V1Pd9oUeiTq0EphWiGBybQLRC/itfYitwvgRo8zMuk6GUKS1S/b8m1QwwiiMM2XEniDJncIF/ujeAu+r/pn7tJV4IPpz3nOlTk888ZPIQok= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180414; c=relaxed/simple; bh=vgLz4SF3EU8nW3xjV4de4zODfdoo/xqh0j1ukDOOGJ4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pOc1ruUcivvBQINKbwMQZhuiuVvOre6ECMV8aaA1avyw8QNrPCxixr4irQZwbS3Tqp/QozOdtjVGMC08cUBrflpNoUBw2LaYD4LkW4WKngTA+UjIZKGw2LVSmVCCBPQtnZ57xaoFOcLVM3WzQ0Zqwpk+qnapdzdRaocy27LKJJw= 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=IiY4Q6Qg; arc=none smtp.client-ip=192.198.163.17 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="IiY4Q6Qg" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1769180411; x=1800716411; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=vgLz4SF3EU8nW3xjV4de4zODfdoo/xqh0j1ukDOOGJ4=; b=IiY4Q6QgDF7gyj7lfxcS6YtO1YlBHGlIAZH4YvtwVFWGDejuPH29VWMV PYJzwvfkh4l2x2bJJ88z5AaUEm2MHPj0YoFREVBtEwUpDaHY4C+uOOXOh 11lc6s873C0af0sUetP6XwRMz7EfHkUyOvcyT7JAzRWulvPuntZxemTvO b1o2eJBt7hto/K2rr3SvSyU1DETn87reKiRD9NCvSbFKXHNHo4zepBxe9 fdqyH1UrPsdjlme60+7HukL+/6uej6k6c4OpgANQb+MSjYlPTALVoZUTx fkmCA6Q9KfKRACy/qSlA12u6U807fcDcicapeJcUOJdc7rq6yQjGdmV24 Q==; X-CSE-ConnectionGUID: BnYVpP+ESgy7Oz7oHtKc0w== X-CSE-MsgGUID: Yec44HVBTTChPGw/Otqgmw== X-IronPort-AV: E=McAfee;i="6800,10657,11680"; a="70334325" X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="70334325" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:07 -0800 X-CSE-ConnectionGUID: tbH5XHWYSAOdGjZg9lbF3A== X-CSE-MsgGUID: N3K3CeK9TF+u85mW7YlRlg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="237697016" Received: from 984fee019967.jf.intel.com ([10.23.153.244]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:07 -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, Chao Gao , "Kirill A. Shutemov" , Farrah Chen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v3 01/26] x86/virt/tdx: Print SEAMCALL leaf numbers in decimal Date: Fri, 23 Jan 2026 06:55:09 -0800 Message-ID: <20260123145645.90444-2-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260123145645.90444-1-chao.gao@intel.com> References: <20260123145645.90444-1-chao.gao@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Both TDX spec and kernel defines SEAMCALL leaf numbers as decimal. Printing them in hex makes no sense. Correct it. Suggested-by: Kirill A. Shutemov Signed-off-by: Chao Gao Tested-by: Farrah Chen Reviewed-by: Kai Huang Reviewed-by: Zhenzhong Duan Reviewed-by: Binbin Wu Reviewed-by: Tony Lindgren --- v2: - print leaf numbers with %llu --- arch/x86/virt/vmx/tdx/tdx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 5ce4ebe99774..dbc7cb08ca53 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -63,7 +63,7 @@ typedef void (*sc_err_func_t)(u64 fn, u64 err, struct tdx= _module_args *args); =20 static inline void seamcall_err(u64 fn, u64 err, struct tdx_module_args *a= rgs) { - pr_err("SEAMCALL (0x%016llx) failed: 0x%016llx\n", fn, err); + pr_err("SEAMCALL (%llu) failed: 0x%016llx\n", fn, err); } =20 static inline void seamcall_err_ret(u64 fn, u64 err, --=20 2.47.3 From nobody Sat Feb 7 08:27:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 17FEF28488D; Fri, 23 Jan 2026 15:00:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180415; cv=none; b=HeeqTPKxJa0C/U3DHlRv5c538lAlUhYBKoHtrO9pulrYGnIWfIKeTczQ92Jo6ZU2NuhSB6uOVszi0d0dLAMUZwkP9YJyoj8ajyOrqRg2tcXCZYxHmpajFRxpUD70Llu5gUfetHmyi5gb9P4+tMM6v1DN6SiWx4N53aa8MTPiH70= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180415; c=relaxed/simple; bh=HaMEyLc+oaG7OmponVaIw/lEk5QQtY46m2sTc9gb1PY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=K89GbD1p5Q7tumB723dKe5KnGjKL31PxpOVVJEX8ysXbadAOFZiHGUSd6U9sCQu2gg7GAs2t3GQrXMT2u5oo0sLKWkBbYXOCBGTg9MlcsEYkqFvoK5lSHaEZ4WXamVYyTQkQ2N9YG0kr3/Nr/ak6U5Qhvya8edDxBFa3qcIhpn0= 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=X0L/Ypiz; arc=none smtp.client-ip=192.198.163.17 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="X0L/Ypiz" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1769180414; x=1800716414; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=HaMEyLc+oaG7OmponVaIw/lEk5QQtY46m2sTc9gb1PY=; b=X0L/Ypiz7r+YW5B9pQRW4BI6SyAUI+MJxx1Hdk3ivr74OblG2tJjfNNn 6lLgk5D6Fgr7xtynXPvDNE43yVCN02EPJ/EH2WsaOMkyBa23rxHq2TMLb ZAc5C9OCg2DIYTXFpvKFqsp6WaCryr8Dk7r5aYSf/qKKgN5yzQmzKh8Gs 7ibI+4s8eoSiFdVG82GtGa21l1DjsVVkJ8fOe5XN8VbcRmDUAN6/gzvkN NKlOiYG4fM19IWHDIKwWRdF2+G9/lsr7fnbgOuFcWbi0mE3D1QFWoLDsZ rZLjoGRJ/DPKoC4FVj4NTd5yY3Gdl6/3M6afdB1mr3EVAErvIfFZ0l/FY Q==; X-CSE-ConnectionGUID: 3UlHI+9YRJ+ZyfRLL6ioRQ== X-CSE-MsgGUID: ina6bKOtQeywPv8ip0rA2w== X-IronPort-AV: E=McAfee;i="6800,10657,11680"; a="70334337" X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="70334337" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:08 -0800 X-CSE-ConnectionGUID: EguImU4ATgyVTKaFDCrj2g== X-CSE-MsgGUID: YPlqmC//QSWU0MFpB0KfEw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="237697028" Received: from 984fee019967.jf.intel.com ([10.23.153.244]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:08 -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, Chao Gao , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v3 02/26] x86/virt/tdx: Use %# prefix for hex values in SEAMCALL error messages Date: Fri, 23 Jan 2026 06:55:10 -0800 Message-ID: <20260123145645.90444-3-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260123145645.90444-1-chao.gao@intel.com> References: <20260123145645.90444-1-chao.gao@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" "%#" format specifier automatically adds the "0x" prefix and has one less character than "0x%". For conciseness, replace "0x%" with "%#" when printing hexadecimal values in SEAMCALL error messages. Suggested-by: Dan Williams Signed-off-by: Chao Gao Reviewed-by: Binbin Wu Reviewed-by: Tony Lindgren --- "0x%" is also used to print TDMR ranges. I didn't convert them to reduce code churn, but if they should be converted for consistency, I'm happy to do that. v2: new --- arch/x86/virt/vmx/tdx/tdx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index dbc7cb08ca53..2218bb42af40 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -63,16 +63,16 @@ typedef void (*sc_err_func_t)(u64 fn, u64 err, struct t= dx_module_args *args); =20 static inline void seamcall_err(u64 fn, u64 err, struct tdx_module_args *a= rgs) { - pr_err("SEAMCALL (%llu) failed: 0x%016llx\n", fn, err); + pr_err("SEAMCALL (%llu) failed: %#016llx\n", fn, err); } =20 static inline void seamcall_err_ret(u64 fn, u64 err, struct tdx_module_args *args) { seamcall_err(fn, err, args); - pr_err("RCX 0x%016llx RDX 0x%016llx R08 0x%016llx\n", + pr_err("RCX %#016llx RDX %#016llx R08 %#016llx\n", args->rcx, args->rdx, args->r8); - pr_err("R09 0x%016llx R10 0x%016llx R11 0x%016llx\n", + pr_err("R09 %#016llx R10 %#016llx R11 %#016llx\n", args->r9, args->r10, args->r11); } =20 --=20 2.47.3 From nobody Sat Feb 7 08:27:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 7FE9C2E06EA; Fri, 23 Jan 2026 15:00:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180416; cv=none; b=SBgSYFX5pnUuCoZYtxFO31609lF5yDUMHhF5OEX+yPWEmULju2Ohib9Q2Soh0/OutOqgKc7DosjKcDONbXj9j8nfvq/q6XrgR7d5cUOlC2voL8iZBSDPt0Ra7Tzo8m2rOk7XlZolNi4FkuQ0xgwIIekEe9yr8nmoxVm+aqZtOdk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180416; c=relaxed/simple; bh=i+mes0H/CJ0dnn+DCy/4MLZXFZzfpvSzV38ZMOA56jg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CWN+Z0WUPkekjhEvjnQNXx5k8m3eT8MgfTD/iWE++05Ppp14gNWK2unyOxfApqkm/NmK68B39QiRMKpRvoTNCrilIJzJjWPDlxyEAevkay/BBh/1AeCaNBVmOWtqcEBvCyT4d7MdCWbOxGZDLgjFC2LnmM9WvmDz9PUgekFj6Ps= 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=m+mg+C99; arc=none smtp.client-ip=192.198.163.17 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="m+mg+C99" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1769180414; x=1800716414; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=i+mes0H/CJ0dnn+DCy/4MLZXFZzfpvSzV38ZMOA56jg=; b=m+mg+C99i2GiNC3BE7dzgTnenk/6MwsDmW502qoFsQerW8kdLCw4jy1m ZYCXd+IMalEtmy7vH1OL1kx9izvOrId1pRIBc+QId7W0Gdb2Sya/uUjP1 yhB3TEOOhtk2JLLssT8rdh2KT+WojaG8XSPcp5HgZSqp1W/w0Vn68eJzH rB2RvcjkGCIxoqD22HsQkZWCqcm6tVtdQtWD2Owi0hyz6+ykTl8VFxvWk kLznLCLlAgutavL/r67b3IUsGvIrhneqhsLy0D4CySCdEsZ9kz0Kokf6Y kS4bv7oG9+QZdYns6PzIA3j0vObT4lcThbaD+jyLO9fWBCzPDaQCEWbmZ g==; X-CSE-ConnectionGUID: go8UfU0uRN+APxzJuuAlkA== X-CSE-MsgGUID: 1aVBnQrQTxWYfU2tP0xCeQ== X-IronPort-AV: E=McAfee;i="6800,10657,11680"; a="70334346" X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="70334346" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:09 -0800 X-CSE-ConnectionGUID: H1GVEiG/RR+ehrVmie6vdw== X-CSE-MsgGUID: Oa4k5bQ1QzC44KRB851/TQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="237697043" Received: from 984fee019967.jf.intel.com ([10.23.153.244]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:08 -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, Chao Gao , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v3 03/26] x86/virt/tdx: Move low level SEAMCALL helpers out of Date: Fri, 23 Jan 2026 06:55:11 -0800 Message-ID: <20260123145645.90444-4-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260123145645.90444-1-chao.gao@intel.com> References: <20260123145645.90444-1-chao.gao@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Kai Huang TDX host core code implements three seamcall*() helpers to make SEAMCALL to the TDX module. Currently, they are implemented in and are exposed to other kernel code which includes . However, other than the TDX host core, seamcall*() are not expected to be used by other kernel code directly. For instance, for all SEAMCALLs that are used by KVM, the TDX host core exports a wrapper function for each of them. Move seamcall*() and related code out of and make them only visible to TDX host core. Since TDX host core tdx.c is already very heavy, don't put low level seamcall*() code there but to a new dedicated "seamcall.h". Also, currently tdx.c has seamcall_prerr*() helpers which additionally print error message when calling seamcall*() fails. Move them to "seamcall.h" as well. In such way all low level SEAMCALL helpers are in a dedicated place, which is much more readable. Signed-off-by: Kai Huang Signed-off-by: Chao Gao Reviewed-by: Zhenzhong Duan Acked-by: Dave Hansen Reviewed-by: Binbin Wu Reviewed-by: Tony Lindgren --- v2: - new --- arch/x86/include/asm/tdx.h | 47 --------------- arch/x86/virt/vmx/tdx/seamcall.h | 99 ++++++++++++++++++++++++++++++++ arch/x86/virt/vmx/tdx/tdx.c | 46 +-------------- 3 files changed, 100 insertions(+), 92 deletions(-) create mode 100644 arch/x86/virt/vmx/tdx/seamcall.h diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h index 6b338d7f01b7..cb2219302dfc 100644 --- a/arch/x86/include/asm/tdx.h +++ b/arch/x86/include/asm/tdx.h @@ -97,54 +97,7 @@ static inline long tdx_kvm_hypercall(unsigned int nr, un= signed long p1, #endif /* CONFIG_INTEL_TDX_GUEST && CONFIG_KVM_GUEST */ =20 #ifdef CONFIG_INTEL_TDX_HOST -u64 __seamcall(u64 fn, struct tdx_module_args *args); -u64 __seamcall_ret(u64 fn, struct tdx_module_args *args); -u64 __seamcall_saved_ret(u64 fn, struct tdx_module_args *args); void tdx_init(void); - -#include -#include -#include - -typedef u64 (*sc_func_t)(u64 fn, struct tdx_module_args *args); - -static __always_inline u64 __seamcall_dirty_cache(sc_func_t func, u64 fn, - struct tdx_module_args *args) -{ - lockdep_assert_preemption_disabled(); - - /* - * SEAMCALLs are made to the TDX module and can generate dirty - * cachelines of TDX private memory. Mark cache state incoherent - * so that the cache can be flushed during kexec. - * - * This needs to be done before actually making the SEAMCALL, - * because kexec-ing CPU could send NMI to stop remote CPUs, - * in which case even disabling IRQ won't help here. - */ - this_cpu_write(cache_state_incoherent, true); - - return func(fn, args); -} - -static __always_inline u64 sc_retry(sc_func_t func, u64 fn, - struct tdx_module_args *args) -{ - int retry =3D RDRAND_RETRY_LOOPS; - u64 ret; - - do { - preempt_disable(); - ret =3D __seamcall_dirty_cache(func, fn, args); - preempt_enable(); - } while (ret =3D=3D TDX_RND_NO_ENTROPY && --retry); - - return ret; -} - -#define seamcall(_fn, _args) sc_retry(__seamcall, (_fn), (_args)) -#define seamcall_ret(_fn, _args) sc_retry(__seamcall_ret, (_fn), (_args)) -#define seamcall_saved_ret(_fn, _args) sc_retry(__seamcall_saved_ret, (_fn= ), (_args)) int tdx_cpu_enable(void); int tdx_enable(void); const char *tdx_dump_mce_info(struct mce *m); diff --git a/arch/x86/virt/vmx/tdx/seamcall.h b/arch/x86/virt/vmx/tdx/seamc= all.h new file mode 100644 index 000000000000..0912e03fabfe --- /dev/null +++ b/arch/x86/virt/vmx/tdx/seamcall.h @@ -0,0 +1,99 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2025 Intel Corporation */ +#ifndef _X86_VIRT_SEAMCALL_H +#define _X86_VIRT_SEAMCALL_H + +#include +#include +#include +#include +#include + +u64 __seamcall(u64 fn, struct tdx_module_args *args); +u64 __seamcall_ret(u64 fn, struct tdx_module_args *args); +u64 __seamcall_saved_ret(u64 fn, struct tdx_module_args *args); + +typedef u64 (*sc_func_t)(u64 fn, struct tdx_module_args *args); + +static __always_inline u64 __seamcall_dirty_cache(sc_func_t func, u64 fn, + struct tdx_module_args *args) +{ + lockdep_assert_preemption_disabled(); + + /* + * SEAMCALLs are made to the TDX module and can generate dirty + * cachelines of TDX private memory. Mark cache state incoherent + * so that the cache can be flushed during kexec. + * + * This needs to be done before actually making the SEAMCALL, + * because kexec-ing CPU could send NMI to stop remote CPUs, + * in which case even disabling IRQ won't help here. + */ + this_cpu_write(cache_state_incoherent, true); + + return func(fn, args); +} + +static __always_inline u64 sc_retry(sc_func_t func, u64 fn, + struct tdx_module_args *args) +{ + int retry =3D RDRAND_RETRY_LOOPS; + u64 ret; + + do { + ret =3D func(fn, args); + } while (ret =3D=3D TDX_RND_NO_ENTROPY && --retry); + + return ret; +} + +#define seamcall(_fn, _args) sc_retry(__seamcall, (_fn), (_args)) +#define seamcall_ret(_fn, _args) sc_retry(__seamcall_ret, (_fn), (_args)) +#define seamcall_saved_ret(_fn, _args) sc_retry(__seamcall_saved_ret, (_fn= ), (_args)) + +typedef void (*sc_err_func_t)(u64 fn, u64 err, struct tdx_module_args *arg= s); + +static inline void seamcall_err(u64 fn, u64 err, struct tdx_module_args *a= rgs) +{ + pr_err("SEAMCALL (%llu) failed: %#016llx\n", fn, err); +} + +static inline void seamcall_err_ret(u64 fn, u64 err, + struct tdx_module_args *args) +{ + seamcall_err(fn, err, args); + pr_err("RCX %#016llx RDX %#016llx R08 %#016llx\n", + args->rcx, args->rdx, args->r8); + pr_err("R09 %#016llx R10 %#016llx R11 %#016llx\n", + args->r9, args->r10, args->r11); +} + +static __always_inline int sc_retry_prerr(sc_func_t func, + sc_err_func_t err_func, + u64 fn, struct tdx_module_args *args) +{ + u64 sret =3D sc_retry(func, fn, args); + + if (sret =3D=3D TDX_SUCCESS) + return 0; + + if (sret =3D=3D TDX_SEAMCALL_VMFAILINVALID) + return -ENODEV; + + if (sret =3D=3D TDX_SEAMCALL_GP) + return -EOPNOTSUPP; + + if (sret =3D=3D TDX_SEAMCALL_UD) + return -EACCES; + + err_func(fn, sret, args); + return -EIO; +} + +#define seamcall_prerr(__fn, __args) \ + sc_retry_prerr(__seamcall, seamcall_err, (__fn), (__args)) + +#define seamcall_prerr_ret(__fn, __args) \ + sc_retry_prerr(__seamcall_ret, seamcall_err_ret, (__fn), (__args)) + +#endif diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 2218bb42af40..b44723ef4a14 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -39,6 +39,7 @@ #include #include #include +#include "seamcall.h" #include "tdx.h" =20 static u32 tdx_global_keyid __ro_after_init; @@ -59,51 +60,6 @@ static LIST_HEAD(tdx_memlist); =20 static struct tdx_sys_info tdx_sysinfo; =20 -typedef void (*sc_err_func_t)(u64 fn, u64 err, struct tdx_module_args *arg= s); - -static inline void seamcall_err(u64 fn, u64 err, struct tdx_module_args *a= rgs) -{ - pr_err("SEAMCALL (%llu) failed: %#016llx\n", fn, err); -} - -static inline void seamcall_err_ret(u64 fn, u64 err, - struct tdx_module_args *args) -{ - seamcall_err(fn, err, args); - pr_err("RCX %#016llx RDX %#016llx R08 %#016llx\n", - args->rcx, args->rdx, args->r8); - pr_err("R09 %#016llx R10 %#016llx R11 %#016llx\n", - args->r9, args->r10, args->r11); -} - -static __always_inline int sc_retry_prerr(sc_func_t func, - sc_err_func_t err_func, - u64 fn, struct tdx_module_args *args) -{ - u64 sret =3D sc_retry(func, fn, args); - - if (sret =3D=3D TDX_SUCCESS) - return 0; - - if (sret =3D=3D TDX_SEAMCALL_VMFAILINVALID) - return -ENODEV; - - if (sret =3D=3D TDX_SEAMCALL_GP) - return -EOPNOTSUPP; - - if (sret =3D=3D TDX_SEAMCALL_UD) - return -EACCES; - - err_func(fn, sret, args); - return -EIO; -} - -#define seamcall_prerr(__fn, __args) \ - sc_retry_prerr(__seamcall, seamcall_err, (__fn), (__args)) - -#define seamcall_prerr_ret(__fn, __args) \ - sc_retry_prerr(__seamcall_ret, seamcall_err_ret, (__fn), (__args)) - /* * Do the module global initialization once and return its result. * It can be done on any cpu. It's always called with interrupts --=20 2.47.3 From nobody Sat Feb 7 08:27:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 85BA4265CA8; Fri, 23 Jan 2026 15:00:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180417; cv=none; b=i+ytdAUcjqe1kRN82bcelz6hQNfca4F+xeUiQjs/AsKfu8uukkcrkdJyC8f4jmBKhJckgh3Q4QMXyc2+MJc42ps4qBCSNq3hidIQJYFbM6J5DfuyaTOdj+e6cCm+15qZSnxIMKVMZtu6otjObujHSLPWkPTjNAhk9KzVb5FD5i8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180417; c=relaxed/simple; bh=xnX+zze05KP0ZC9spil2KJ6751Wn7UXOI7ZpdQ6pvGI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SnDXSWZ+vTIgFd44NEbNCbYP4pH/sX335EEssiHLqtGnlfMc4fi3735RPG9b970aOZkQY+BuoC1YUakb+3eRTSlYaPcNp0v0Y12weodrwY6yrMwo47lCD5DegeztbKMmCZZEi8y02mlUv6/10IIgsIxReFMxDtUNRbAFXhkmQmc= 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=eldzUrWz; arc=none smtp.client-ip=192.198.163.17 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="eldzUrWz" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1769180415; x=1800716415; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=xnX+zze05KP0ZC9spil2KJ6751Wn7UXOI7ZpdQ6pvGI=; b=eldzUrWzG2DLcxwIHYmXf7gjfwis3CY6+FNNs3ej79+gWFEVrZYhwOlT TL0Hd+2Yt6TfeM8P18uWMqrbxvPEkgHSzMS2j4UEMVB69M4F07QUQG0/L 7c7i4etdE2z9oz8PILQ0v4FIsj7jKNoeXhEDTkBz6hLJrhVhNS76xHeWf rCbWUtb/EdlNo3EF604uj1VJXizMYJu8jp9KcA+DPJ53OttJQVKz5jPmw RtGpCXeOezn6huhYxNkToLR9avrSkvV7DPV6g2pauu6X8dbKZNXu7VtPD +sBXNlJZl0VRR/Kj+l6OQNoPQGIK3c4L/0JuvLy5m0L96KsCnGcLWLy8M A==; X-CSE-ConnectionGUID: IhbozfsNTXK+pLi4gjjqOQ== X-CSE-MsgGUID: DOVT0cfURoSWhD5leIGNfg== X-IronPort-AV: E=McAfee;i="6800,10657,11680"; a="70334356" X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="70334356" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:10 -0800 X-CSE-ConnectionGUID: lfwQx8BUQOSrKrQYLGCj/g== X-CSE-MsgGUID: bwnZhz1aSw+6g1vwXlOwrA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="237697059" Received: from 984fee019967.jf.intel.com ([10.23.153.244]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:10 -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, Chao Gao , Jonathan Cameron , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v3 04/26] coco/tdx-host: Introduce a "tdx_host" device Date: Fri, 23 Jan 2026 06:55:12 -0800 Message-ID: <20260123145645.90444-5-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260123145645.90444-1-chao.gao@intel.com> References: <20260123145645.90444-1-chao.gao@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" TDX depends on a platform firmware module that is invoked via instructions similar to vmenter (i.e. enter into a new privileged "root-mode" context to manage private memory and private device mechanisms). It is a software construct that depends on the CPU vmxon state to enable invocation of TDX-module ABIs. Unlike other Trusted Execution Environment (TEE) platform implementations that employ a firmware module running on a PCI device with an MMIO mailbox for communication, TDX has no hardware device to point to as the TEE Secure Manager (TSM). Create a virtual device not only to align with other implementations but also to make it easier to - expose metadata (e.g., TDX module version, seamldr version etc) to the userspace as device attributes - implement firmware uploader APIs which are tied to a device. This is needed to support TDX module runtime updates - enable TDX Connect which will share a common infrastructure with other platform implementations. In the TDX Connect context, every architecture has a TSM, represented by a PCIe or virtual device. The new "tdx_host" device will serve the TSM role. A faux device is used as for TDX because the TDX module is singular within the system and lacks associated platform resources. Using a faux device eliminates the need to create a stub bus. The call to tdx_get_sysinfo() ensures that the TDX Module is ready to provide services. Note that AMD has a PCI device for the PSP for SEV and ARM CCA will likely have a faux device [1]. Co-developed-by: Xu Yilun Signed-off-by: Xu Yilun Signed-off-by: Dan Williams Signed-off-by: Chao Gao Reviewed-by: Jonathan Cameron Link: https://lore.kernel.org/all/2025073035-bulginess-rematch-b92e@gregkh/= # [1] Reviewed-by: Tony Lindgren Reviewed-by: Xu Yilun --- v3: - add Jonathan's reviewed-by - add tdx_get_sysinfo() in module_init() to ensure the TDX Module is up and running. - note in the changelog that both AMD and ARM have devices for coco --- arch/x86/virt/vmx/tdx/tdx.c | 2 +- drivers/virt/coco/Kconfig | 2 ++ drivers/virt/coco/Makefile | 1 + drivers/virt/coco/tdx-host/Kconfig | 10 +++++++ drivers/virt/coco/tdx-host/Makefile | 1 + drivers/virt/coco/tdx-host/tdx-host.c | 43 +++++++++++++++++++++++++++ 6 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 drivers/virt/coco/tdx-host/Kconfig create mode 100644 drivers/virt/coco/tdx-host/Makefile create mode 100644 drivers/virt/coco/tdx-host/tdx-host.c diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index b44723ef4a14..a0990c5dd78d 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -1434,7 +1434,7 @@ const struct tdx_sys_info *tdx_get_sysinfo(void) =20 return p; } -EXPORT_SYMBOL_FOR_KVM(tdx_get_sysinfo); +EXPORT_SYMBOL_FOR_MODULES(tdx_get_sysinfo, "kvm-intel,tdx-host"); =20 u32 tdx_get_nr_guest_keyids(void) { diff --git a/drivers/virt/coco/Kconfig b/drivers/virt/coco/Kconfig index df1cfaf26c65..f7691f64fbe3 100644 --- a/drivers/virt/coco/Kconfig +++ b/drivers/virt/coco/Kconfig @@ -17,5 +17,7 @@ source "drivers/virt/coco/arm-cca-guest/Kconfig" source "drivers/virt/coco/guest/Kconfig" endif =20 +source "drivers/virt/coco/tdx-host/Kconfig" + config TSM bool diff --git a/drivers/virt/coco/Makefile b/drivers/virt/coco/Makefile index cb52021912b3..b323b0ae4f82 100644 --- a/drivers/virt/coco/Makefile +++ b/drivers/virt/coco/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_EFI_SECRET) +=3D efi_secret/ obj-$(CONFIG_ARM_PKVM_GUEST) +=3D pkvm-guest/ obj-$(CONFIG_SEV_GUEST) +=3D sev-guest/ obj-$(CONFIG_INTEL_TDX_GUEST) +=3D tdx-guest/ +obj-$(CONFIG_INTEL_TDX_HOST) +=3D tdx-host/ obj-$(CONFIG_ARM_CCA_GUEST) +=3D arm-cca-guest/ obj-$(CONFIG_TSM) +=3D tsm-core.o obj-$(CONFIG_TSM_GUEST) +=3D guest/ diff --git a/drivers/virt/coco/tdx-host/Kconfig b/drivers/virt/coco/tdx-hos= t/Kconfig new file mode 100644 index 000000000000..e58bad148a35 --- /dev/null +++ b/drivers/virt/coco/tdx-host/Kconfig @@ -0,0 +1,10 @@ +config TDX_HOST_SERVICES + tristate "TDX Host Services Driver" + depends on INTEL_TDX_HOST + default m + help + Enable access to TDX host services like module update and + extensions (e.g. TDX Connect). + + Say y or m if enabling support for confidential virtual machine + support (CONFIG_INTEL_TDX_HOST). The module is called tdx_host.ko diff --git a/drivers/virt/coco/tdx-host/Makefile b/drivers/virt/coco/tdx-ho= st/Makefile new file mode 100644 index 000000000000..e61e749a8dff --- /dev/null +++ b/drivers/virt/coco/tdx-host/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_TDX_HOST_SERVICES) +=3D tdx-host.o diff --git a/drivers/virt/coco/tdx-host/tdx-host.c b/drivers/virt/coco/tdx-= host/tdx-host.c new file mode 100644 index 000000000000..c77885392b09 --- /dev/null +++ b/drivers/virt/coco/tdx-host/tdx-host.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * TDX host user interface driver + * + * Copyright (C) 2025 Intel Corporation + */ + +#include +#include +#include + +#include +#include + +static const struct x86_cpu_id tdx_host_ids[] =3D { + X86_MATCH_FEATURE(X86_FEATURE_TDX_HOST_PLATFORM, NULL), + {} +}; +MODULE_DEVICE_TABLE(x86cpu, tdx_host_ids); + +static struct faux_device *fdev; + +static int __init tdx_host_init(void) +{ + if (!x86_match_cpu(tdx_host_ids) || !tdx_get_sysinfo()) + return -ENODEV; + + fdev =3D faux_device_create(KBUILD_MODNAME, NULL, NULL); + if (!fdev) + return -ENODEV; + + return 0; +} +module_init(tdx_host_init); + +static void __exit tdx_host_exit(void) +{ + faux_device_destroy(fdev); +} +module_exit(tdx_host_exit); + +MODULE_DESCRIPTION("TDX Host Services"); +MODULE_LICENSE("GPL"); --=20 2.47.3 From nobody Sat Feb 7 08:27:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 65FF833508E; Fri, 23 Jan 2026 15:00:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180420; cv=none; b=qM6cqLF5rXzdTrpJ2LHfVBugbhKtrtOwrSsoOIbkLPIKQ2vhv6TbOEVM8cwILCdtTk710Mgqkc5S2opZZ8sw9+ViIMP+Z9KUHRVU4l8NSPaXyupwXdCyuOHfvpylGPFsJR5uWgF9o/zYwiMv6rnkxI0sW8EgubUn8LhDs1OyAek= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180420; c=relaxed/simple; bh=tCpcmovCbl3/A+tZy+bcjGs0zPptOmPyXEVVuw3kWpQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YqFpBLFJrL0dzgXINrdwwnInVw9sYsQvDJ62oc4Uoc5Aq/ooS8SVWjdin0j+au1klIc489pqDoMolmQ4RQuF79E574YKxVKXj5TmNsvRfxJKg9YtaiNDtGfn/lpWSrkqkrPHYFP2lfzXKxXREh9Aa+1W2SkXB3bR346L+jSRd/s= 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=nMZPPq74; arc=none smtp.client-ip=192.198.163.17 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="nMZPPq74" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1769180417; x=1800716417; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=tCpcmovCbl3/A+tZy+bcjGs0zPptOmPyXEVVuw3kWpQ=; b=nMZPPq74RlziaJgRzpYOnYxMHSTnGlcIK02J5cLpl6RAUnDjmDdkaYzj RqriNMPcXP8YkAjwW+A/FHsZUu4uL9L9CImvTolIZmTF4eazHIoXFFXyH 1jN7FfhcF0KjNvnMAEJLdG9mtmAJ3VWlE+KBIkqZ3Lh+Z7TS0kOLsaKDr 7SQJhm2/TZitIYOk4vNul06kYq9RELSjOAjmyfClxxrQrkPHwoRAfboJO eOXto/5BFG4Hvxma1pZ2igw4rZfkvrIK+tcxOntDYBrCG596W6APiqRbW 7KS4a3eHo7Qm4dqgIy1LbWTZK7wTh44cuUvDW5i+WuQxp6PLMPKqH4UKh Q==; X-CSE-ConnectionGUID: jOMpvJAJRBqVQq36oFuooQ== X-CSE-MsgGUID: lIqcj1a0Roe7DpZGaM2tfA== X-IronPort-AV: E=McAfee;i="6800,10657,11680"; a="70334364" X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="70334364" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:10 -0800 X-CSE-ConnectionGUID: 1Sr+YLbfRsqwmaOVUyqbeg== X-CSE-MsgGUID: nujEMQ3ESBKhi9kvOv0uNg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="237697084" Received: from 984fee019967.jf.intel.com ([10.23.153.244]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:10 -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, Chao Gao Subject: [PATCH v3 05/26] coco/tdx-host: Expose TDX Module version Date: Fri, 23 Jan 2026 06:55:13 -0800 Message-ID: <20260123145645.90444-6-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260123145645.90444-1-chao.gao@intel.com> References: <20260123145645.90444-1-chao.gao@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" For TDX Module updates, userspace needs to select compatible update versions based on the current module version. This design delegates module selection complexity to userspace because TDX Module update policies are complex and version series are platform-specific. For example, the 1.5.x series is for certain platform generations, while the 2.0.x series is intended for others. And TDX Module 1.5.x may be updated to 1.5.y but not to 1.5.y+1. Expose the TDX Module version to userspace via sysfs to aid module selection. Since the TDX faux device will drive module updates, expose the version as its attribute. This approach follows the pattern used by microcode updates and other CoCo implementations: 1. AMD has a PCI device for the PSP for SEV which provides an existing place to hang their equivalent metadata. 2. ARM CCA will likely have a faux device (although it isn't obvious if they have a need to export version information there) [1] 3. Microcode revisions are exposed as CPU device attributes One bonus of exposing TDX Module version via sysfs is: TDX Module version information remains available even after dmesg logs are cleared. Signed-off-by: Chao Gao Link: https://lore.kernel.org/all/2025073035-bulginess-rematch-b92e@gregkh/= # [1] Reviewed-by: Binbin Wu Reviewed-by: Tony Lindgren Reviewed-by: Xu Yilun --- v3: - Justify the sysfs ABI choice and expand background on other CoCo implementations. --- .../ABI/testing/sysfs-devices-faux-tdx-host | 6 +++++ drivers/virt/coco/tdx-host/tdx-host.c | 26 ++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 Documentation/ABI/testing/sysfs-devices-faux-tdx-host diff --git a/Documentation/ABI/testing/sysfs-devices-faux-tdx-host b/Docume= ntation/ABI/testing/sysfs-devices-faux-tdx-host new file mode 100644 index 000000000000..901abbae2e61 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-devices-faux-tdx-host @@ -0,0 +1,6 @@ +What: /sys/devices/faux/tdx_host/version +Contact: linux-coco@lists.linux.dev +Description: (RO) Report the version of the loaded TDX Module. The TDX Mod= ule + version is formatted as x.y.z, where "x" is the major version, + "y" is the minor version and "z" is the update version. Versions + are used for bug reporting, TDX Module updates and etc. diff --git a/drivers/virt/coco/tdx-host/tdx-host.c b/drivers/virt/coco/tdx-= host/tdx-host.c index c77885392b09..0424933b2560 100644 --- a/drivers/virt/coco/tdx-host/tdx-host.c +++ b/drivers/virt/coco/tdx-host/tdx-host.c @@ -8,6 +8,7 @@ #include #include #include +#include =20 #include #include @@ -18,6 +19,29 @@ static const struct x86_cpu_id tdx_host_ids[] =3D { }; MODULE_DEVICE_TABLE(x86cpu, tdx_host_ids); =20 +static ssize_t version_show(struct device *dev, struct device_attribute *a= ttr, + char *buf) +{ + const struct tdx_sys_info *tdx_sysinfo =3D tdx_get_sysinfo(); + const struct tdx_sys_info_version *ver; + + if (!tdx_sysinfo) + return -ENXIO; + + ver =3D &tdx_sysinfo->version; + + return sysfs_emit(buf, "%u.%u.%02u\n", ver->major_version, + ver->minor_version, + ver->update_version); +} +static DEVICE_ATTR_RO(version); + +static struct attribute *tdx_host_attrs[] =3D { + &dev_attr_version.attr, + NULL, +}; +ATTRIBUTE_GROUPS(tdx_host); + static struct faux_device *fdev; =20 static int __init tdx_host_init(void) @@ -25,7 +49,7 @@ static int __init tdx_host_init(void) if (!x86_match_cpu(tdx_host_ids) || !tdx_get_sysinfo()) return -ENODEV; =20 - fdev =3D faux_device_create(KBUILD_MODNAME, NULL, NULL); + fdev =3D faux_device_create_with_groups(KBUILD_MODNAME, NULL, NULL, tdx_h= ost_groups); if (!fdev) return -ENODEV; =20 --=20 2.47.3 From nobody Sat Feb 7 08:27:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 7EE4B1ADC83; Fri, 23 Jan 2026 15:00:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180421; cv=none; b=EvwhRnfFxmKuyDkCyzR+mY05o1hNIDvtPF9nA3xUaBThMC3Snpp4mg5noVurGLvFwH6fPuIMYHkum/eGULVEeV5LSOuckI8T1qoPGJBewTgnPDSPrUnLMXeTKtijQ0yIiw+pjL+T3nrA5RRmqEeapoM6sV/WMw/NDl3Zapktmec= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180421; c=relaxed/simple; bh=EUdvM04qz2HU4Z4hCMb6uYQfEZu2qW0yXwhkH90a0KQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BOipTj1zUduf5oDYaKWM7duFG73w0SkMuJRBleY3mVpl2bw+x2iUKoQi7V1QSNw3OPREZIioyWJCv2S03b1kl2rw5N5EIvdZCPmI4oMxv/znNrLdIBEoqHs5EVpIchA4d+Hl5oL7KHESSzC0vGzVYnPJ5RPsschPb59fUTqC8b4= 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=OPRxGL2S; arc=none smtp.client-ip=192.198.163.17 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="OPRxGL2S" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1769180418; x=1800716418; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=EUdvM04qz2HU4Z4hCMb6uYQfEZu2qW0yXwhkH90a0KQ=; b=OPRxGL2SD4rjrd9v3jCz9qG9estkNDJOERlGqwPRmLIupeI3TXCwbuta xPNNYv+vz+/tbwv5f1AtWbO6DD/S578Lb5x+S8aPVGe4IUQL+h0wSAL5u UVF8BGio1VGHiWLJTZdevjn2x503xePWxt67lihBGWEX/OIB/wrtYSZNz URUZUGd1ATrjGQ0o+RW0v63ZLDSgrg+I1iJvw3yCH/n4kIMcasSbPawRk 43g/5rby8p/r4CZYCYLk5UcDnVl+LoYzM8eQI5zd5Qco+Uaou/qwvW/zk bvli1t3I34kLhr0DTdA21HaCSbTuG9aO6Jl/CePE4MojjhFPZJM/64IgC w==; X-CSE-ConnectionGUID: 49WS1UWMQBSVmP0sJl9HNA== X-CSE-MsgGUID: Wq+vjex0QCShlQJ9O+dM6w== X-IronPort-AV: E=McAfee;i="6800,10657,11680"; a="70334372" X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="70334372" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:11 -0800 X-CSE-ConnectionGUID: Vg43tIqvR7qE5IldtlceBQ== X-CSE-MsgGUID: hVIuuNeVSl+O5J88qChV7g== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="237697090" Received: from 984fee019967.jf.intel.com ([10.23.153.244]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:11 -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, Chao Gao , Farrah Chen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v3 06/26] x86/virt/tdx: Prepare to support P-SEAMLDR SEAMCALLs Date: Fri, 23 Jan 2026 06:55:14 -0800 Message-ID: <20260123145645.90444-7-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260123145645.90444-1-chao.gao@intel.com> References: <20260123145645.90444-1-chao.gao@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" P-SEAMLDR is another component alongside the TDX module within the protected SEAM range. P-SEAMLDR can update the TDX module at runtime. Software can talk with P-SEAMLDR via SEAMCALLs with the bit 63 of RAX (leaf number) set to 1 (a.k.a P-SEAMLDR SEAMCALLs). P-SEAMLDR SEAMCALLs differ from SEAMCALLs of the TDX module in terms of error codes and the handling of the current VMCS. In preparation for adding support for P-SEAMLDR SEAMCALLs, do the two following changes to SEAMCALL low-level helpers: 1) Tweak sc_retry() to retry on "lack of entropy" errors reported by P-SEAMLDR because it uses a different error code. 2) Add seamldr_err() to log error messages on P-SEAMLDR SEAMCALL failures. Signed-off-by: Chao Gao Tested-by: Farrah Chen Reviewed-by: Binbin Wu Reviewed-by: Tony Lindgren --- Add seamldr_prerr() as a macro to be consistent with existing code. If maintainers would like to switch these to static inline functions then I would be happy to add a new patch to convert existing macros to static inline functions and build on that. v3: - print P-SEAMLDR leaf numbers in hex - use %# to print error code [Binbin] - mark the is_seamldr_call() call as unlikely [Binbin] - remove the function to get the error code for retry from leaf numbers [Yilun] v2: - use a macro rather than an inline function for seamldr_err() for consistency. --- arch/x86/virt/vmx/tdx/seamcall.h | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/arch/x86/virt/vmx/tdx/seamcall.h b/arch/x86/virt/vmx/tdx/seamc= all.h index 0912e03fabfe..256f71d6ca70 100644 --- a/arch/x86/virt/vmx/tdx/seamcall.h +++ b/arch/x86/virt/vmx/tdx/seamcall.h @@ -34,15 +34,28 @@ static __always_inline u64 __seamcall_dirty_cache(sc_fu= nc_t func, u64 fn, return func(fn, args); } =20 +#define SEAMLDR_RND_NO_ENTROPY 0x8000000000030001ULL + +#define SEAMLDR_SEAMCALL_MASK _BITUL(63) + +static inline bool is_seamldr_call(u64 fn) +{ + return fn & SEAMLDR_SEAMCALL_MASK; +} + static __always_inline u64 sc_retry(sc_func_t func, u64 fn, struct tdx_module_args *args) { + u64 retry_code =3D TDX_RND_NO_ENTROPY; int retry =3D RDRAND_RETRY_LOOPS; u64 ret; =20 + if (unlikely(is_seamldr_call(fn))) + retry_code =3D SEAMLDR_RND_NO_ENTROPY; + do { ret =3D func(fn, args); - } while (ret =3D=3D TDX_RND_NO_ENTROPY && --retry); + } while (ret =3D=3D retry_code && --retry); =20 return ret; } @@ -68,6 +81,16 @@ static inline void seamcall_err_ret(u64 fn, u64 err, args->r9, args->r10, args->r11); } =20 +static inline void seamldr_err(u64 fn, u64 err, struct tdx_module_args *ar= gs) +{ + /* + * Note: P-SEAMLDR leaf numbers are printed in hex as they have + * bit 63 set, making them hard to read and understand if printed + * in decimal + */ + pr_err("P-SEAMLDR (%llx) failed: %#016llx\n", fn, err); +} + static __always_inline int sc_retry_prerr(sc_func_t func, sc_err_func_t err_func, u64 fn, struct tdx_module_args *args) @@ -96,4 +119,7 @@ static __always_inline int sc_retry_prerr(sc_func_t func, #define seamcall_prerr_ret(__fn, __args) \ sc_retry_prerr(__seamcall_ret, seamcall_err_ret, (__fn), (__args)) =20 +#define seamldr_prerr(__fn, __args) \ + sc_retry_prerr(__seamcall, seamldr_err, (__fn), (__args)) + #endif --=20 2.47.3 From nobody Sat Feb 7 08:27:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 A9834337B8C; Fri, 23 Jan 2026 15:00:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180422; cv=none; b=WTQ1TuE45717hKRs4fMwZH3DJyeuNlw8UlPNbPNyGWpxhqTUPzDK+3SJ2A+2nep/rjrl4NqwmDFqHArMqil7EA/NJ2ZEn+Zv61uEH5997dTdwop9mkQffua5S/2JqfWSTnr4R0v2wbzFq4Gf7vTg/cIEPZb1+o3fF3zsO6EElhM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180422; c=relaxed/simple; bh=l6gRODA9DOWaUAZIpnN8DaS/2uBMMYa5BOi5JNoTwvw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=QdLvTLLIhchH4J+dQYiWIB4q7PGWY7LotDvftQBiG3MP6MnieEjZyGoX/43Hjw+CtSaAYScDUkjwsKC8gF+cWdVU80J1pU0fEMvT3KqulONwus0Z036itk8AJrMMA6Bz2PtB2u5dfexPXYkDC//TkV7iN8ik++s8WICPOTPMOpM= 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=nMwm8/md; arc=none smtp.client-ip=192.198.163.17 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="nMwm8/md" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1769180418; x=1800716418; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=l6gRODA9DOWaUAZIpnN8DaS/2uBMMYa5BOi5JNoTwvw=; b=nMwm8/mdkVelts5zPg+fKp1o04x533kZ0r/RVOg4E9SKlgpq8T4CMGcL QD7YMeffX4vn4+CEaMpHxcFUhR5R/R49N4agts0Kl7+1dO8DdxvCd5beH rpIZ/mShS8GYAYSHXdBcFdQ/Hb9kWELpcTtmivpnxfgYqfmiUfwg83VX/ 8qIkU02v2orNV7Zr2myD/wUzwo2bIQRZFwdg1uU8YijNM+dG/foYxC6C5 t/qpSTPblV/VromZ8UqvcvP/0jEBh1ChHOslx1JeIrlLzhANMibrDk46Z FVtVBtpk11HAjNw6Y3sjPwstiBULBhJxrjMT1PvqfcM/Yyt7eiV2E/WRB w==; X-CSE-ConnectionGUID: CnxQhNetThei/XY3NEMJAA== X-CSE-MsgGUID: +SkDaSOjTeODolDAAz8tUg== X-IronPort-AV: E=McAfee;i="6800,10657,11680"; a="70334381" X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="70334381" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:12 -0800 X-CSE-ConnectionGUID: M96KETEJQAW17m2phGDAbg== X-CSE-MsgGUID: dlx+zI7kT9udG9MJaOYtEw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="237697099" Received: from 984fee019967.jf.intel.com ([10.23.153.244]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:11 -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, Chao Gao , Farrah Chen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v3 07/26] x86/virt/seamldr: Introduce a wrapper for P-SEAMLDR SEAMCALLs Date: Fri, 23 Jan 2026 06:55:15 -0800 Message-ID: <20260123145645.90444-8-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260123145645.90444-1-chao.gao@intel.com> References: <20260123145645.90444-1-chao.gao@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Software needs to talk with P-SEAMLDR via P-SEAMLDR SEAMCALLs. So, add a wrapper for P-SEAMLDR SEAMCALLs. Save and restore the current VMCS using VMPTRST and VMPTRLD instructions to avoid breaking KVM. Doing so is because P-SEAMLDR SEAMCALLs would invalidate the current VMCS as documented in Intel=C2=AE Trust Domain CPU Architectural Extensions (May 2021 edition) Chapter 2.3 [1]: SEAMRET from the P-SEAMLDR clears the current VMCS structure pointed to by the current-VMCS pointer. A VMM that invokes the P-SEAMLDR using SEAMCALL must reload the current-VMCS, if required, using the VMPTRLD instruction. Disable interrupts to prevent KVM code from interfering with P-SEAMLDR SEAMCALLs. For example, if a vCPU is scheduled before the current VMCS is restored, it may encounter an invalid current VMCS, causing its VMX instruction to fail. Additionally, if KVM sends IPIs to invalidate a current VMCS and the invalidation occurs right after the current VMCS is saved, that VMCS will be reloaded after P-SEAMLDR SEAMCALLs, leading to unexpected behavior. NMIs are not a problem, as the only scenario where instructions relying on the current-VMCS are used is during guest PMI handling in KVM. This occurs immediately after VM exits with IRQ and NMI disabled, ensuring no interference with P-SEAMLDR SEAMCALLs. Signed-off-by: Chao Gao Tested-by: Farrah Chen Link: https://cdrdv2.intel.com/v1/dl/getContent/733582 # [1] Reviewed-by: Binbin Wu Reviewed-by: Tony Lindgren --- v2: - don't create a new, inferior framework to save/restore VMCS - use human-friendly language, just "current VMCS" rather than SDM term "current-VMCS pointer" - don't mix guard() with goto --- arch/x86/virt/vmx/tdx/Makefile | 1 + arch/x86/virt/vmx/tdx/seamldr.c | 56 ++++++++++++++++++++++++++++++ drivers/virt/coco/tdx-host/Kconfig | 10 ++++++ 3 files changed, 67 insertions(+) create mode 100644 arch/x86/virt/vmx/tdx/seamldr.c diff --git a/arch/x86/virt/vmx/tdx/Makefile b/arch/x86/virt/vmx/tdx/Makefile index 90da47eb85ee..26aea3531c36 100644 --- a/arch/x86/virt/vmx/tdx/Makefile +++ b/arch/x86/virt/vmx/tdx/Makefile @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only obj-y +=3D seamcall.o tdx.o +obj-$(CONFIG_INTEL_TDX_MODULE_UPDATE) +=3D seamldr.o diff --git a/arch/x86/virt/vmx/tdx/seamldr.c b/arch/x86/virt/vmx/tdx/seamld= r.c new file mode 100644 index 000000000000..b99d73f7bb08 --- /dev/null +++ b/arch/x86/virt/vmx/tdx/seamldr.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright(c) 2025 Intel Corporation. + * + * Intel TDX module runtime update + */ +#define pr_fmt(fmt) "seamldr: " fmt + +#include +#include + +#include "seamcall.h" + +static __maybe_unused int seamldr_call(u64 fn, struct tdx_module_args *arg= s) +{ + unsigned long flags; + u64 vmcs; + int ret; + + if (!is_seamldr_call(fn)) + return -EINVAL; + + /* + * SEAMRET from P-SEAMLDR invalidates the current VMCS. Save/restore + * the VMCS across P-SEAMLDR SEAMCALLs to avoid clobbering KVM state. + * Disable interrupts as KVM is allowed to do VMREAD/VMWRITE in IRQ + * context (but not NMI context). + */ + local_irq_save(flags); + + asm goto("1: vmptrst %0\n\t" + _ASM_EXTABLE(1b, %l[error]) + : "=3Dm" (vmcs) : : "cc" : error); + + ret =3D seamldr_prerr(fn, args); + + /* + * Restore the current VMCS pointer. VMPTSTR "returns" all ones if the + * current VMCS is invalid. + */ + if (vmcs !=3D -1ULL) { + asm goto("1: vmptrld %0\n\t" + "jna %l[error]\n\t" + _ASM_EXTABLE(1b, %l[error]) + : : "m" (vmcs) : "cc" : error); + } + + local_irq_restore(flags); + return ret; + +error: + local_irq_restore(flags); + + WARN_ONCE(1, "Failed to save/restore the current VMCS"); + return -EIO; +} diff --git a/drivers/virt/coco/tdx-host/Kconfig b/drivers/virt/coco/tdx-hos= t/Kconfig index e58bad148a35..6a9199e6c2c6 100644 --- a/drivers/virt/coco/tdx-host/Kconfig +++ b/drivers/virt/coco/tdx-host/Kconfig @@ -8,3 +8,13 @@ config TDX_HOST_SERVICES =20 Say y or m if enabling support for confidential virtual machine support (CONFIG_INTEL_TDX_HOST). The module is called tdx_host.ko + +config INTEL_TDX_MODULE_UPDATE + bool "Intel TDX module runtime update" + depends on TDX_HOST_SERVICES + help + This enables the kernel to support TDX module runtime update. This + allows the admin to update the TDX module to another compatible + version without the need to terminate running TDX guests. + + If unsure, say N. --=20 2.47.3 From nobody Sat Feb 7 08:27:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 52D7933C50E; Fri, 23 Jan 2026 15:00:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180425; cv=none; b=tXPSIZU/kHKFQ/NZ57qE+JNMbkPa4z7YC/D8CQB2JGzcLrDylkD360Q0qZgTzrY+PBa1qfU+Idx0DXGAy3lswPVl+gZOzAEQQfxJeiLGJKOiC32XY/RSsejSRulGZJteFHXfsBZpg+wlger6iVSIi8Jfe6yR4++VPrQNOVD2LBY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180425; c=relaxed/simple; bh=5q4zqWajw/8RUodFT+CwqmTk6wtdoZ/kJ+GQJqa5ufU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FyE58XjNAbwdpbQGhbx78V8AJFy00uhleQ0cdMyGMaGQ6oFc9Gf+eOxeIRDPg/DidNIYivZMhaw3jYhDzZoFScU4Lm0K8PshJ6fymkTrSSFYzzknyvO5gUYroRY1j8c5REZmPTLMObxQQ4Too6BixjvWG4aaFBdfVe+QopBT1YE= 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=do6/lEXu; arc=none smtp.client-ip=192.198.163.17 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="do6/lEXu" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1769180421; x=1800716421; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=5q4zqWajw/8RUodFT+CwqmTk6wtdoZ/kJ+GQJqa5ufU=; b=do6/lEXuqdHN3xuiLeXvxy2yOaP+KE4m5hsHiek1UWhJA/CTOqexwttU 3gNkzvOfUJKX2PSV1TbVonniSG59jmIvF3aX2RJCqxGvTxfP2wNslL6vw cPqVMCVVPqtDI/XxdgcFAlOHa7L5nW3K/FQi6PgB4sc5kDtoNkb/GZBzz yhxRDS0vHSKvZYbI7QVruCSiIKwiX+nCrrLlIObG8Huoye6148Iav3/2P vhKxlXTRjhsd0RhA7VwTcxrseC7FFHfLBFbNtAlz8OsdnWVW0bN/lwl61 ypJDM5XZV7j25dTENyedlisVpc5znoW56Uq9Fj9hOohM4kdhjHDzp+HmI A==; X-CSE-ConnectionGUID: e+dp7VzGQdCsJBizYz7bOQ== X-CSE-MsgGUID: 9Gmy41/PSauL3FYWZ9wsKQ== X-IronPort-AV: E=McAfee;i="6800,10657,11680"; a="70334390" X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="70334390" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:12 -0800 X-CSE-ConnectionGUID: v1yJjE8FR869Sza7hB3BRg== X-CSE-MsgGUID: 7Ue34iN0Tw6r5nEkThgzlg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="237697104" Received: from 984fee019967.jf.intel.com ([10.23.153.244]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:12 -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, Chao Gao , Farrah Chen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v3 08/26] x86/virt/seamldr: Retrieve P-SEAMLDR information Date: Fri, 23 Jan 2026 06:55:16 -0800 Message-ID: <20260123145645.90444-9-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260123145645.90444-1-chao.gao@intel.com> References: <20260123145645.90444-1-chao.gao@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" P-SEAMLDR returns its information e.g., version and supported features, in response to the SEAMLDR.INFO SEAMCALL. This information is useful for userspace. For example, the admin can decide which TDX module versions are compatible with the P-SEAMLDR according to the P-SEAMLDR version. Add and export seamldr_get_info() which retrieves P-SEAMLDR information by invoking SEAMLDR.INFO SEAMCALL in preparation for exposing P-SEAMLDR version and other necessary information to userspace. Signed-off-by: Chao Gao Tested-by: Farrah Chen Reviewed-by: Binbin Wu Reviewed-by: Tony Lindgren --- arch/x86/include/asm/seamldr.h | 27 +++++++++++++++++++++++++++ arch/x86/virt/vmx/tdx/seamldr.c | 17 ++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 arch/x86/include/asm/seamldr.h diff --git a/arch/x86/include/asm/seamldr.h b/arch/x86/include/asm/seamldr.h new file mode 100644 index 000000000000..d1e9f6e16e8d --- /dev/null +++ b/arch/x86/include/asm/seamldr.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_X86_SEAMLDR_H +#define _ASM_X86_SEAMLDR_H + +#include + +struct seamldr_info { + u32 version; + u32 attributes; + u32 vendor_id; + u32 build_date; + u16 build_num; + u16 minor_version; + u16 major_version; + u16 update_version; + u8 reserved0[4]; + u32 num_remaining_updates; + u8 reserved1[224]; +} __packed; + +#ifdef CONFIG_INTEL_TDX_MODULE_UPDATE +const struct seamldr_info *seamldr_get_info(void); +#else +static inline const struct seamldr_info *seamldr_get_info(void) { return N= ULL; } +#endif + +#endif diff --git a/arch/x86/virt/vmx/tdx/seamldr.c b/arch/x86/virt/vmx/tdx/seamld= r.c index b99d73f7bb08..6a83ae405fac 100644 --- a/arch/x86/virt/vmx/tdx/seamldr.c +++ b/arch/x86/virt/vmx/tdx/seamldr.c @@ -9,9 +9,16 @@ #include #include =20 +#include + #include "seamcall.h" =20 -static __maybe_unused int seamldr_call(u64 fn, struct tdx_module_args *arg= s) +/* P-SEAMLDR SEAMCALL leaf function */ +#define P_SEAMLDR_INFO 0x8000000000000000 + +static struct seamldr_info seamldr_info __aligned(256); + +static inline int seamldr_call(u64 fn, struct tdx_module_args *args) { unsigned long flags; u64 vmcs; @@ -54,3 +61,11 @@ static __maybe_unused int seamldr_call(u64 fn, struct td= x_module_args *args) WARN_ONCE(1, "Failed to save/restore the current VMCS"); return -EIO; } + +const struct seamldr_info *seamldr_get_info(void) +{ + struct tdx_module_args args =3D { .rcx =3D __pa(&seamldr_info) }; + + return seamldr_call(P_SEAMLDR_INFO, &args) ? NULL : &seamldr_info; +} +EXPORT_SYMBOL_FOR_MODULES(seamldr_get_info, "tdx-host"); --=20 2.47.3 From nobody Sat Feb 7 08:27:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 E199E33506B; Fri, 23 Jan 2026 15:00:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180426; cv=none; b=Eda+eZ6my95SkgfCiKyUJF6UolEuQ0N0hHeJ5edGrh6EK3bWOnlgVBrcqbuSPI5iwa7ScLINPyI51uBt+D1uPcJrLwaDnUT30iHtGeh2uH4zjUVIRDshFJqyCeYtQPzdGirX747TYO/vPqmbFiIHW9RqsOmsLkr0UbWLGRh2Y+I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180426; c=relaxed/simple; bh=LmLmoBJLYp1Fw5ImScOvQ6T5aiGshRkqk4yUpZCR5VE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=U4Xg+vATyYNorwRnGn9MTPs5Fw/e4eZvOk1uiRnFovCe8ZA1a4bRdTakY3Ql33x2oyxM5VPejAEjiOsvLMdIqpERuglY/O7O3NLyre1J3G5EX+JIaky+f1s3a5uaV4RJHwEpVui9/grB7GustCJgoW7G9YnkZrPG1yYaBI+Acsw= 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=PLedWdvX; arc=none smtp.client-ip=192.198.163.17 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="PLedWdvX" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1769180422; x=1800716422; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=LmLmoBJLYp1Fw5ImScOvQ6T5aiGshRkqk4yUpZCR5VE=; b=PLedWdvXGHz+41kKF1YH4wlpuZEcl3Qou6VM3g3ZyT+Z73yiuV36oFXb 8m+LVWjf9ECAFFAw38iKUv46di6Ss5nY2dkHsnrNVNk2foDCwsooH/ZdU 3OCV88gKW6vsRpC5BF5mO3WJ4+kqL0CEk2UxzlJBPUWlBNwLiFXPz1Y0p Ah+lBmc+BKzui8GhNiRGqpvtGGWFTAceqmCmh8vDwn7K9q39Y6ebct5Nn MJkRyOgnT07L0twK2hKU65MvIu9yHeAiarSLgzzv4/+bhFeztZ0nL0PYq EHUR7Io7nTpHppndxR6byr4FFcflJjWkM0e+HZtIutI3tK0/d/Y3hyire A==; X-CSE-ConnectionGUID: 2EmG0c08RO2o7ihvjZWREQ== X-CSE-MsgGUID: MPJRTP+ZTWKWj7WnK0xkyQ== X-IronPort-AV: E=McAfee;i="6800,10657,11680"; a="70334396" X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="70334396" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:13 -0800 X-CSE-ConnectionGUID: Lh9ZhzXMQMu36ykEEVeoeA== X-CSE-MsgGUID: 9uN2K5lnT/GK6m5fB1tdeA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="237697115" Received: from 984fee019967.jf.intel.com ([10.23.153.244]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:13 -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, Chao Gao , Farrah Chen Subject: [PATCH v3 09/26] coco/tdx-host: Expose P-SEAMLDR information via sysfs Date: Fri, 23 Jan 2026 06:55:17 -0800 Message-ID: <20260123145645.90444-10-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260123145645.90444-1-chao.gao@intel.com> References: <20260123145645.90444-1-chao.gao@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable TDX Module updates require userspace to select the appropriate module to load. Expose necessary information to facilitate this decision. Two values are needed: - P-SEAMLDR version: for compatibility checks between TDX Module and P-SEAMLDR - num_remaining_updates: indicates how many updates can be performed Expose them as tdx-host device attributes. Signed-off-by: Chao Gao Tested-by: Farrah Chen Reviewed-by: Tony Lindgren --- v3: - use #ifdef rather than .is_visible() to control P-SEAMLDR sysfs visibility [Yilun] --- .../ABI/testing/sysfs-devices-faux-tdx-host | 25 ++++++++ drivers/virt/coco/tdx-host/tdx-host.c | 60 ++++++++++++++++++- 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/Documentation/ABI/testing/sysfs-devices-faux-tdx-host b/Docume= ntation/ABI/testing/sysfs-devices-faux-tdx-host index 901abbae2e61..a3f155977016 100644 --- a/Documentation/ABI/testing/sysfs-devices-faux-tdx-host +++ b/Documentation/ABI/testing/sysfs-devices-faux-tdx-host @@ -4,3 +4,28 @@ Description: (RO) Report the version of the loaded TDX Mod= ule. The TDX Module version is formatted as x.y.z, where "x" is the major version, "y" is the minor version and "z" is the update version. Versions are used for bug reporting, TDX Module updates and etc. + +What: /sys/devices/faux/tdx_host/seamldr/version +Contact: linux-coco@lists.linux.dev +Description: (RO) Report the version of the loaded SEAM loader. The SEAM + loader version is formatted as x.y.z, where "x" is the major + version, "y" is the minor version and "z" is the update version. + Versions are used for bug reporting and compatibility check. + +What: /sys/devices/faux/tdx_host/seamldr/num_remaining_updates +Contact: linux-coco@lists.linux.dev +Description: (RO) Report the number of remaining updates that can be perfo= rmed. + The CPU keeps track of TCB versions for each TDX Module that + has been loaded. Since this tracking database has finite + capacity, there's a maximum number of Module updates that can + be performed. + + After each successful update, the number reduces by one. Once it + reaches zero, further updates will fail until next reboot. The + number is always zero if P-SEAMLDR doesn't support updates. + + See Intel=C2=AE Trust Domain Extensions - SEAM Loader (SEAMLDR) + Interface Specification Chapter 3.3 "SEAMLDR_INFO" and Chapter + 4.2 "SEAMLDR.INSTALL" for more information. The documentation is + available at: + https://cdrdv2-public.intel.com/739045/intel-tdx-seamldr-interface-speci= fication.pdf diff --git a/drivers/virt/coco/tdx-host/tdx-host.c b/drivers/virt/coco/tdx-= host/tdx-host.c index 0424933b2560..f4ce89522806 100644 --- a/drivers/virt/coco/tdx-host/tdx-host.c +++ b/drivers/virt/coco/tdx-host/tdx-host.c @@ -11,6 +11,7 @@ #include =20 #include +#include #include =20 static const struct x86_cpu_id tdx_host_ids[] =3D { @@ -40,7 +41,64 @@ static struct attribute *tdx_host_attrs[] =3D { &dev_attr_version.attr, NULL, }; -ATTRIBUTE_GROUPS(tdx_host); + +struct attribute_group tdx_host_group =3D { + .attrs =3D tdx_host_attrs, +}; + +#ifdef CONFIG_INTEL_TDX_MODULE_UPDATE +static ssize_t seamldr_version_show(struct device *dev, struct device_attr= ibute *attr, + char *buf) +{ + const struct seamldr_info *info =3D seamldr_get_info(); + + if (!info) + return -ENXIO; + + return sysfs_emit(buf, "%u.%u.%02u\n", info->major_version, + info->minor_version, + info->update_version); +} + +static ssize_t num_remaining_updates_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + const struct seamldr_info *info =3D seamldr_get_info(); + + if (!info) + return -ENXIO; + + return sysfs_emit(buf, "%u\n", info->num_remaining_updates); +} + +/* + * Open-code DEVICE_ATTR_RO to specify a different 'show' function for + * P-SEAMLDR version as version_show() is used for TDX Module version. + */ +static struct device_attribute dev_attr_seamldr_version =3D + __ATTR(version, 0444, seamldr_version_show, NULL); +static DEVICE_ATTR_RO(num_remaining_updates); + +static struct attribute *seamldr_attrs[] =3D { + &dev_attr_seamldr_version.attr, + &dev_attr_num_remaining_updates.attr, + NULL, +}; + +static struct attribute_group seamldr_group =3D { + .name =3D "seamldr", + .attrs =3D seamldr_attrs, +}; +#endif /* CONFIG_INTEL_TDX_MODULE_UPDATE */ + +static const struct attribute_group *tdx_host_groups[] =3D { + &tdx_host_group, +#ifdef CONFIG_INTEL_TDX_MODULE_UPDATE + &seamldr_group, +#endif + NULL, +}; =20 static struct faux_device *fdev; =20 --=20 2.47.3 From nobody Sat Feb 7 08:27:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 1E1EF2DECC6; Fri, 23 Jan 2026 15:00:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180427; cv=none; b=GsWcKuTy7k46yHnupB6rCriHmbNDEoD5ig8OzqWmUvWWUzzv/fPxowPuvky9M2dfBnuQfOgvPVEuPGccfJtWHsLH9bIC73vd7Z3it/PEvi23saSNnAV2xJnNRccJ2JdVqjO5mLIoGrt0VuMod3+ppqlT9qDk6BmqkYS4tFKT67E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180427; c=relaxed/simple; bh=iyuCaDaAcegyeDCHE8c/aayAPOHbknHM/l0oTLZdxpw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=alSWO39GZ7ZY9pMPE/Cw0vFkSjA0A4p3b2SUkIO+mvqSA4NPhSv3GbGIvynxPOrRSKb1tXV687PXK26x5X24i7y/wbzon0q7wXy8JWF26yMqKjg+xlH1Crht74c2BPiqo0Do71AnCXAH9c3uHOTL2pzOUaQzoPmTfmI7+dk6Jo4= 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=JddqBQZW; arc=none smtp.client-ip=192.198.163.17 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="JddqBQZW" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1769180423; x=1800716423; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=iyuCaDaAcegyeDCHE8c/aayAPOHbknHM/l0oTLZdxpw=; b=JddqBQZWXuL5IrwJFe4k2ZvRvlLDu+xYVJmJQ/bYpIYqSwZ6xjnAPEVe FW/2dWmJCWB+9qhCzgJetGXIja6T8rCUMs93NCRkou2pSa1IFpP5GfM+9 0IyzZqf/ei0Jqd1S7OiPpHh2DHtldDa0cOQh9zANj2hzgjTvQBn5fPpTU OeGV3fipXMWgtk8fxwDBosnPnjHPMxXSvORsa+zdwmPR7SyjCaihhXSIZ pca4DKMhyKa3zgAnBq6l9fFfFhhUIG+F+SQ5choP0OyZOKfWEx1nMnIRZ H1HhAtbdja29ybtbr8G518KKqFqZx+T7FGLo+/6FS3l2Zl84ZHsd09ulb Q==; X-CSE-ConnectionGUID: HbYl/7ElRSieitwF0zCyAQ== X-CSE-MsgGUID: 50PEh2y/TnufUdMQGexMVw== X-IronPort-AV: E=McAfee;i="6800,10657,11680"; a="70334404" X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="70334404" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:14 -0800 X-CSE-ConnectionGUID: skrujS8RSZS5kEeAKUr8ZA== X-CSE-MsgGUID: FCTFCq3ASbSHi/plHAwR+g== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="237697122" Received: from 984fee019967.jf.intel.com ([10.23.153.244]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:14 -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, Chao Gao , Farrah Chen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v3 10/26] coco/tdx-host: Implement FW_UPLOAD sysfs ABI for TDX Module updates Date: Fri, 23 Jan 2026 06:55:18 -0800 Message-ID: <20260123145645.90444-11-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260123145645.90444-1-chao.gao@intel.com> References: <20260123145645.90444-1-chao.gao@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The firmware upload framework provides a standard mechanism for firmware updates by allowing device drivers to expose sysfs interfaces for user-initiated updates. Register with this framework to expose sysfs interfaces for TDX Module updates and implement operations to process data blobs supplied by userspace. Note that: 1. P-SEAMLDR processes the entire update at once rather than chunk-by-chunk, so .write() is called only once per update; so the offset should be always 0. 2. TDX Module Updates complete synchronously within .write(), meaning .poll_complete() is only called after successful updates and therefore always returns success Why fw_upload instead of request_firmware()? =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D The explicit file selection capabilities of fw_upload is preferred over the implicit file selection of request_firmware() for the following reasons: a. Intel distributes all versions of the TDX Module, allowing admins to load any version rather than always defaulting to the latest. This flexibility is necessary because future extensions may require reverting to a previous version to clear fatal errors. b. Some module version series are platform-specific. For example, the 1.5.x series is for certain platform generations, while the 2.0.x series is intended for others. c. The update policy for TDX Module updates is non-linear at times. The latest TDX Module may not be compatible. For example, TDX Module 1.5.x may be updated to 1.5.y but not to 1.5.y+1. This policy is documented separately in a file released along with each TDX Module release. So, the default policy of "request_firmware()" of "always load latest", is not suitable for TDX. Userspace needs to deploy a more sophisticated policy check (e.g., latest may not be compatible), and there is potential operator choice to consider. Just have userspace pick rather than add kernel mechanism to change the default policy of request_firmware(). Signed-off-by: Chao Gao Tested-by: Farrah Chen Reviewed-by: Tony Lindgren --- v3: - clear "cancel_request" in the "prepare" phase [Binbin] - Don't fail the whole tdx-host device if seamldr_init() met an error [Yilun] - Add kdoc for seamldr_install_module() and verify that the input buffer is vmalloc'd. [Yilun] --- arch/x86/include/asm/seamldr.h | 2 + arch/x86/include/asm/tdx.h | 5 ++ arch/x86/virt/vmx/tdx/seamldr.c | 19 ++++ drivers/virt/coco/tdx-host/Kconfig | 2 + drivers/virt/coco/tdx-host/tdx-host.c | 124 +++++++++++++++++++++++++- 5 files changed, 151 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/seamldr.h b/arch/x86/include/asm/seamldr.h index d1e9f6e16e8d..692bde5e9bb4 100644 --- a/arch/x86/include/asm/seamldr.h +++ b/arch/x86/include/asm/seamldr.h @@ -20,8 +20,10 @@ struct seamldr_info { =20 #ifdef CONFIG_INTEL_TDX_MODULE_UPDATE const struct seamldr_info *seamldr_get_info(void); +int seamldr_install_module(const u8 *data, u32 size); #else static inline const struct seamldr_info *seamldr_get_info(void) { return N= ULL; } +static inline int seamldr_install_module(const u8 *data, u32 size) { retur= n -EOPNOTSUPP; } #endif =20 #endif diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h index cb2219302dfc..ffadbf64d0c1 100644 --- a/arch/x86/include/asm/tdx.h +++ b/arch/x86/include/asm/tdx.h @@ -103,6 +103,11 @@ int tdx_enable(void); const char *tdx_dump_mce_info(struct mce *m); const struct tdx_sys_info *tdx_get_sysinfo(void); =20 +static inline bool tdx_supports_runtime_update(const struct tdx_sys_info *= sysinfo) +{ + return false; /* To be enabled when kernel is ready */ +} + int tdx_guest_keyid_alloc(void); u32 tdx_get_nr_guest_keyids(void); void tdx_guest_keyid_free(unsigned int keyid); diff --git a/arch/x86/virt/vmx/tdx/seamldr.c b/arch/x86/virt/vmx/tdx/seamld= r.c index 6a83ae405fac..af7a6621e5e0 100644 --- a/arch/x86/virt/vmx/tdx/seamldr.c +++ b/arch/x86/virt/vmx/tdx/seamldr.c @@ -7,6 +7,7 @@ #define pr_fmt(fmt) "seamldr: " fmt =20 #include +#include #include =20 #include @@ -69,3 +70,21 @@ const struct seamldr_info *seamldr_get_info(void) return seamldr_call(P_SEAMLDR_INFO, &args) ? NULL : &seamldr_info; } EXPORT_SYMBOL_FOR_MODULES(seamldr_get_info, "tdx-host"); + +/** + * seamldr_install_module - Install a new TDX module + * @data: Pointer to the TDX module binary data. It should be vmalloc'd + * memory. + * @size: Size of the TDX module binary data + * + * Returns 0 on success, negative error code on failure. + */ +int seamldr_install_module(const u8 *data, u32 size) +{ + if (!is_vmalloc_addr(data)) + return -EINVAL; + + /* TODO: Update TDX Module here */ + return 0; +} +EXPORT_SYMBOL_FOR_MODULES(seamldr_install_module, "tdx-host"); diff --git a/drivers/virt/coco/tdx-host/Kconfig b/drivers/virt/coco/tdx-hos= t/Kconfig index 6a9199e6c2c6..59aaca2252b0 100644 --- a/drivers/virt/coco/tdx-host/Kconfig +++ b/drivers/virt/coco/tdx-host/Kconfig @@ -12,6 +12,8 @@ config TDX_HOST_SERVICES config INTEL_TDX_MODULE_UPDATE bool "Intel TDX module runtime update" depends on TDX_HOST_SERVICES + select FW_LOADER + select FW_UPLOAD help This enables the kernel to support TDX module runtime update. This allows the admin to update the TDX module to another compatible diff --git a/drivers/virt/coco/tdx-host/tdx-host.c b/drivers/virt/coco/tdx-= host/tdx-host.c index f4ce89522806..06487de2ebfe 100644 --- a/drivers/virt/coco/tdx-host/tdx-host.c +++ b/drivers/virt/coco/tdx-host/tdx-host.c @@ -6,6 +6,7 @@ */ =20 #include +#include #include #include #include @@ -20,6 +21,13 @@ static const struct x86_cpu_id tdx_host_ids[] =3D { }; MODULE_DEVICE_TABLE(x86cpu, tdx_host_ids); =20 +struct tdx_fw_upload_status { + bool cancel_request; +}; + +struct fw_upload *tdx_fwl; +static struct tdx_fw_upload_status tdx_fw_upload_status; + static ssize_t version_show(struct device *dev, struct device_attribute *a= ttr, char *buf) { @@ -100,6 +108,120 @@ static const struct attribute_group *tdx_host_groups[= ] =3D { NULL, }; =20 +static enum fw_upload_err tdx_fw_prepare(struct fw_upload *fwl, + const u8 *data, u32 size) +{ + struct tdx_fw_upload_status *status =3D fwl->dd_handle; + + status->cancel_request =3D false; + + return FW_UPLOAD_ERR_NONE; +} + +static enum fw_upload_err tdx_fw_write(struct fw_upload *fwl, const u8 *da= ta, + u32 offset, u32 size, u32 *written) +{ + struct tdx_fw_upload_status *status =3D fwl->dd_handle; + int ret; + + if (status->cancel_request) { + status->cancel_request =3D false; + return FW_UPLOAD_ERR_CANCELED; + } + + /* + * tdx_fw_write() always processes all data on the first call with + * offset =3D=3D 0. Since it never returns partial success (it either + * succeeds completely or fails), there is no subsequent call with + * non-zero offsets. + */ + WARN_ON_ONCE(offset); + ret =3D seamldr_install_module(data, size); + switch (ret) { + case 0: + *written =3D size; + return FW_UPLOAD_ERR_NONE; + case -EBUSY: + return FW_UPLOAD_ERR_BUSY; + case -EIO: + return FW_UPLOAD_ERR_HW_ERROR; + case -ENOSPC: + return FW_UPLOAD_ERR_WEAROUT; + case -ENOMEM: + return FW_UPLOAD_ERR_RW_ERROR; + default: + return FW_UPLOAD_ERR_FW_INVALID; + } +} + +static enum fw_upload_err tdx_fw_poll_complete(struct fw_upload *fwl) +{ + /* + * TDX Module updates are completed in the previous phase + * (tdx_fw_write()). If any error occurred, the previous phase + * would return an error code to abort the update process. In + * other words, reaching this point means the update succeeded. + */ + return FW_UPLOAD_ERR_NONE; +} + +static void tdx_fw_cancel(struct fw_upload *fwl) +{ + struct tdx_fw_upload_status *status =3D fwl->dd_handle; + + status->cancel_request =3D true; +} + +static const struct fw_upload_ops tdx_fw_ops =3D { + .prepare =3D tdx_fw_prepare, + .write =3D tdx_fw_write, + .poll_complete =3D tdx_fw_poll_complete, + .cancel =3D tdx_fw_cancel, +}; + +static void seamldr_init(struct device *dev) +{ + const struct tdx_sys_info *tdx_sysinfo =3D tdx_get_sysinfo(); + int ret; + + if (WARN_ON_ONCE(!tdx_sysinfo)) + return; + + if (!IS_ENABLED(CONFIG_INTEL_TDX_MODULE_UPDATE)) + return; + + if (!tdx_supports_runtime_update(tdx_sysinfo)) + pr_info("Current TDX Module cannot be updated. Consider BIOS updates\n"); + + tdx_fwl =3D firmware_upload_register(THIS_MODULE, dev, "seamldr_upload", + &tdx_fw_ops, &tdx_fw_upload_status); + ret =3D PTR_ERR_OR_ZERO(tdx_fwl); + if (ret) + pr_err("failed to register module uploader %d\n", ret); +} + +static void seamldr_deinit(void) +{ + if (tdx_fwl) + firmware_upload_unregister(tdx_fwl); +} + +static int tdx_host_probe(struct faux_device *fdev) +{ + seamldr_init(&fdev->dev); + return 0; +} + +static void tdx_host_remove(struct faux_device *fdev) +{ + seamldr_deinit(); +} + +static struct faux_device_ops tdx_host_ops =3D { + .probe =3D tdx_host_probe, + .remove =3D tdx_host_remove, +}; + static struct faux_device *fdev; =20 static int __init tdx_host_init(void) @@ -107,7 +229,7 @@ static int __init tdx_host_init(void) if (!x86_match_cpu(tdx_host_ids) || !tdx_get_sysinfo()) return -ENODEV; =20 - fdev =3D faux_device_create_with_groups(KBUILD_MODNAME, NULL, NULL, tdx_h= ost_groups); + fdev =3D faux_device_create_with_groups(KBUILD_MODNAME, NULL, &tdx_host_o= ps, tdx_host_groups); if (!fdev) return -ENODEV; =20 --=20 2.47.3 From nobody Sat Feb 7 08:27:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 D9FE929E116; Fri, 23 Jan 2026 15:00:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180430; cv=none; b=FwDEFWXtX5oyEsi1WF3AFa3cP9VYMDa0xZl2gE+/JGqUAS/lSv9BbkzCP+fA6mB/cVdMXy600m0XL+FQ4zWWKG/Dd2i4lGRBgWe+XNbogFR1jqZ/vCvgP+AaFKDPzFUxyBwSmoQ6sS4KnYviM9ogcxJtdHm0eigbyHpDJUZ4bg4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180430; c=relaxed/simple; bh=FbJoGMrz+I/JDICtR2MC+0hc/OWifhsA5zpFGgiABbw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UAw/B1Q4YtibHZyaT48bX4sE3J8PlSQAI5jWZ5v0yNS65S+xHmiF2Rw++wo+lb/fi+13OdKnBPB4fwAERS2t+ilQ4xRM8BVxnXKrrRTyTYBZXQe1e9GmwH5MG2gUvdOw2ZuiqkMWbKX0tTnUCvRS1xr0AJ1KEbyMi7ibo4hEH1w= 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=fcdfEeNR; arc=none smtp.client-ip=192.198.163.17 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="fcdfEeNR" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1769180426; x=1800716426; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=FbJoGMrz+I/JDICtR2MC+0hc/OWifhsA5zpFGgiABbw=; b=fcdfEeNRkBntCo4IH5879Lf1XH8CK3+SSYXt/uRdXX2c6WVowc8grY5r NBUhsQVJeFBr+hPEaYmr2Y6IAR6WGxPhwQvB9kSuVPCC5IQDM3+EBv+OX h3iBOvAzeOCl8SzdKU2Kvyqdcvmbu+blnMbpBXD2LlbjbeL3EeRBrYB0/ QK9j3wTKKRMyc+cZsOpQDpHz1p8eqTRnzedpAooKWOzUjd5Rkek2WjUON Rat0Lm3alkYPq2wN9JeN1GceTS7jhHpecqs1BIBxWXbGl29sg8NZoCqkc bSSO9JlDtL9VAMgG6F7sQxzOeUDRW8M/ppvSa2XSAn+E4mgH6y2C1bAID w==; X-CSE-ConnectionGUID: 3oQe7o/cSjKtnTrOE/+NGw== X-CSE-MsgGUID: KeGEol1rRY+h2cq/h45PHQ== X-IronPort-AV: E=McAfee;i="6800,10657,11680"; a="70334413" X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="70334413" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:14 -0800 X-CSE-ConnectionGUID: nZVRL8jsQzSjk9zcZxoLhg== X-CSE-MsgGUID: S2Oub1MUSvebzDIkmmd40g== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="237697125" Received: from 984fee019967.jf.intel.com ([10.23.153.244]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:14 -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, Chao Gao , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v3 11/26] x86/virt/seamldr: Block TDX Module updates if any CPU is offline Date: Fri, 23 Jan 2026 06:55:19 -0800 Message-ID: <20260123145645.90444-12-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260123145645.90444-1-chao.gao@intel.com> References: <20260123145645.90444-1-chao.gao@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" P-SEAMLDR requires every CPU to call the SEAMLDR.INSTALL SEAMCALL during updates. So, every CPU should be online. Check if all CPUs are online and abort the update if any CPU is offline at the very beginning. Without this check, P-SEAMLDR will report failure at a later phase where the old TDX module is gone and TDs have to be killed. Signed-off-by: Chao Gao Reviewed-by: Tony Lindgren Reviewed-by: Xu Yilun --- arch/x86/virt/vmx/tdx/seamldr.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/x86/virt/vmx/tdx/seamldr.c b/arch/x86/virt/vmx/tdx/seamld= r.c index af7a6621e5e0..88388aa0fb5f 100644 --- a/arch/x86/virt/vmx/tdx/seamldr.c +++ b/arch/x86/virt/vmx/tdx/seamldr.c @@ -6,6 +6,8 @@ */ #define pr_fmt(fmt) "seamldr: " fmt =20 +#include +#include #include #include #include @@ -84,6 +86,12 @@ int seamldr_install_module(const u8 *data, u32 size) if (!is_vmalloc_addr(data)) return -EINVAL; =20 + guard(cpus_read_lock)(); + if (!cpumask_equal(cpu_online_mask, cpu_present_mask)) { + pr_err("Cannot update TDX module if any CPU is offline\n"); + return -EBUSY; + } + /* TODO: Update TDX Module here */ return 0; } --=20 2.47.3 From nobody Sat Feb 7 08:27:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 A6D842F39D7; Fri, 23 Jan 2026 15:00:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180429; cv=none; b=Va96tlgh1R7SUfoN9MQbk7H+HWRU5UjICL+NsriyOXhdDvoztzr0eKbgY2gF8KKr4fV+OGsf7K459HuvJ5NqX5v87iUxG5h9RF+tXCHQvKr70LglhYpzSSoMPRz4gK/mbS/sMsHGZQ/cqm584FUAyEh4Z1BjxLy/j7n7677q3kU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180429; c=relaxed/simple; bh=2mas6uKv803snqoU3Os52DqiAqkG0aYWViBeCHLZ4pM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=eY3JxiEKE/ya86DKafLfNp7niGf5CYRV9E4k7U6v+Qpm44FkwLXLtv46RqAjHfro6y/Nbk71162Utp4JZ+rVDE0o0EKKnfZD4y7y5rJlW2dZMc70SwC5fmW0lcV62oPPiAe257gwVJhBCdDsLp2ODeWVA352JJrlfXF2b3CqOE8= 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=OjqRi9un; arc=none smtp.client-ip=192.198.163.17 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="OjqRi9un" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1769180427; x=1800716427; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=2mas6uKv803snqoU3Os52DqiAqkG0aYWViBeCHLZ4pM=; b=OjqRi9unT3RafW0tnXr3t1CMgisQtmmnfz3apUNf4B5bvAaV+K2doWJp fwOD8LLww2vt3fyrZ7KdS61E9gpQ1GrCETCP9LWj71vqIgtdyQEmx2vT5 Y2h1YRmsXZW/Pj+sBnGH4rjt+rGgryRrZCoRRM+PGTzpFgeDOxCokRGt0 OjIeUFE1pVYP2I+0IWlAbXizkA9ZufkOH2NCQLyQov9L/XeiiSNa0Xhjt pHYna1JJeTtnvyGVrAcaP6M3GaeOrc5zWMI7JdVfi1ME07zeNLdEzndHD 9TUi5df2RSeOFONyJsUfkkC5eK4umlAn1AvIaJyc0utvGCi4g41e4+8rQ A==; X-CSE-ConnectionGUID: lNq6X3BZSKyy4uO8OQC8+Q== X-CSE-MsgGUID: 4oH95j2fRA2imR8yIg5ZUw== X-IronPort-AV: E=McAfee;i="6800,10657,11680"; a="70334422" X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="70334422" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:14 -0800 X-CSE-ConnectionGUID: BfaFtyx5Sh2ljCfEgNKQ0g== X-CSE-MsgGUID: 8olzq3EoQkKEcCv4HZZ1gQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="237697133" Received: from 984fee019967.jf.intel.com ([10.23.153.244]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:14 -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, Chao Gao , Farrah Chen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v3 12/26] x86/virt/seamldr: Verify availability of slots for TDX Module updates Date: Fri, 23 Jan 2026 06:55:20 -0800 Message-ID: <20260123145645.90444-13-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260123145645.90444-1-chao.gao@intel.com> References: <20260123145645.90444-1-chao.gao@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The CPU keeps track of TCB versions for each TDX Module that has been loaded. Since this tracking database has finite capacity, there's a maximum number of module updates that can be performed. After each successful update, the number reduces by one. Once it reaches zero, further updates will fail until next reboot. Before updating the TDX Module, ensure that the limit on TDX Module updates has not been exceeded to prevent update failures in a later phase where TDs have to be killed. Signed-off-by: Chao Gao Tested-by: Farrah Chen Reviewed-by: Tony Lindgren --- arch/x86/virt/vmx/tdx/seamldr.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/x86/virt/vmx/tdx/seamldr.c b/arch/x86/virt/vmx/tdx/seamld= r.c index 88388aa0fb5f..d1d4f96c4963 100644 --- a/arch/x86/virt/vmx/tdx/seamldr.c +++ b/arch/x86/virt/vmx/tdx/seamldr.c @@ -83,6 +83,14 @@ EXPORT_SYMBOL_FOR_MODULES(seamldr_get_info, "tdx-host"); */ int seamldr_install_module(const u8 *data, u32 size) { + const struct seamldr_info *info =3D seamldr_get_info(); + + if (!info) + return -EIO; + + if (!info->num_remaining_updates) + return -ENOSPC; + if (!is_vmalloc_addr(data)) return -EINVAL; =20 --=20 2.47.3 From nobody Sat Feb 7 08:27:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 7F10C335078; Fri, 23 Jan 2026 15:00:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180432; cv=none; b=uYpmr2CO9O4UQ24cD1Cha3v4XLD2CsF2jUllmGOHfE+FsCuqkz7oLtuxZzwJg1SRGHo89P8y7tJZ3qMUgut67CiKoqKgwbN8/mws70TBH78ivpp3agev7SRuoYr2QFNfzcEinxQ34wN9AeqCUmMui4URHtMHxG/bGPOs+/pfFj0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180432; c=relaxed/simple; bh=4LnuKXZdo9kH8tHxBpxRr93UuLKtVKw8kcBh5tt10ng=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tgTdpakeg2yKCCcnrcmYxXCyy4Zrxm+1/2KGEW6yK/v6j+SPxeEzE/Vcy2Iy3FL/20e426Fv5A/0DEDRcl7OEBDGMeW069oMgpzxgrpPTdnosEeLtYknPJ9EfUALmmGp66YlqPQrc4I3+OFwAbxTQRCUKwCGLayUeZRsZzp2u+g= 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=jtIMl8z2; arc=none smtp.client-ip=192.198.163.17 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="jtIMl8z2" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1769180428; x=1800716428; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=4LnuKXZdo9kH8tHxBpxRr93UuLKtVKw8kcBh5tt10ng=; b=jtIMl8z2jnCWrimBeme1W5J1Wgw3h2h4EfiWGZbhoFXPyf5PIEinNsrk +gzzNQj7god8bUO/e0rrnDmDP1WFmMexWBoNsqvbRpUEVWHFHG1EcGJtH aoFaI9eBftwv4HQoUJ5JCiE9Vd/EICBxgLorPeQIHjvDUUlgV2zN6Kg6y kl74/hcVWdbquo/A3cMOgappWY6y+AQ6Lh3hbNVCJ5ysp397aJIUWJWST hj/3LAXTxjw8fcDajQsYpL/2SWnbSd+1lu2Yzig/CHSCngeoGu8JHXe1E C3vNEULM5AL7wxdXEJagC8U9FGPD4XusLqjgrckrCZoUattxLWGxzFhug g==; X-CSE-ConnectionGUID: 6wQYFlGNSdCpasQ6KnWsjA== X-CSE-MsgGUID: PQoMYUQjR0apP2Xj9UIdBw== X-IronPort-AV: E=McAfee;i="6800,10657,11680"; a="70334431" X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="70334431" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:15 -0800 X-CSE-ConnectionGUID: 1JumdmDxTTmAtiAd9CUWtA== X-CSE-MsgGUID: wg7sgRBERO6DFa1EHA3y/Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="237697141" Received: from 984fee019967.jf.intel.com ([10.23.153.244]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:15 -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, Chao Gao , Farrah Chen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v3 13/26] x86/virt/seamldr: Allocate and populate a module update request Date: Fri, 23 Jan 2026 06:55:21 -0800 Message-ID: <20260123145645.90444-14-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260123145645.90444-1-chao.gao@intel.com> References: <20260123145645.90444-1-chao.gao@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" A module update request is a struct used to describe information about the TDX module to install. It is part of the P-SEAMLDR <-> kernel ABI and is accepted by the SEAMLDR_INSTALL SEAMCALL. The request includes pointers to pages that contain the module binary, a pointer to a sigstruct file, and an update scenario. Define the request struct according to the P-SEAMLDR spec [1], and parse the bitstream from userspace to populate that struct for later module updates. Note that the bitstream format is specified in [2]. It consists of a header, a sigstruct, a module binary, and reserved fields for future extensions. The header includes fields like a simple checksum and a signature for error detection. Signed-off-by: Chao Gao Tested-by: Farrah Chen Link: https://cdrdv2.intel.com/v1/dl/getContent/733584 # [1] Link: https://github.com/intel/tdx-module-binaries/blob/main/blob_structure= .txt # [2] Reviewed-by: Tony Lindgren --- v3: - Print tdx_blob version in hex [Binbin] - Drop redundant sigstruct alignment check [Yilun] - Note buffers passed from firmware upload infrastructure are vmalloc()'d above alloc_seamldr_params() --- arch/x86/virt/vmx/tdx/seamldr.c | 158 ++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) diff --git a/arch/x86/virt/vmx/tdx/seamldr.c b/arch/x86/virt/vmx/tdx/seamld= r.c index d1d4f96c4963..d136ef89cd36 100644 --- a/arch/x86/virt/vmx/tdx/seamldr.c +++ b/arch/x86/virt/vmx/tdx/seamldr.c @@ -6,10 +6,12 @@ */ #define pr_fmt(fmt) "seamldr: " fmt =20 +#include #include #include #include #include +#include #include =20 #include @@ -19,6 +21,26 @@ /* P-SEAMLDR SEAMCALL leaf function */ #define P_SEAMLDR_INFO 0x8000000000000000 =20 +/* P-SEAMLDR can accept up to 496 4KB pages for TDX module binary */ +#define SEAMLDR_MAX_NR_MODULE_4KB_PAGES 496 + +/* scenario field in struct seamldr_params */ +#define SEAMLDR_SCENARIO_UPDATE 1 + +/* + * Passed to P-SEAMLDR to describe information about the TDX module to ins= tall. + * Defined in "SEAM Loader (SEAMLDR) Interface Specification", Revision + * 343755-003, Section 3.2. + */ +struct seamldr_params { + u32 version; + u32 scenario; + u64 sigstruct_pa; + u8 reserved[104]; + u64 num_module_pages; + u64 mod_pages_pa_list[SEAMLDR_MAX_NR_MODULE_4KB_PAGES]; +} __packed; + static struct seamldr_info seamldr_info __aligned(256); =20 static inline int seamldr_call(u64 fn, struct tdx_module_args *args) @@ -73,6 +95,137 @@ const struct seamldr_info *seamldr_get_info(void) } EXPORT_SYMBOL_FOR_MODULES(seamldr_get_info, "tdx-host"); =20 +static void free_seamldr_params(struct seamldr_params *params) +{ + free_page((unsigned long)params); +} + +/* + * Allocate and populate a seamldr_params. + * Note that both @module and @sig should be vmalloc'd memory. + */ +static struct seamldr_params *alloc_seamldr_params(const void *module, uns= igned int module_size, + const void *sig, unsigned int sig_size) +{ + struct seamldr_params *params; + const u8 *ptr; + int i; + + BUILD_BUG_ON(sizeof(struct seamldr_params) !=3D SZ_4K); + if (module_size > SEAMLDR_MAX_NR_MODULE_4KB_PAGES * SZ_4K) + return ERR_PTR(-EINVAL); + + if (!IS_ALIGNED(module_size, SZ_4K) || sig_size !=3D SZ_4K || + !IS_ALIGNED((unsigned long)module, SZ_4K) || + !IS_ALIGNED((unsigned long)sig, SZ_4K)) + return ERR_PTR(-EINVAL); + + params =3D (struct seamldr_params *)get_zeroed_page(GFP_KERNEL); + if (!params) + return ERR_PTR(-ENOMEM); + + params->scenario =3D SEAMLDR_SCENARIO_UPDATE; + + /* + * Don't assume @sig is page-aligned although it is 4KB-aligned. + * Always add the in-page offset to get the physical address. + */ + params->sigstruct_pa =3D (vmalloc_to_pfn(sig) << PAGE_SHIFT) + + ((unsigned long)sig & ~PAGE_MASK); + params->num_module_pages =3D module_size / SZ_4K; + + ptr =3D module; + for (i =3D 0; i < params->num_module_pages; i++) { + params->mod_pages_pa_list[i] =3D (vmalloc_to_pfn(ptr) << PAGE_SHIFT) + + ((unsigned long)ptr & ~PAGE_MASK); + ptr +=3D SZ_4K; + } + + return params; +} + +/* + * Intel TDX Module blob. Its format is defined at: + * https://github.com/intel/tdx-module-binaries/blob/main/blob_structure.t= xt + */ +struct tdx_blob { + u16 version; + u16 checksum; + u32 offset_of_module; + u8 signature[8]; + u32 len; + u32 resv1; + u64 resv2[509]; + u8 data[]; +} __packed; + +/* + * Verify that the checksum of the entire blob is zero. The checksum is + * calculated by summing up all 16-bit words, with carry bits dropped. + */ +static bool verify_checksum(const struct tdx_blob *blob) +{ + u32 size =3D blob->len; + u16 checksum =3D 0; + const u16 *p; + int i; + + /* Handle the last byte if the size is odd */ + if (size % 2) { + checksum +=3D *((const u8 *)blob + size - 1); + size--; + } + + p =3D (const u16 *)blob; + for (i =3D 0; i < size; i +=3D 2) { + checksum +=3D *p; + p++; + } + + return !checksum; +} + +static struct seamldr_params *init_seamldr_params(const u8 *data, u32 size) +{ + const struct tdx_blob *blob =3D (const void *)data; + int module_size, sig_size; + const void *sig, *module; + + if (blob->version !=3D 0x100) { + pr_err("unsupported blob version: %x\n", blob->version); + return ERR_PTR(-EINVAL); + } + + if (blob->resv1 || memchr_inv(blob->resv2, 0, sizeof(blob->resv2))) { + pr_err("non-zero reserved fields\n"); + return ERR_PTR(-EINVAL); + } + + /* Split the given blob into a sigstruct and a module */ + sig =3D blob->data; + sig_size =3D blob->offset_of_module - sizeof(struct tdx_blob); + module =3D data + blob->offset_of_module; + module_size =3D size - blob->offset_of_module; + + if (sig_size <=3D 0 || module_size <=3D 0 || blob->len !=3D size) + return ERR_PTR(-EINVAL); + + if (memcmp(blob->signature, "TDX-BLOB", 8)) { + pr_err("invalid signature\n"); + return ERR_PTR(-EINVAL); + } + + if (!verify_checksum(blob)) { + pr_err("invalid checksum\n"); + return ERR_PTR(-EINVAL); + } + + return alloc_seamldr_params(module, module_size, sig, sig_size); +} + +DEFINE_FREE(free_seamldr_params, struct seamldr_params *, + if (!IS_ERR_OR_NULL(_T)) free_seamldr_params(_T)) + /** * seamldr_install_module - Install a new TDX module * @data: Pointer to the TDX module binary data. It should be vmalloc'd @@ -94,6 +247,11 @@ int seamldr_install_module(const u8 *data, u32 size) if (!is_vmalloc_addr(data)) return -EINVAL; =20 + struct seamldr_params *params __free(free_seamldr_params) =3D + init_seamldr_params(data, size); + if (IS_ERR(params)) + return PTR_ERR(params); + guard(cpus_read_lock)(); if (!cpumask_equal(cpu_online_mask, cpu_present_mask)) { pr_err("Cannot update TDX module if any CPU is offline\n"); --=20 2.47.3 From nobody Sat Feb 7 08:27:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 7C1D026F289; Fri, 23 Jan 2026 15:00:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180432; cv=none; b=IffqZxQwDSkpSOGElNOgXZuemlRrook8a0hqHpEPwBTmggLGMEoAfL6WmObtJbK+jICgDOMKi6J7OU8b3TTsNLwfsh4y+BBU//ZLGYPXw5XpV1X9oU/q3rmGqDgtulMCAeE17MvRWxkRMPvEkwunvqdPuG85yQzgtRsUubO2+CA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180432; c=relaxed/simple; bh=pj80xMaMJyv6ytv5C3tFWZzqYHBt6ByJtfpSuegj9sA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=brexv5cRmQVJbpZl0Y8Kpge7JhuzK3zk9PmOdN3wPgUPwgxOIDEMl7m4PGaPPOMnEzz5pVFSmK7jxx42uosN36r0UdFHgFIzmr+0+LnFJiurrau+ZqzafoH5Xy8R+g4qLGSdabZcpBhnUJxGQgNhcxntryTK19npC/1xdQE5ZtY= 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=cUHkHEbE; arc=none smtp.client-ip=192.198.163.17 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="cUHkHEbE" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1769180430; x=1800716430; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=pj80xMaMJyv6ytv5C3tFWZzqYHBt6ByJtfpSuegj9sA=; b=cUHkHEbEkv6vGYdUJNeXqnVGyg8qMYapjbNON7iuBLcRfvXDmTE7jNWX NbhJvM0Ytncp3hRshNc0rxOE6P3pCRBVeF6DisMQu3OYy1rbFAnqUg8tS cZPhU9vn/AAVZl6vl+CH532YpxvLGvwqPP3fzuzOfWWmNOkT1CBd0ZuXT z09IORWzihl+VEy1UrPAhDssMwCGIapSG20Xr8HzxpvSR/KdhFLUgYnVW p15SJqdWsAfz6BQsj3lR9x1QgLmZP5YJqSA5nBQLzA04NzDGIYlDJNDM1 vEf/M1AGz4WnFh2ono6WmzIRpO/I9OVtxBEhjSfO1daIFhLshO6hoNwV3 A==; X-CSE-ConnectionGUID: 5zRsVxuZSmO0p1uKbJQrAw== X-CSE-MsgGUID: dRiOM+7+T1aO1H4HYA5EwQ== X-IronPort-AV: E=McAfee;i="6800,10657,11680"; a="70334440" X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="70334440" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:15 -0800 X-CSE-ConnectionGUID: TgAQZjCnQeCw9Ab47JpCgQ== X-CSE-MsgGUID: a0VuTPaYTd+Hi237MV2KXw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="237697151" Received: from 984fee019967.jf.intel.com ([10.23.153.244]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:15 -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, Chao Gao , Farrah Chen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v3 14/26] x86/virt/seamldr: Introduce skeleton for TDX Module updates Date: Fri, 23 Jan 2026 06:55:22 -0800 Message-ID: <20260123145645.90444-15-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260123145645.90444-1-chao.gao@intel.com> References: <20260123145645.90444-1-chao.gao@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The P-SEAMLDR requires that no TDX Module SEAMCALLs are invoked during a runtime TDX Module update. But currently, TDX Module SEAMCALLs are invoked in various contexts and in parallel across CPUs. Additionally, considering the need to force all vCPUs out of guest mode, no single lock primitive, except for stop_machine(), can meet this requirement. Perform TDX Module updates within stop_machine() as it achieves the P-SEAMLDR requirements and is an existing well understood mechanism. TDX Module updates consist of several steps: shutting down the old module, installing the new module, and initializing the new one and etc. Some steps must be executed on a single CPU, others serially across all CPUs, and some can be performed concurrently on all CPUs and there are ordering requirements between steps. So, all CPUs need to perform the work in a step-locked manner. In preparation for adding concrete steps for TDX Module updates, establish the framework by mimicking multi_cpu_stop(). Specifically, use a global state machine to control the work done on each CPU and require all CPUs to acknowledge completion before proceeding to the next stage. Potential alternative to stop_machine() =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D An alternative approach is to lock all KVM entry points and kick all vCPUs. Here, KVM entry points refer to KVM VM/vCPU ioctl entry points, implemented in KVM common code (virt/kvm). Adding a locking mechanism there would affect all architectures. And to lock only TDX vCPUs, new logic would be needed to identify TDX vCPUs, which the common code currently lacks. This would add significant complexity and maintenance overhead for a TDX-specific use case. Signed-off-by: Chao Gao Tested-by: Farrah Chen Reviewed-by: Tony Lindgren Reviewed-by: Xu Yilun --- v2: - refine the changlog to follow context-problem-solution structure - move alternative discussions at the end of the changelog - add a comment about state machine transition - Move rcu_momentary_eqs() call to the else branch. --- arch/x86/virt/vmx/tdx/seamldr.c | 71 ++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/arch/x86/virt/vmx/tdx/seamldr.c b/arch/x86/virt/vmx/tdx/seamld= r.c index d136ef89cd36..06080c648b02 100644 --- a/arch/x86/virt/vmx/tdx/seamldr.c +++ b/arch/x86/virt/vmx/tdx/seamldr.c @@ -11,7 +11,9 @@ #include #include #include +#include #include +#include #include =20 #include @@ -223,6 +225,68 @@ static struct seamldr_params *init_seamldr_params(cons= t u8 *data, u32 size) return alloc_seamldr_params(module, module_size, sig, sig_size); } =20 +/* + * During a TDX Module update, all CPUs start from TDP_START and progress + * to TDP_DONE. Each state is associated with certain work. For some + * states, just one CPU needs to perform the work, while other CPUs just + * wait during those states. + */ +enum tdp_state { + TDP_START, + TDP_DONE, +}; + +static struct { + enum tdp_state state; + atomic_t thread_ack; +} tdp_data; + +static void set_target_state(enum tdp_state state) +{ + /* Reset ack counter. */ + atomic_set(&tdp_data.thread_ack, num_online_cpus()); + /* Ensure thread_ack is updated before the new state */ + smp_wmb(); + WRITE_ONCE(tdp_data.state, state); +} + +/* Last one to ack a state moves to the next state. */ +static void ack_state(void) +{ + if (atomic_dec_and_test(&tdp_data.thread_ack)) + set_target_state(tdp_data.state + 1); +} + +/* + * See multi_cpu_stop() from where this multi-cpu state-machine was + * adopted, and the rationale for touch_nmi_watchdog() + */ +static int do_seamldr_install_module(void *params) +{ + enum tdp_state newstate, curstate =3D TDP_START; + int ret =3D 0; + + do { + /* Chill out and ensure we re-read tdp_data. */ + cpu_relax(); + newstate =3D READ_ONCE(tdp_data.state); + + if (newstate !=3D curstate) { + curstate =3D newstate; + switch (curstate) { + default: + break; + } + ack_state(); + } else { + touch_nmi_watchdog(); + rcu_momentary_eqs(); + } + } while (curstate !=3D TDP_DONE); + + return ret; +} + DEFINE_FREE(free_seamldr_params, struct seamldr_params *, if (!IS_ERR_OR_NULL(_T)) free_seamldr_params(_T)) =20 @@ -237,6 +301,7 @@ DEFINE_FREE(free_seamldr_params, struct seamldr_params = *, int seamldr_install_module(const u8 *data, u32 size) { const struct seamldr_info *info =3D seamldr_get_info(); + int ret; =20 if (!info) return -EIO; @@ -258,7 +323,11 @@ int seamldr_install_module(const u8 *data, u32 size) return -EBUSY; } =20 - /* TODO: Update TDX Module here */ + set_target_state(TDP_START + 1); + ret =3D stop_machine_cpuslocked(do_seamldr_install_module, params, cpu_on= line_mask); + if (ret) + return ret; + return 0; } EXPORT_SYMBOL_FOR_MODULES(seamldr_install_module, "tdx-host"); --=20 2.47.3 From nobody Sat Feb 7 08:27:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 82C1F352FB7; Fri, 23 Jan 2026 15:00:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180433; cv=none; b=IjoWkmCKDu8wLXdQiFyZVYR6VPXf9HhwxsaMeYPhjYk5HQmwjBskB8YmXFse9Ge+ZHpVLaOJI41nw3wgXu0m6GKrFxXf8bZ3XZjO3sIgQDW9X19FSFhl4/IwK7skePk0SaPsbeF1IzVyoOtEboRAZiG66W7NTrsmcw5EUvnRyAA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180433; c=relaxed/simple; bh=a3gRMZp+tq9HMVyIh/sGo+Ksja88/ptZZkRDwyCC7Tk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=r1l+1yYjYgNTYpxHeAZXrJDyT6m8uC+jQ6a8Q8GmUF/avdDtLo0nFQ9pO8ENA+0W7g4pTHdbK2p/DhAuKAYGqgImJ2dhgDIFVbwc0f1Uo7FoGlINaFOzf0mcKRqRDKVwQ43z1l4iFtazIs2sFV6yLIyvOLbmsp37wTnyy8EP+L4= 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=VFLyRaKo; arc=none smtp.client-ip=192.198.163.17 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="VFLyRaKo" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1769180431; x=1800716431; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=a3gRMZp+tq9HMVyIh/sGo+Ksja88/ptZZkRDwyCC7Tk=; b=VFLyRaKotoleROn3GXF6R76gfnr38iMSirec32Qa44nXxSVSZoxZd+Ag JW5Mo+9YKN+7KoQQq+/skEew57ip6kKw6QirypvoV7wnDQ/8ahmkNqgyG 8hE0ivtX9SZdHNeikxFDTHkjJacOZsRdoCEmYyT2m01H4rQ5b5yo6LN7F lvEfYe3jPxEPz3zDhFOusLGlsFZJva3BZwGSMwy7cVzsMdWLJF6MpQKev Wx/U1Jbwe+TzHv2Qtdj1tyeyIKjYeuEfTpV5D2Rynv7nM6XWJXkdl8Kch GP9uY9xh4gF4TZPqPw2kGYIp5gpZ6X+wve3mp56y0YGg064ygxyO5N3lK w==; X-CSE-ConnectionGUID: jEf/q4uBSduqE8nLqpHf3Q== X-CSE-MsgGUID: /16jzDCYSPWAsfvu6zdysw== X-IronPort-AV: E=McAfee;i="6800,10657,11680"; a="70334449" X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="70334449" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:16 -0800 X-CSE-ConnectionGUID: kmAe1EgEQ5O/iDp+Qpefww== X-CSE-MsgGUID: grWDjCIcQ9WFEeV6fbbRmw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="237697156" Received: from 984fee019967.jf.intel.com ([10.23.153.244]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:16 -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, Chao Gao , Farrah Chen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v3 15/26] x86/virt/seamldr: Abort updates if errors occurred midway Date: Fri, 23 Jan 2026 06:55:23 -0800 Message-ID: <20260123145645.90444-16-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260123145645.90444-1-chao.gao@intel.com> References: <20260123145645.90444-1-chao.gao@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The TDX Module update process has multiple stages, each of which may encounter failures. The current state machine of updates proceeds to the next stage regardless of errors. But continuing updates when errors occur midway is pointless. If a CPU encounters an error, abort the update by setting a flag and exiting the execution loop. Note that this CPU doesn't acknowledge the current stage. This will keep all other CPUs in the current stage until they see the flag and exit the loop as well. Signed-off-by: Chao Gao Tested-by: Farrah Chen Reviewed-by: Tony Lindgren Reviewed-by: Xu Yilun --- v3: - Instead of fast-forward to the final stage, exit the execution loop directly. --- arch/x86/virt/vmx/tdx/seamldr.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/x86/virt/vmx/tdx/seamldr.c b/arch/x86/virt/vmx/tdx/seamld= r.c index 06080c648b02..a13d526b38a7 100644 --- a/arch/x86/virt/vmx/tdx/seamldr.c +++ b/arch/x86/virt/vmx/tdx/seamldr.c @@ -239,6 +239,7 @@ enum tdp_state { static struct { enum tdp_state state; atomic_t thread_ack; + atomic_t failed; } tdp_data; =20 static void set_target_state(enum tdp_state state) @@ -277,12 +278,16 @@ static int do_seamldr_install_module(void *params) default: break; } - ack_state(); + + if (ret) + atomic_inc(&tdp_data.failed); + else + ack_state(); } else { touch_nmi_watchdog(); rcu_momentary_eqs(); } - } while (curstate !=3D TDP_DONE); + } while (curstate !=3D TDP_DONE && !atomic_read(&tdp_data.failed)); =20 return ret; } @@ -323,6 +328,7 @@ int seamldr_install_module(const u8 *data, u32 size) return -EBUSY; } =20 + atomic_set(&tdp_data.failed, 0); set_target_state(TDP_START + 1); ret =3D stop_machine_cpuslocked(do_seamldr_install_module, params, cpu_on= line_mask); if (ret) --=20 2.47.3 From nobody Sat Feb 7 08:27:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 C98AC3570A9; Fri, 23 Jan 2026 15:00:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180435; cv=none; b=uigdjOGbREnjl7Cz1ynv22pKJhdeXByRkm6LJehQYUU4LK1buUkUAflNjZuh5XCDzORPIqgerc+4KS4PJIYT38GtvOQyXYXJET76fIYLayPgpcqnDwesFIy/w/+qXjIO8KKkh+epMq6mPrscM5nNdRe3XHIFlYtR4frOJPM8GH0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180435; c=relaxed/simple; bh=eCHsjN/WFKTRp2ioiJ0lDE/cxmPQPl26vIGWgJI90qs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MgqX990h3Lx/Vj086ZHzLTur10nPXQ5RkR/qmGctJCAXihsPh/9SSTBKkKylB2ROaze/exBz2zkwFAatbaN1KoaiPrSXsgAnNX86Lctzyi39/zE8fxdsaE4+9zlVZhOKEfU/H/RSjmGBEJFJGM+wjyKswbGGjHV9WVIgPF1qfjE= 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=KwnkBJFA; arc=none smtp.client-ip=192.198.163.17 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="KwnkBJFA" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1769180433; x=1800716433; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=eCHsjN/WFKTRp2ioiJ0lDE/cxmPQPl26vIGWgJI90qs=; b=KwnkBJFABBlM3G/HaJT2KBQRfm4mUHj0E2sy+eaIL13wFRkpa+R8WB6H y2/2qHAwF3MIq7I4jBBKNBwcBu+TbiYwoOqMJkfDGBJ2n6Nja33Vmi4Yl mAJVjNTPrul6f47rsEOS9q5t4pKltVBQL0LyB3iLyNRmwJWxSkWbiWroA /anfw+b6e+4F2mfyTWxfCzRP9o5jhIn/IAHPLf7WkJnTts5x31WTCt63Z QaV/0R1dnAThen2hHDJDyvn7OWwCK4ocCX+Ks3LMrfy9C3f1W8b6TlNHL Ur7lpVpbMuxxvXc7gWx6up1au+zOvUaRqTIhaZPQ8qIOEI4+PaLFJRWIZ w==; X-CSE-ConnectionGUID: V3ptGusdQUmWHGLI17Zgeg== X-CSE-MsgGUID: AoknQZucSbeyYsmRDqRNBA== X-IronPort-AV: E=McAfee;i="6800,10657,11680"; a="70334460" X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="70334460" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:17 -0800 X-CSE-ConnectionGUID: UmfE6kZWTj6o/LxogLuewA== X-CSE-MsgGUID: 8+YgL/bETrOzLc4/6nBu3Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="237697166" Received: from 984fee019967.jf.intel.com ([10.23.153.244]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:17 -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, Chao Gao , Farrah Chen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v3 16/26] x86/virt/seamldr: Shut down the current TDX module Date: Fri, 23 Jan 2026 06:55:24 -0800 Message-ID: <20260123145645.90444-17-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260123145645.90444-1-chao.gao@intel.com> References: <20260123145645.90444-1-chao.gao@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" TDX Module updates request shutting down the existing TDX module. During this shutdown, the module generates hand-off data, which captures the module's states essential for preserving running TDs. The new TDX Module can utilize this hand-off data to establish its states. Invoke the TDH_SYS_SHUTDOWN SEAMCALL on one CPU to perform the shutdown. This SEAMCALL requires a hand-off module version. Use the module's own hand-off version, as it is the highest version the module can produce and is more likely to be compatible with new modules as new modules likely have higher hand-off version. Signed-off-by: Chao Gao Tested-by: Farrah Chen Reviewed-by: Tony Lindgren --- v3: - remove autogeneration stuff in the changelog v2: - add a comment about how handoff version is chosen. - remove the first !ret in get_tdx_sys_info_handoff() as we edited the auto-generated code anyway - remove !! when determining whether a CPU is the primary one - remove unnecessary if-break nesting in TDP_SHUTDOWN --- arch/x86/include/asm/tdx_global_metadata.h | 5 +++++ arch/x86/virt/vmx/tdx/seamldr.c | 10 ++++++++++ arch/x86/virt/vmx/tdx/tdx.c | 16 ++++++++++++++++ arch/x86/virt/vmx/tdx/tdx.h | 3 +++ arch/x86/virt/vmx/tdx/tdx_global_metadata.c | 13 +++++++++++++ 5 files changed, 47 insertions(+) diff --git a/arch/x86/include/asm/tdx_global_metadata.h b/arch/x86/include/= asm/tdx_global_metadata.h index 40689c8dc67e..8a9ebd895e70 100644 --- a/arch/x86/include/asm/tdx_global_metadata.h +++ b/arch/x86/include/asm/tdx_global_metadata.h @@ -40,12 +40,17 @@ struct tdx_sys_info_td_conf { u64 cpuid_config_values[128][2]; }; =20 +struct tdx_sys_info_handoff { + u16 module_hv; +}; + struct tdx_sys_info { struct tdx_sys_info_version version; struct tdx_sys_info_features features; struct tdx_sys_info_tdmr tdmr; struct tdx_sys_info_td_ctrl td_ctrl; struct tdx_sys_info_td_conf td_conf; + struct tdx_sys_info_handoff handoff; }; =20 #endif diff --git a/arch/x86/virt/vmx/tdx/seamldr.c b/arch/x86/virt/vmx/tdx/seamld= r.c index a13d526b38a7..76f404d1115c 100644 --- a/arch/x86/virt/vmx/tdx/seamldr.c +++ b/arch/x86/virt/vmx/tdx/seamldr.c @@ -19,6 +19,7 @@ #include =20 #include "seamcall.h" +#include "tdx.h" =20 /* P-SEAMLDR SEAMCALL leaf function */ #define P_SEAMLDR_INFO 0x8000000000000000 @@ -233,6 +234,7 @@ static struct seamldr_params *init_seamldr_params(const= u8 *data, u32 size) */ enum tdp_state { TDP_START, + TDP_SHUTDOWN, TDP_DONE, }; =20 @@ -265,8 +267,12 @@ static void ack_state(void) static int do_seamldr_install_module(void *params) { enum tdp_state newstate, curstate =3D TDP_START; + int cpu =3D smp_processor_id(); + bool primary; int ret =3D 0; =20 + primary =3D cpumask_first(cpu_online_mask) =3D=3D cpu; + do { /* Chill out and ensure we re-read tdp_data. */ cpu_relax(); @@ -275,6 +281,10 @@ static int do_seamldr_install_module(void *params) if (newstate !=3D curstate) { curstate =3D newstate; switch (curstate) { + case TDP_SHUTDOWN: + if (primary) + ret =3D tdx_module_shutdown(); + break; default: break; } diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index a0990c5dd78d..8b36a80cf229 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -1175,6 +1175,22 @@ int tdx_enable(void) } EXPORT_SYMBOL_FOR_KVM(tdx_enable); =20 +int tdx_module_shutdown(void) +{ + struct tdx_module_args args =3D {}; + + /* + * Shut down the TDX Module and prepare handoff data for the next + * TDX Module. This SEAMCALL requires a hand-off module version. + * Use the module's own hand-off version, as it is the highest + * version the module can produce and is more likely to be + * compatible with new modules as new modules likely have higher + * hand-off version. + */ + args.rcx =3D tdx_sysinfo.handoff.module_hv; + return seamcall_prerr(TDH_SYS_SHUTDOWN, &args); +} + static bool is_pamt_page(unsigned long phys) { struct tdmr_info_list *tdmr_list =3D &tdx_tdmr_list; diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h index 82bb82be8567..1c4da9540ae0 100644 --- a/arch/x86/virt/vmx/tdx/tdx.h +++ b/arch/x86/virt/vmx/tdx/tdx.h @@ -46,6 +46,7 @@ #define TDH_PHYMEM_PAGE_WBINVD 41 #define TDH_VP_WR 43 #define TDH_SYS_CONFIG 45 +#define TDH_SYS_SHUTDOWN 52 =20 /* * SEAMCALL leaf: @@ -118,4 +119,6 @@ struct tdmr_info_list { int max_tdmrs; /* How many 'tdmr_info's are allocated */ }; =20 +int tdx_module_shutdown(void); + #endif diff --git a/arch/x86/virt/vmx/tdx/tdx_global_metadata.c b/arch/x86/virt/vm= x/tdx/tdx_global_metadata.c index 4c9917a9c2c3..7f4ed9af1d8d 100644 --- a/arch/x86/virt/vmx/tdx/tdx_global_metadata.c +++ b/arch/x86/virt/vmx/tdx/tdx_global_metadata.c @@ -100,6 +100,18 @@ static int get_tdx_sys_info_td_conf(struct tdx_sys_inf= o_td_conf *sysinfo_td_conf return ret; } =20 +static int get_tdx_sys_info_handoff(struct tdx_sys_info_handoff *sysinfo_h= andoff) +{ + int ret =3D 0; + u64 val; + + if (tdx_supports_runtime_update(&tdx_sysinfo) && + !(ret =3D read_sys_metadata_field(0x8900000100000000, &val))) + sysinfo_handoff->module_hv =3D val; + + return ret; +} + static int get_tdx_sys_info(struct tdx_sys_info *sysinfo) { int ret =3D 0; @@ -115,6 +127,7 @@ static int get_tdx_sys_info(struct tdx_sys_info *sysinf= o) ret =3D ret ?: get_tdx_sys_info_tdmr(&sysinfo->tdmr); ret =3D ret ?: get_tdx_sys_info_td_ctrl(&sysinfo->td_ctrl); ret =3D ret ?: get_tdx_sys_info_td_conf(&sysinfo->td_conf); + ret =3D ret ?: get_tdx_sys_info_handoff(&sysinfo->handoff); =20 return ret; } --=20 2.47.3 From nobody Sat Feb 7 08:27:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 2DB0C330640; Fri, 23 Jan 2026 15:00:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180435; cv=none; b=buMu6fJ5aWt4+4IQob7CO2JEaDtU8EvaQRRLGYKNcJU1pHqNzCZTeyHELLg93Ws+qlWgZrmLx/O2lj2/6gr7oxys7Nigqbb9F7HI5uqK2DJZxA5+dmlGifo9dOvxz/qLcDcVdbyyqpZQvwxWGv1WJPQaB5fOKQxfVxyfcflTbtM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180435; c=relaxed/simple; bh=zY5aVbwXxUTAc4TRpLTMQoaPT5wFuMGqIm8BtbmOegs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nz5ZOz5aPP+kfJTw/E105jnlcNF2eDSpKri6HJg3g9c3HwJvNz82FEijRujKSAn+xm796T9wyWDxJOd/hWvF8SGRgU7gzJJNSK6smw1loavnF7X05MCdm9jwal8tqQfvXay7M8f9ZQz3SBI/g0A2NcTurdwD+iX71LMeqiQHWIQ= 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=Fx0K1vD7; arc=none smtp.client-ip=192.198.163.17 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="Fx0K1vD7" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1769180433; x=1800716433; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=zY5aVbwXxUTAc4TRpLTMQoaPT5wFuMGqIm8BtbmOegs=; b=Fx0K1vD7jS/bH+EJyXwoQ74qM/XDEGrT7sI4cBS1OMYtT5nq3KNBkQfi wq+6CEe4Qtw6D0x7CGwsTnemX7PfKvTn8QGZaa8kRyxqB4YXPDR/SWv1j HqiffwaDweNfHWreFcqxkph+gz1/DypUWSd6oeRQiFx0SeJl4dHZMyL06 +efRE7WUbVChzEu0vh89AL5RE2QV4QV5euvn8rOrpOO38hUGw6SXVNjUL 6AlxX4RDXt/kWGCPvRBSsN1IhH8mPYoZN2P7w5F+EY4wdNXpjmSpi4wuo EReQOjv+z8X8+p9CNp62sX71enim12DVGhm6cG+5ar7eWgZHt1QPcglNe w==; X-CSE-ConnectionGUID: HIhAMTyeStq7TAurFVhRqw== X-CSE-MsgGUID: EIAMG8bzSsq3D4+rXYdJEg== X-IronPort-AV: E=McAfee;i="6800,10657,11680"; a="70334469" X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="70334469" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:17 -0800 X-CSE-ConnectionGUID: LFFzWEJHTqWcEsfK3UXMVA== X-CSE-MsgGUID: 314T0wDFQyy+zhy6lsj1Bg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="237697174" Received: from 984fee019967.jf.intel.com ([10.23.153.244]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:17 -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, Chao Gao , Farrah Chen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v3 17/26] x86/virt/tdx: Reset software states after TDX module shutdown Date: Fri, 23 Jan 2026 06:55:25 -0800 Message-ID: <20260123145645.90444-18-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260123145645.90444-1-chao.gao@intel.com> References: <20260123145645.90444-1-chao.gao@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The TDX module requires a one-time global initialization (TDH.SYS.INIT) and per-CPU initialization (TDH.SYS.LP.INIT) before use. These initializations are guarded by software flags to prevent repetition. After TDX module updates, the new TDX module requires the same global and per-CPU initializations, but the existing software flags prevent re-initialization. Reset all software flags guarding the initialization flows to allow the global and per-CPU initializations to be triggered again after updates. Signed-off-by: Chao Gao Tested-by: Farrah Chen Reviewed-by: Tony Lindgren --- arch/x86/virt/vmx/tdx/tdx.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 8b36a80cf229..2763c1869b78 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -54,6 +54,8 @@ static struct tdmr_info_list tdx_tdmr_list; =20 static enum tdx_module_status_t tdx_module_status; static DEFINE_MUTEX(tdx_module_lock); +static bool sysinit_done; +static int sysinit_ret; =20 /* All TDX-usable memory regions. Protected by mem_hotplug_lock. */ static LIST_HEAD(tdx_memlist); @@ -69,8 +71,6 @@ static int try_init_module_global(void) { struct tdx_module_args args =3D {}; static DEFINE_RAW_SPINLOCK(sysinit_lock); - static bool sysinit_done; - static int sysinit_ret; =20 lockdep_assert_irqs_disabled(); =20 @@ -1178,6 +1178,7 @@ EXPORT_SYMBOL_FOR_KVM(tdx_enable); int tdx_module_shutdown(void) { struct tdx_module_args args =3D {}; + int ret, cpu; =20 /* * Shut down the TDX Module and prepare handoff data for the next @@ -1188,7 +1189,17 @@ int tdx_module_shutdown(void) * hand-off version. */ args.rcx =3D tdx_sysinfo.handoff.module_hv; - return seamcall_prerr(TDH_SYS_SHUTDOWN, &args); + ret =3D seamcall_prerr(TDH_SYS_SHUTDOWN, &args); + if (ret) + return ret; + + tdx_module_status =3D TDX_MODULE_UNINITIALIZED; + sysinit_done =3D false; + sysinit_ret =3D 0; + + for_each_online_cpu(cpu) + per_cpu(tdx_lp_initialized, cpu) =3D false; + return 0; } =20 static bool is_pamt_page(unsigned long phys) --=20 2.47.3 From nobody Sat Feb 7 08:27:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 7735B357A49; Fri, 23 Jan 2026 15:00:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180435; cv=none; b=pkUMrfUwfiee9ZopKqsA2cyBiAsYPXuww7JaHIo75ZbF9tBriaP/2l0rpoC14ITwW2v3wq3slcjpsWFiIRy4VYA8wCEYXotUZZJFnEXRpdVk+Suow7eTLHXE7GrY5ii+RJlSuPeRZLoUC6KGtBVoFjxvFZNuAX53OjeNOKXOJOY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180435; c=relaxed/simple; bh=c+YcofYlDsoQPUldf/eodN31yd/szVEY6FullhsT+/4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=iN/tlVR/+7Q5DGJ0pgL2+WpwL/wMncni5DGhcF0hTbhGFb6GCo9DKOZT3adAnF79E/9sWfAeeTDadNNPvG0JEZ2zFFZu+Wid21HRP0HwavpfiXuvENkGddC0SzuY9mXiHpgSlhtblLkelmQnmrDpURwhIX9BqZXrpE23g9tV1kQ= 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=ePx0B2It; arc=none smtp.client-ip=192.198.163.17 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="ePx0B2It" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1769180434; x=1800716434; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=c+YcofYlDsoQPUldf/eodN31yd/szVEY6FullhsT+/4=; b=ePx0B2ItxwiNKnIK4ItuG0Y0Jmu3K3Q76Kgi42qxNjG/ITYGACidhxLN vAexa5N+TzJA3FbHmDWOmSBSZZWxz1YmX1nDh0DRvP+MbKS7eyr9j3c+R HqC86KXTBqKNBcWU3vl2VC0Olwj/5T/V71VM3ptp8RkjJLpLe4DHBMiix pHG5w5M2jC3CxlrChYr5LDInMyv9qiRfJGPemnvE8jzoVbN47kpB+j0vs P+ghVjK+c9atSsZhuTw00pPs7Q4C/so0un5GCWhHBIEm7rVp5baWca/Hq lVtBK4Ixk51w0YDfL22SH/Rx1XbAJWEoDx8dUpj0ZScU88h4ebeV0gCq0 Q==; X-CSE-ConnectionGUID: LwKQMkkiTbmrJtcutNxkKQ== X-CSE-MsgGUID: LlF/CSBWRCSykUoAcAKRrg== X-IronPort-AV: E=McAfee;i="6800,10657,11680"; a="70334478" X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="70334478" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:18 -0800 X-CSE-ConnectionGUID: J7kqfZNRTNajWQNCmyj28w== X-CSE-MsgGUID: CyYboKZqSRi0wY6y+7izcw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="237697180" Received: from 984fee019967.jf.intel.com ([10.23.153.244]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:17 -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, Chao Gao , Farrah Chen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v3 18/26] x86/virt/seamldr: Log TDX Module update failures Date: Fri, 23 Jan 2026 06:55:26 -0800 Message-ID: <20260123145645.90444-19-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260123145645.90444-1-chao.gao@intel.com> References: <20260123145645.90444-1-chao.gao@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" If failures occur after the TDX Module has been successfully shut down, they are unrecoverable. The kernel cannot restore the previous TDX Module to a running state. All subsequent SEAMCALLs to the TDX Module will fail, so TDs cannot continue to run. Log a message to clarify that SEAMCALL errors are expected in this case. To prevent TDX Module update failures, admins are encouraged to use the user space tool [1] that will perform compatibility and integrity checks that guarantee TDX Module update success. Signed-off-by: Chao Gao Tested-by: Farrah Chen Link: https://github.com/intel/tdx-module-binaries/blob/main/version_select= _and_load.py # [1] Reviewed-by: Tony Lindgren --- v3: - Rephrase the changelog to eliminate the confusing uses of 'i.e.' and 'e.= g.' [Dave/Yilun] --- arch/x86/virt/vmx/tdx/seamldr.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/arch/x86/virt/vmx/tdx/seamldr.c b/arch/x86/virt/vmx/tdx/seamld= r.c index 76f404d1115c..b497fa72ebb6 100644 --- a/arch/x86/virt/vmx/tdx/seamldr.c +++ b/arch/x86/virt/vmx/tdx/seamldr.c @@ -260,6 +260,14 @@ static void ack_state(void) set_target_state(tdp_data.state + 1); } =20 +static void print_update_failure_message(void) +{ + static atomic_t printed =3D ATOMIC_INIT(0); + + if (atomic_inc_return(&printed) =3D=3D 1) + pr_err("update failed, SEAMCALLs will report failure until TDs killed\n"= ); +} + /* * See multi_cpu_stop() from where this multi-cpu state-machine was * adopted, and the rationale for touch_nmi_watchdog() @@ -289,10 +297,13 @@ static int do_seamldr_install_module(void *params) break; } =20 - if (ret) + if (ret) { atomic_inc(&tdp_data.failed); - else + if (curstate > TDP_SHUTDOWN) + print_update_failure_message(); + } else { ack_state(); + } } else { touch_nmi_watchdog(); rcu_momentary_eqs(); --=20 2.47.3 From nobody Sat Feb 7 08:27:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 6E2E9361DD2; Fri, 23 Jan 2026 15:00:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180437; cv=none; b=VeM3rb2aH3Cainp9LafWUXzfBPkYYC0TN7Ri2NWrs/x0RBG56c/IdhB1RdhMzjf+Di+0GcEglvXdJfdcEnp/RbxieH28Z3evo31VknNZ35I6BxCh8qtfgmLua2OC4m+EdtSxXsp7wTkAt62R7sozgYB7HCYBpeUJyoeVxVzJs/4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180437; c=relaxed/simple; bh=KJpmqqhLnjAbDclaNk+4xpsm/pXva8svEd54xfOtQPw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=F3Uet478oNCdPgo9em/bbWmDxd/DllCL+1ieoTRXS+1De8DYkLv6QHepYKf8tqwrtMJWOK+vg92MikI2JAmmPr+9EvAkcW47AU/K0FD1tfF19K+OY4WswbCeK9HHKp3OqDuEY151V9QAIt+CutC/O19zAgUKjN3GGAG++zNx+uc= 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=LklEmNJ0; arc=none smtp.client-ip=192.198.163.17 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="LklEmNJ0" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1769180436; x=1800716436; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=KJpmqqhLnjAbDclaNk+4xpsm/pXva8svEd54xfOtQPw=; b=LklEmNJ04Ao50Xx+70LP7yxBQ47V4Q9eK1pq+ur4cgLTSdueESo6JnIi rwZpnr4tN9efjtFAjsU25kPcqXxB2H7FStOC5hrXs+Uqd+0ydEWcrjvKU 5vNnoLGBs4vbjJYpRK58gP0J94N8Inc7xnycl4/B99PXTOVNB0drpUsWA PXjhl7hNCdh1gUVIjSec1zNlm30PNSySJSJroSE4Oi1hxlTh55jYH25IP e6EL8EfmhqUJUXTzrnm4AptD/JMP5fpa+YxQy0w6rmqlGgVYSWEHmpnxu ssljkTsTXldroN/hRjRfMmagCabTdpSMujnIOHZ7zshZ9DuDXvT+DBtcn A==; X-CSE-ConnectionGUID: 4tCBbG7mQTakslkrNewrtQ== X-CSE-MsgGUID: tIEh1d6tRpKJoZRvj2D2JQ== X-IronPort-AV: E=McAfee;i="6800,10657,11680"; a="70334487" X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="70334487" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:18 -0800 X-CSE-ConnectionGUID: VtwK72JFTvOS9MSnXDwF1w== X-CSE-MsgGUID: OiWuBPkKR72fDYfjxuD+Ow== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="237697186" Received: from 984fee019967.jf.intel.com ([10.23.153.244]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:18 -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, Chao Gao , Farrah Chen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v3 19/26] x86/virt/seamldr: Install a new TDX Module Date: Fri, 23 Jan 2026 06:55:27 -0800 Message-ID: <20260123145645.90444-20-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260123145645.90444-1-chao.gao@intel.com> References: <20260123145645.90444-1-chao.gao@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" After shutting down the running TDX module, the next step is to install the new TDX Module supplied by userspace. P-SEAMLDR provides the SEAMLDR.INSTALL SEAMCALL for that. The SEAMCALL accepts the seamldr_params struct and should be called serially on all CPUs. Invoke the SEAMLDR.INSTALL SEAMCALL serially on all CPUs and add a new spinlock to enforce serialization. Signed-off-by: Chao Gao Tested-by: Farrah Chen Reviewed-by: Tony Lindgren --- arch/x86/virt/vmx/tdx/seamldr.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/arch/x86/virt/vmx/tdx/seamldr.c b/arch/x86/virt/vmx/tdx/seamld= r.c index b497fa72ebb6..13c34e6378e0 100644 --- a/arch/x86/virt/vmx/tdx/seamldr.c +++ b/arch/x86/virt/vmx/tdx/seamldr.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include =20 @@ -23,6 +24,7 @@ =20 /* P-SEAMLDR SEAMCALL leaf function */ #define P_SEAMLDR_INFO 0x8000000000000000 +#define P_SEAMLDR_INSTALL 0x8000000000000001 =20 /* P-SEAMLDR can accept up to 496 4KB pages for TDX module binary */ #define SEAMLDR_MAX_NR_MODULE_4KB_PAGES 496 @@ -45,6 +47,7 @@ struct seamldr_params { } __packed; =20 static struct seamldr_info seamldr_info __aligned(256); +static DEFINE_RAW_SPINLOCK(seamldr_lock); =20 static inline int seamldr_call(u64 fn, struct tdx_module_args *args) { @@ -235,6 +238,7 @@ static struct seamldr_params *init_seamldr_params(const= u8 *data, u32 size) enum tdp_state { TDP_START, TDP_SHUTDOWN, + TDP_CPU_INSTALL, TDP_DONE, }; =20 @@ -272,9 +276,10 @@ static void print_update_failure_message(void) * See multi_cpu_stop() from where this multi-cpu state-machine was * adopted, and the rationale for touch_nmi_watchdog() */ -static int do_seamldr_install_module(void *params) +static int do_seamldr_install_module(void *seamldr_params) { enum tdp_state newstate, curstate =3D TDP_START; + struct tdx_module_args args =3D {}; int cpu =3D smp_processor_id(); bool primary; int ret =3D 0; @@ -293,6 +298,11 @@ static int do_seamldr_install_module(void *params) if (primary) ret =3D tdx_module_shutdown(); break; + case TDP_CPU_INSTALL: + args.rcx =3D __pa(seamldr_params); + scoped_guard(raw_spinlock, &seamldr_lock) + ret =3D seamldr_call(P_SEAMLDR_INSTALL, &args); + break; default: break; } --=20 2.47.3 From nobody Sat Feb 7 08:27:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 6FCA1362129; Fri, 23 Jan 2026 15:00:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180438; cv=none; b=OYj455xCK6UeBVjjMKUN0agt5b838rMscY84gkSnKXkQnplhBfKWxRTmAlwke7w9AzxaL4PyUYNH6GaUwo67Ttq8Y3HWiLel7fhI2Wji3SNI/jPzCKQMi6NvUDlShiyzajHOjJvKU4gWgkCe6GKUf5hkD/pauSyQJVdFE9+3F6Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180438; c=relaxed/simple; bh=W/SuQAxt7ClBHx9qecLubHrb5FhNgT3NcUOt5cFlxEc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Lqg5uwXDWDgSo2o26aHysplLoHoxNDSZPo8DAqtjvmEAFKeRAT0Qp04pNdnuuRqZOWAQR3r34CEuW/Krc0WPrRlnr3hTngX/VERcVNI/3QMMi4H308S3I/FuKvSW9bMdQTjIO8toe1vtcIyTAQghFZlaC/FUu2Ye+otUocIGWeQ= 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=E4EcoqV4; arc=none smtp.client-ip=192.198.163.17 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="E4EcoqV4" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1769180436; x=1800716436; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=W/SuQAxt7ClBHx9qecLubHrb5FhNgT3NcUOt5cFlxEc=; b=E4EcoqV4RQTQ3+xRB01hMkGGSkfwo8jJALjYvMAxSa1/1QgFQHT+2KCf +Zs3kVpatA/WbnQ0V/PuSP5YZOCAaeX4y/Eq53H7payXqfkPzacCLVSUL orH5/pMq+iTX9ANHGorgUMIjbY8pxaZofKNKHXt8nG4h62X2keRc5UxHr OQtAeY69yxFHyRn57LNWKxCtgyrZBWu9HOen0An2XyfIR5kIGTp57AKuT ToU7zBGOAdoBzW6qN4T/r0yATb8Mf7ZD32K5O1nMAhSi2llSPcfmI9J79 UrtktWazz6Dn3hmIX43MyOviHQnlNhPlI7JIw3EZJVF9mXwMeD6K1dkDL Q==; X-CSE-ConnectionGUID: zO6HZXIEQNOOIO+6uz+aTw== X-CSE-MsgGUID: o92uHkHzRN2fArADy1Hk5A== X-IronPort-AV: E=McAfee;i="6800,10657,11680"; a="70334496" X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="70334496" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:18 -0800 X-CSE-ConnectionGUID: 2XrvhoCXT7SVFEQgT9a3sA== X-CSE-MsgGUID: AmhIpe1pTmaa59UY/q4DCg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="237697190" Received: from 984fee019967.jf.intel.com ([10.23.153.244]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:18 -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, Chao Gao , Farrah Chen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v3 20/26] x86/virt/seamldr: Do TDX per-CPU initialization after updates Date: Fri, 23 Jan 2026 06:55:28 -0800 Message-ID: <20260123145645.90444-21-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260123145645.90444-1-chao.gao@intel.com> References: <20260123145645.90444-1-chao.gao@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" After installing the new TDX module, each CPU should be initialized again to make the CPU ready to run any other SEAMCALLs. So, call tdx_cpu_enable() on all CPUs. Signed-off-by: Chao Gao Tested-by: Farrah Chen Reviewed-by: Tony Lindgren Reviewed-by: Xu Yilun --- arch/x86/virt/vmx/tdx/seamldr.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/x86/virt/vmx/tdx/seamldr.c b/arch/x86/virt/vmx/tdx/seamld= r.c index 13c34e6378e0..ee672f381dd5 100644 --- a/arch/x86/virt/vmx/tdx/seamldr.c +++ b/arch/x86/virt/vmx/tdx/seamldr.c @@ -239,6 +239,7 @@ enum tdp_state { TDP_START, TDP_SHUTDOWN, TDP_CPU_INSTALL, + TDP_CPU_INIT, TDP_DONE, }; =20 @@ -303,6 +304,9 @@ static int do_seamldr_install_module(void *seamldr_para= ms) scoped_guard(raw_spinlock, &seamldr_lock) ret =3D seamldr_call(P_SEAMLDR_INSTALL, &args); break; + case TDP_CPU_INIT: + ret =3D tdx_cpu_enable(); + break; default: break; } --=20 2.47.3 From nobody Sat Feb 7 08:27:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 6FD2636212E; Fri, 23 Jan 2026 15:00:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180437; cv=none; b=j55619OlgBV4Tsd8mWIBS5vtA/TuSsvz2h3noFVLkoNiJyxes9G+B26K8KZqHEPJNag/6SAsguAFB+lE5OUM2aAFJr1vYYvf/YI3vzRXcqHqW1p8gafl4NZqEZw37370v24aOBaWnLHJr8NZqmW3JtuEaiOTuP71e3n6arkwX5o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180437; c=relaxed/simple; bh=xW4j0l2qmTh00vzb82ZFjrNGHJwRR46YR7Za6lDhCTM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HTecjTq179h5TOl35pOB7jm7Vyjlf3gAPwsWPrAqm2QgIint2RD9eQlexD6CXYKah/YaoG/bWH7tOSHTQHQ274DRNRrlyaLO6Qh7BDptSeE7dkGaOGDAFzHHA3trHN2T/WYyqlldphbRPi4O+xta5UCBo+kur6uqJkdNKcC/5IY= 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=nLixZieV; arc=none smtp.client-ip=192.198.163.17 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="nLixZieV" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1769180436; x=1800716436; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=xW4j0l2qmTh00vzb82ZFjrNGHJwRR46YR7Za6lDhCTM=; b=nLixZieVFWr2Mij+xWRMmBYa0ROECXZ/ATUeYN4kvROpD/lc+GSli4qS wqhTlfA+gMKbIcXtip9F2swfq/TYHjGAIJ73UUPYf2ndTD0YQyiQ0Pv8m CWmnE8kn2ATTgXKnM4NFl2g6T3Bh/x+8rSBp2Ln7eA0HAwVaSEyRnvnKa vxuKtW/SxiDG/K+txtwd0EXi4BfX+JtY5A8ZI5QdqoSMfa4usknu+IiwT jrTkwO6KYNYC0YvvZHVOCSeskVU5psQZcaNta9hAGvpYQhgjDGUQXknpQ Dqq0CgC0JJBVhMio2Xb7fEqDUNfU33Lark9FeiVw49RTuQgRsXa9rfUdV g==; X-CSE-ConnectionGUID: ahBA78O5Q2qpCL1LSUv8Hw== X-CSE-MsgGUID: z1vSkS9VS3eAIugAFHQd1w== X-IronPort-AV: E=McAfee;i="6800,10657,11680"; a="70334506" X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="70334506" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:19 -0800 X-CSE-ConnectionGUID: GrFZaddoSyyEii7M73hpiA== X-CSE-MsgGUID: TzUN+6HIRUWT81G8RXPZyA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="237697199" Received: from 984fee019967.jf.intel.com ([10.23.153.244]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:19 -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, Chao Gao , Farrah Chen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v3 21/26] x86/virt/tdx: Establish contexts for the new TDX Module Date: Fri, 23 Jan 2026 06:55:29 -0800 Message-ID: <20260123145645.90444-22-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260123145645.90444-1-chao.gao@intel.com> References: <20260123145645.90444-1-chao.gao@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" After being installed, the new TDX Module shouldn't re-configure the global HKID, TDMRs or PAMTs. Instead, to preserve running TDs, it should import the handoff data from the old module to establish all necessary contexts. Once the import is done, the TDX Module update is complete, and the new module is ready to handle requests from the VMM and guests. Call the TDH.SYS.UPDATE SEAMCALL to import the handoff data from the old module. Note that the location and the format of handoff data is defined by the TDX Module. The new module knows where to get the handoff data and how to parse it. The kernel doesn't need to provide its location, format etc. Signed-off-by: Chao Gao Tested-by: Farrah Chen Reviewed-by: Tony Lindgren --- v3: - use seamcall_prerr() rather than raw seamcall() [Binbin] - use pr_err() to print error message [Binbin] --- arch/x86/virt/vmx/tdx/seamldr.c | 5 +++++ arch/x86/virt/vmx/tdx/tdx.c | 16 ++++++++++++++++ arch/x86/virt/vmx/tdx/tdx.h | 2 ++ 3 files changed, 23 insertions(+) diff --git a/arch/x86/virt/vmx/tdx/seamldr.c b/arch/x86/virt/vmx/tdx/seamld= r.c index ee672f381dd5..7fa68c0c6ce4 100644 --- a/arch/x86/virt/vmx/tdx/seamldr.c +++ b/arch/x86/virt/vmx/tdx/seamldr.c @@ -240,6 +240,7 @@ enum tdp_state { TDP_SHUTDOWN, TDP_CPU_INSTALL, TDP_CPU_INIT, + TDP_RUN_UPDATE, TDP_DONE, }; =20 @@ -307,6 +308,10 @@ static int do_seamldr_install_module(void *seamldr_par= ams) case TDP_CPU_INIT: ret =3D tdx_cpu_enable(); break; + case TDP_RUN_UPDATE: + if (primary) + ret =3D tdx_module_run_update(); + break; default: break; } diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 2763c1869b78..2654aa169dda 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -1202,6 +1202,22 @@ int tdx_module_shutdown(void) return 0; } =20 +int tdx_module_run_update(void) +{ + struct tdx_module_args args =3D {}; + int ret; + + ret =3D seamcall_prerr(TDH_SYS_UPDATE, &args); + if (ret) { + pr_err("TDX-Module update failed (%d)\n", ret); + tdx_module_status =3D TDX_MODULE_ERROR; + return ret; + } + + tdx_module_status =3D TDX_MODULE_INITIALIZED; + return 0; +} + static bool is_pamt_page(unsigned long phys) { struct tdmr_info_list *tdmr_list =3D &tdx_tdmr_list; diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h index 1c4da9540ae0..0887debfd139 100644 --- a/arch/x86/virt/vmx/tdx/tdx.h +++ b/arch/x86/virt/vmx/tdx/tdx.h @@ -47,6 +47,7 @@ #define TDH_VP_WR 43 #define TDH_SYS_CONFIG 45 #define TDH_SYS_SHUTDOWN 52 +#define TDH_SYS_UPDATE 53 =20 /* * SEAMCALL leaf: @@ -120,5 +121,6 @@ struct tdmr_info_list { }; =20 int tdx_module_shutdown(void); +int tdx_module_run_update(void); =20 #endif --=20 2.47.3 From nobody Sat Feb 7 08:27:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 2710436A023; Fri, 23 Jan 2026 15:00:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180441; cv=none; b=tsc3RdBklViwpKvVgy8oxIM2lZAN7dEmVIW6eYZmF0tnmXK3byUcPY5kl7rV8pd5gzLyOr0BihiF3pHNRw4bOJJMSrtVQUgWOImM0DwinyDtvq2olsSiu38inGn7ziWxImqgWmi293mjr9lWWXPFq05LZmL/zg9WgWPABMdbMjk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180441; c=relaxed/simple; bh=KbDSi56WVEYQ90zmpbaEQB1XUcz2GYksChn0Kc4VnyA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pGkB5n9Y9I2YDYZhYl3Kns/KrvEGqIt2me0WSa5MHEm+Lot3EvCTH4lGdg0stc0mEFvWf1beow0JQsYw+saEtZBI69dmZ/yin8M7hYByUgcnwFY9Tm1u06W3Lsd/oJLmoRD4X4VKE3c8dQ3TgBx6fOXj0nBLZl54Mu4uRwRxRR0= 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=GUB75IwX; arc=none smtp.client-ip=192.198.163.17 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="GUB75IwX" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1769180438; x=1800716438; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=KbDSi56WVEYQ90zmpbaEQB1XUcz2GYksChn0Kc4VnyA=; b=GUB75IwXcV+6madUsrNGb8VHQ+UvRnpRSGoQ6xI92U1XqoLyI1CVUzmv HCNunnTPUYhJ/HyIvjKvyaC5+Bh8gGvYaqwjqNT70Y4hW/gnVvGL/WxdW fEx+Nu+CCxy49o4HFzdhTvtbab2iXNMQ6SSmAeIQzB6ausJ85oyYikaYI aWtO748LG0VRiARa9kx+w2ZF3PmcJFP7djiXCqvgNnZdJ5eBIJo4eYguU UFaBWspZRElkTiTnbR3LqK69nmFBwe0XjKvJZwKJZhLem62+h5uomaxC+ NfWCgcuyRVw5DWbnSlPXNx8pg6ux5bKSWZafr4ExGgVaFAKhCQn9jIyT4 w==; X-CSE-ConnectionGUID: sMDsa1exT/63jXf+ZQzrxQ== X-CSE-MsgGUID: z8sRJTTxQ+O7LL62NFUc3Q== X-IronPort-AV: E=McAfee;i="6800,10657,11680"; a="70334516" X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="70334516" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:20 -0800 X-CSE-ConnectionGUID: a/4x6YlUT8CPTGQa5rPs+g== X-CSE-MsgGUID: Wxhmcr6QRc2rUwj2QAJcUw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="237697208" Received: from 984fee019967.jf.intel.com ([10.23.153.244]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:20 -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, Chao Gao , Farrah Chen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v3 22/26] x86/virt/tdx: Update tdx_sysinfo and check features post-update Date: Fri, 23 Jan 2026 06:55:30 -0800 Message-ID: <20260123145645.90444-23-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260123145645.90444-1-chao.gao@intel.com> References: <20260123145645.90444-1-chao.gao@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" tdx_sysinfo contains all metadata of the active TDX module, including versions, supported features, and TDMR/TDCS/TDVPS information. These elements 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 Tested-by: Farrah Chen Reviewed-by: Tony Lindgren Reviewed-by: Xu Yilun --- 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/seamld= r.c index 7fa68c0c6ce4..d2d85114d6c4 100644 --- a/arch/x86/virt/vmx/tdx/seamldr.c +++ b/arch/x86/virt/vmx/tdx/seamldr.c @@ -357,6 +357,15 @@ int seamldr_install_module(const u8 *data, u32 size) if (!is_vmalloc_addr(data)) return -EINVAL; =20 + /* + * 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) =3D kzalloc(sizeof(*sysinfo), + GFP_KERNEL); + if (!sysinfo) + return -ENOMEM; + struct seamldr_params *params __free(free_seamldr_params) =3D init_seamldr_params(data, size); if (IS_ERR(params)) @@ -374,6 +383,6 @@ int seamldr_install_module(const u8 *data, u32 size) if (ret) return ret; =20 - 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 2654aa169dda..5d3f3f3eeb7d 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; } =20 +/* + * 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 =3D get_tdx_sys_info(info); + if (WARN_ONCE(ret, "version retrieval failed after update, replace TDX Mo= dule\n")) + return ret; + + old =3D &tdx_sysinfo.version; + new =3D &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 =3D info->version; + tdx_sysinfo.handoff =3D info->handoff; + + if (!memcmp(&tdx_sysinfo, info, sizeof(*info))) + return 0; + + pr_info("TDX module features have changed after updates, but might not ta= ke 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 =3D &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 @@ =20 #include =20 +#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 { =20 int tdx_module_shutdown(void); int tdx_module_run_update(void); +int tdx_module_post_update(struct tdx_sys_info *info); =20 #endif --=20 2.47.3 From nobody Sat Feb 7 08:27:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 3DB98352FB7; Fri, 23 Jan 2026 15:00:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180440; cv=none; b=i3csu5q1VndLBopiksf20/uGHD1qWof2mT8+REHBBdPyTDgwfeSPrlPdDhFKx2EnaUR0Oysoxpsg2/eFernJqCi/57aJQj+B8x9mUqJ1UHpKU2uRcHvk0ZLvBgDMX0P1sjsdcsV/ZvQG/+xVE9i1c+/iN58FICMkLQbUz5nPNx4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180440; c=relaxed/simple; bh=0g+/1AW3re/sy+yiWP4UxxTqPhaUBDy59R1dOAb9GAk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=P86NI/fqcD3SSoS1xymJWQXxf5JiThk1JCe44fbSycx6zWT8gvZ70SZKT40tEKL6p7KkJpzlFbfqaWQ2ypyFqHm3ESaP8pxldk7UgytF4GiO5fWdQEKDk1DKIhLZ1E8KCy3SdnjASGMUyDPCWUxcmvOXK/9uG3lmeXVNHl6Nxfw= 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=dwIy6eoU; arc=none smtp.client-ip=192.198.163.17 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="dwIy6eoU" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1769180438; x=1800716438; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=0g+/1AW3re/sy+yiWP4UxxTqPhaUBDy59R1dOAb9GAk=; b=dwIy6eoUjfJHNs6GFRxlxoIkUBkIBaN4TgmYJ6NenLkDjUz4gcqnBBb+ 9Hp9dNR6WgvuztU5jf/ZlkZsZoWMTfAV1r7FEix9i9QmupbryTKOfDSlZ mY0yl2IS1loSfjbj0pXWxMuWp62bVYVJBPj3f30C5mQI0s2CRxoQPVnf2 RO9scH4OHAw/gjgxOytjuCHpZ3SEHNYt6zK+uZPFgHwJ4T3VqvwtnyE4c CRpvRwflADhfpYlMijyigrChQqKVFiLbWdFhN7g+CaBIgLAwW/jpDgcDP gcrO63S7MKsJNn6ZHVSVM1hH29jvwOgjwaF7etAiqCJXSTqiXdokpqXTQ Q==; X-CSE-ConnectionGUID: VCYau2RuRu6sRZxq+surYQ== X-CSE-MsgGUID: MzR3ZRDEToWjebf7auh5FQ== X-IronPort-AV: E=McAfee;i="6800,10657,11680"; a="70334525" X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="70334525" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:20 -0800 X-CSE-ConnectionGUID: EpxuqmBOQBue2WoSpWetfA== X-CSE-MsgGUID: 2ZrjhY+nQ7WJQjRSTzqStQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="237697216" Received: from 984fee019967.jf.intel.com ([10.23.153.244]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:20 -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, Chao Gao , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v3 23/26] x86/virt/tdx: Enable TDX Module runtime updates Date: Fri, 23 Jan 2026 06:55:31 -0800 Message-ID: <20260123145645.90444-24-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260123145645.90444-1-chao.gao@intel.com> References: <20260123145645.90444-1-chao.gao@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" All pieces of TDX Module runtime updates are in place. Enable it if it is supported. Signed-off-by: Chao Gao Reviewed-by: Tony Lindgren Reviewed-by: Xu Yilun --- arch/x86/include/asm/tdx.h | 5 ++++- arch/x86/virt/vmx/tdx/tdx.h | 3 --- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h index ffadbf64d0c1..0cd408f902f4 100644 --- a/arch/x86/include/asm/tdx.h +++ b/arch/x86/include/asm/tdx.h @@ -32,6 +32,9 @@ #define TDX_SUCCESS 0ULL #define TDX_RND_NO_ENTROPY 0x8000020300000000ULL =20 +/* Bit definitions of TDX_FEATURES0 metadata field */ +#define TDX_FEATURES0_TD_PRESERVING BIT(1) +#define TDX_FEATURES0_NO_RBP_MOD BIT(18) #ifndef __ASSEMBLER__ =20 #include @@ -105,7 +108,7 @@ const struct tdx_sys_info *tdx_get_sysinfo(void); =20 static inline bool tdx_supports_runtime_update(const struct tdx_sys_info *= sysinfo) { - return false; /* To be enabled when kernel is ready */ + return sysinfo->features.tdx_features0 & TDX_FEATURES0_TD_PRESERVING; } =20 int tdx_guest_keyid_alloc(void); diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h index d1807a476d3b..749f4d74cb2c 100644 --- a/arch/x86/virt/vmx/tdx/tdx.h +++ b/arch/x86/virt/vmx/tdx/tdx.h @@ -88,9 +88,6 @@ struct tdmr_info { DECLARE_FLEX_ARRAY(struct tdmr_reserved_area, reserved_areas); } __packed __aligned(TDMR_INFO_ALIGNMENT); =20 -/* Bit definitions of TDX_FEATURES0 metadata field */ -#define TDX_FEATURES0_NO_RBP_MOD BIT(18) - /* * Do not put any hardware-defined TDX structure representations below * this comment! --=20 2.47.3 From nobody Sat Feb 7 08:27:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 B1BFC36656C; Fri, 23 Jan 2026 15:00:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180440; cv=none; b=RhF2LUZYvuHjAj3FaQCWXHJU6HW0po2dYuk080P+eKIkLUS44uvSKXSoxSIZAhxBvxTbHfNZMZ6+u41EUuQ8TfAQGtDdu2Qqzdp0DFxFskr+fsyFW1Et/ID/+rd2/Eipkxy8x25zgx+q7pg9Ds8sixhgTf+UQDHY21jzD6CKDjM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180440; c=relaxed/simple; bh=vvzbZrmWpmV4juJ40Ifm3lvVv14EgpU1dMvILRTmZHk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=DPSFoPD3F1EhFT1rLWknguwrFxH4yj+Ghq/VUQYYP1Uiqwh2p9Mwg8x+v/2cw5OxTBO7QkaUmSnCDCBQABvYanjGrDvxWB4T0oce4f2EhpOGE33CxO36F0jLQv8P43Z0gBJdmLcJQuAt29+vxqy3VMu1RYgGYAnF+gSOgKk4nAE= 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=JhItdOqe; arc=none smtp.client-ip=192.198.163.17 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="JhItdOqe" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1769180439; x=1800716439; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=vvzbZrmWpmV4juJ40Ifm3lvVv14EgpU1dMvILRTmZHk=; b=JhItdOqem5Q2CUwRkSzrRZe2kevhHUxmPA87mdo+PYdXQLrraUa/0bMA NtGxrFDIcJ/fH9VAiWKZkBwkdUwbJ+WFqnY6G99r+V8hKoYIv0pmRZzcq km7JxMwOR65X5bi3qtpI7cEYNsPhdW89L1Q3iUqwSqZacWeRBc5GPI8Fm 81mjXaYaChae9bHx6XRqE/OJlJCNQTxJrm0B0DGIENGkG0GSg+Lw81hos YIIkC2BRLuDcp0Lc1EZwGIHUXMoKXRGRlX4s2Fv8fT5GfD0AcHLDsSaYz Bod2Xmn9i1BYTxgDw4XbqTEfbWBCVwHB5BaFQzynuDxa8a0TnfjQ+Hy+3 A==; X-CSE-ConnectionGUID: c9UrCA3jQHeVD7R78cmzNQ== X-CSE-MsgGUID: LfqVcjYBTuihKnQs7Y8d4w== X-IronPort-AV: E=McAfee;i="6800,10657,11680"; a="70334535" X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="70334535" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:21 -0800 X-CSE-ConnectionGUID: +sdwN0EGS4GqpGe5TPcqoA== X-CSE-MsgGUID: xnPA9BEAT1OlpSc2sHrXWg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="237697219" Received: from 984fee019967.jf.intel.com ([10.23.153.244]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:21 -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, Chao Gao , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v3 24/26] x86/virt/seamldr: Extend sigstruct to 16KB Date: Fri, 23 Jan 2026 06:55:32 -0800 Message-ID: <20260123145645.90444-25-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260123145645.90444-1-chao.gao@intel.com> References: <20260123145645.90444-1-chao.gao@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Currently, each TDX Module has a 4KB sigstruct that is passed to the P-SEAMLDR during module updates to authenticate the TDX Module binary. Future TDX Module versions will pack additional information into the sigstruct, which will exceed the current 4KB size limit. To accommodate this, the sigstruct is being extended to support up to 16KB. Update seamldr_params and tdx-blob structures to handle the larger sigstruct size. Signed-off-by: Chao Gao Reviewed-by: Tony Lindgren --- arch/x86/virt/vmx/tdx/seamldr.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/arch/x86/virt/vmx/tdx/seamldr.c b/arch/x86/virt/vmx/tdx/seamld= r.c index d2d85114d6c4..9e77b24f659c 100644 --- a/arch/x86/virt/vmx/tdx/seamldr.c +++ b/arch/x86/virt/vmx/tdx/seamldr.c @@ -29,6 +29,8 @@ /* P-SEAMLDR can accept up to 496 4KB pages for TDX module binary */ #define SEAMLDR_MAX_NR_MODULE_4KB_PAGES 496 =20 +#define SEAMLDR_MAX_NR_SIG_4KB_PAGES 4 + /* scenario field in struct seamldr_params */ #define SEAMLDR_SCENARIO_UPDATE 1 =20 @@ -40,8 +42,8 @@ struct seamldr_params { u32 version; u32 scenario; - u64 sigstruct_pa; - u8 reserved[104]; + u64 sigstruct_pa[SEAMLDR_MAX_NR_SIG_4KB_PAGES]; + u8 reserved[80]; u64 num_module_pages; u64 mod_pages_pa_list[SEAMLDR_MAX_NR_MODULE_4KB_PAGES]; } __packed; @@ -121,7 +123,10 @@ static struct seamldr_params *alloc_seamldr_params(con= st void *module, unsigned if (module_size > SEAMLDR_MAX_NR_MODULE_4KB_PAGES * SZ_4K) return ERR_PTR(-EINVAL); =20 - if (!IS_ALIGNED(module_size, SZ_4K) || sig_size !=3D SZ_4K || + if (sig_size > SEAMLDR_MAX_NR_SIG_4KB_PAGES * SZ_4K) + return ERR_PTR(-EINVAL); + + if (!IS_ALIGNED(module_size, SZ_4K) || !IS_ALIGNED(sig_size, SZ_4K) || !IS_ALIGNED((unsigned long)module, SZ_4K) || !IS_ALIGNED((unsigned long)sig, SZ_4K)) return ERR_PTR(-EINVAL); @@ -132,12 +137,17 @@ static struct seamldr_params *alloc_seamldr_params(co= nst void *module, unsigned =20 params->scenario =3D SEAMLDR_SCENARIO_UPDATE; =20 - /* - * Don't assume @sig is page-aligned although it is 4KB-aligned. - * Always add the in-page offset to get the physical address. - */ - params->sigstruct_pa =3D (vmalloc_to_pfn(sig) << PAGE_SHIFT) + - ((unsigned long)sig & ~PAGE_MASK); + ptr =3D sig; + for (i =3D 0; i < sig_size / SZ_4K; i++) { + /* + * Don't assume @sig is page-aligned although it is 4KB-aligned. + * Always add the in-page offset to get the physical address. + */ + params->sigstruct_pa[i] =3D (vmalloc_to_pfn(ptr) << PAGE_SHIFT) + + ((unsigned long)ptr & ~PAGE_MASK); + ptr +=3D SZ_4K; + } + params->num_module_pages =3D module_size / SZ_4K; =20 ptr =3D module; --=20 2.47.3 From nobody Sat Feb 7 08:27:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 AC1BB2E92D2; Fri, 23 Jan 2026 15:00:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180442; cv=none; b=L1oAoVZ3qwwm1FPkpSbhQTvjdyMPlYvQfPcyA9pdtbhTrCHdf44xF2LOa+Ajs2EfjJBXV+teqN7MlYZDYmaSD0wbNw7btAQgppvl8q6s4XkBrashAgtjIyKjYjLDA5fYXbbjkNtQ+59iFcyjMrOcpBXI+f4Cc0zzmA1oafFXu74= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180442; c=relaxed/simple; bh=ChYtG309Tbh3eYosJ6vQDIt+smUYzcJ5csnA0tNPxIc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EP6904o0ohu75/yx6sXjSxxCJ3oF1k+3Zoih8GYYfe+l3PLld1D88WgBcLw6mMdRnQgYHsQQfFvFGkBKauoZ1CPMZuqn6Zcnn3tXAibTw4vBpIsqVC8K9e0O8+9vOsrPk0B5IDQOFZk1fKJWFX1NyOYsBgOfscx1SYy3wV9cV4E= 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=YRCWR7MY; arc=none smtp.client-ip=192.198.163.17 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="YRCWR7MY" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1769180441; x=1800716441; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ChYtG309Tbh3eYosJ6vQDIt+smUYzcJ5csnA0tNPxIc=; b=YRCWR7MY34HGlgEBJC5yLsq4M5lGWVazqftxxiHXIDhYZLAxdL/XXLQX LoQdTHfSWPpnwH3vHEe9C3ywwAhTVA9aoepzdecgFVyyG06jR1k0TBh+P R/SCfPdZv7hS9hdliSPMm6Z3/kbPpu4Fmu3E1CrMr0GivER3YDjU1W1mR lVOxISUoG6wADGAdx+bWuFjlzmCQI4CGjhsBrz8ZcvLaIMKZka8SX/wAH yEzuNindPc6esCbx1Gz0rkm+ULZVMKRQnVcji/TTJf0mOXlaeP1dOx6Pm f1+8MNQBYM4aWKoNyqWpZtM+GTEgtgtPa1XbWjyKCYg3zq4Bwx9BAXG8w Q==; X-CSE-ConnectionGUID: tahIEQEbQAmPtejb2urzDQ== X-CSE-MsgGUID: n7m6E5syQdWQBAxlXYtr2Q== X-IronPort-AV: E=McAfee;i="6800,10657,11680"; a="70334544" X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="70334544" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:21 -0800 X-CSE-ConnectionGUID: XEUXxL6dQtOI8+9yqSsKTw== X-CSE-MsgGUID: kkUWZcVbRom9SqR3Z7YDcg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="237697246" Received: from 984fee019967.jf.intel.com ([10.23.153.244]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:21 -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, Chao Gao , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" , Paolo Bonzini Subject: [PATCH v3 25/26] x86/virt/tdx: Avoid updates during update-sensitive operations Date: Fri, 23 Jan 2026 06:55:33 -0800 Message-ID: <20260123145645.90444-26-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260123145645.90444-1-chao.gao@intel.com> References: <20260123145645.90444-1-chao.gao@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" TDX Module updates may cause TD management operations to fail if they occur during phases of the TD lifecycle that are sensitive to update compatibility. Currently, there are two update-sensitive scenarios: - TD build, where TD Measurement Register (TDMR) accumulates over multiple TDH.MEM.PAGE.ADD, TDH.MR.EXTEND and TDH.MR.FINALIZE calls. - TD migration, where an intermediate crypto state is saved if a state migration function (TDH.EXPORT.STATE.* or TDH.IMPORT.STATE.*) is interrupted and restored when the function is resumed. For example, if an update races with TD build operations, the TD Measurement Register will become incorrect, causing the TD to fail attestation. The TDX Module offers two solutions: 1. Avoid updates during update-sensitive times The host VMM can instruct TDH.SYS.SHUTDOWN to fail if any of the TDs are currently in any update-sensitive cases. 2. Detect incompatibility after updates On TDH.SYS.UPDATE, the host VMM can configure the TDX Module to detect actual incompatibility cases. The TDX Module will then return a special error to signal the incompatibility, allowing the host VMM to restart the update-sensitive operations. Implement option #1 to fail updates if the feature is available. Also, distinguish this update failure from other failures by returning -EBUSY, which will be converted to a firmware update error code indicating that the firmware is busy. Options like "do nothing" or option #2 are not viable [1] because the former allows damage to propagate to multiple, potentially unknown components (adding significant complexity to the whole ecosystem), while the latter may make existing KVM ioctls unstable. Based on a reference patch by Vishal [2]. Signed-off-by: Chao Gao Link: https://lore.kernel.org/linux-coco/aQIbM5m09G0FYTzE@google.com/ # [1] Link: https://lore.kernel.org/linux-coco/CAGtprH_oR44Vx9Z0cfxvq5-QbyLmy_+Gn= 3tWm3wzHPmC1nC0eg@mail.gmail.com/ # [2] Reviewed-by: Tony Lindgren --- arch/x86/include/asm/tdx.h | 13 +++++++++++-- arch/x86/kvm/vmx/tdx_errno.h | 2 -- arch/x86/virt/vmx/tdx/tdx.c | 23 +++++++++++++++++++---- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h index 0cd408f902f4..85746de7c528 100644 --- a/arch/x86/include/asm/tdx.h +++ b/arch/x86/include/asm/tdx.h @@ -26,15 +26,19 @@ #define TDX_SEAMCALL_GP (TDX_SW_ERROR | X86_TRAP_GP) #define TDX_SEAMCALL_UD (TDX_SW_ERROR | X86_TRAP_UD) =20 +#define TDX_SEAMCALL_STATUS_MASK 0xFFFFFFFF00000000ULL + /* * TDX module SEAMCALL leaf function error codes */ -#define TDX_SUCCESS 0ULL -#define TDX_RND_NO_ENTROPY 0x8000020300000000ULL +#define TDX_SUCCESS 0ULL +#define TDX_RND_NO_ENTROPY 0x8000020300000000ULL +#define TDX_UPDATE_COMPAT_SENSITIVE 0x8000051200000000ULL =20 /* Bit definitions of TDX_FEATURES0 metadata field */ #define TDX_FEATURES0_TD_PRESERVING BIT(1) #define TDX_FEATURES0_NO_RBP_MOD BIT(18) +#define TDX_FEATURES0_UPDATE_COMPAT BIT_ULL(47) #ifndef __ASSEMBLER__ =20 #include @@ -111,6 +115,11 @@ static inline bool tdx_supports_runtime_update(const s= truct tdx_sys_info *sysinf return sysinfo->features.tdx_features0 & TDX_FEATURES0_TD_PRESERVING; } =20 +static inline bool tdx_supports_update_compatibility(const struct tdx_sys_= info *sysinfo) +{ + return sysinfo->features.tdx_features0 & TDX_FEATURES0_UPDATE_COMPAT; +} + int tdx_guest_keyid_alloc(void); u32 tdx_get_nr_guest_keyids(void); void tdx_guest_keyid_free(unsigned int keyid); diff --git a/arch/x86/kvm/vmx/tdx_errno.h b/arch/x86/kvm/vmx/tdx_errno.h index 6ff4672c4181..215c00d76a94 100644 --- a/arch/x86/kvm/vmx/tdx_errno.h +++ b/arch/x86/kvm/vmx/tdx_errno.h @@ -4,8 +4,6 @@ #ifndef __KVM_X86_TDX_ERRNO_H #define __KVM_X86_TDX_ERRNO_H =20 -#define TDX_SEAMCALL_STATUS_MASK 0xFFFFFFFF00000000ULL - /* * TDX SEAMCALL Status Codes (returned in RAX) */ diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 5d3f3f3eeb7d..5b562255630b 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -1175,10 +1175,13 @@ int tdx_enable(void) } EXPORT_SYMBOL_FOR_KVM(tdx_enable); =20 +#define TDX_SYS_SHUTDOWN_AVOID_COMPAT_SENSITIVE BIT(16) + int tdx_module_shutdown(void) { struct tdx_module_args args =3D {}; - int ret, cpu; + u64 ret; + int cpu; =20 /* * Shut down the TDX Module and prepare handoff data for the next @@ -1189,9 +1192,21 @@ int tdx_module_shutdown(void) * hand-off version. */ args.rcx =3D tdx_sysinfo.handoff.module_hv; - ret =3D seamcall_prerr(TDH_SYS_SHUTDOWN, &args); - if (ret) - return ret; + + if (tdx_supports_update_compatibility(&tdx_sysinfo)) + args.rcx |=3D TDX_SYS_SHUTDOWN_AVOID_COMPAT_SENSITIVE; + + ret =3D seamcall(TDH_SYS_SHUTDOWN, &args); + + /* + * Return -EBUSY to signal that there is one or more ongoing flows + * which may not be compatible with an updated TDX module, so that + * userspace can retry on this error. + */ + if ((ret & TDX_SEAMCALL_STATUS_MASK) =3D=3D TDX_UPDATE_COMPAT_SENSITIVE) + return -EBUSY; + else if (ret) + return -EIO; =20 tdx_module_status =3D TDX_MODULE_UNINITIALIZED; sysinit_done =3D false; --=20 2.47.3 From nobody Sat Feb 7 08:27:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.17]) (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 0409D28FFFB; Fri, 23 Jan 2026 15:00:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.17 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180443; cv=none; b=PpOlFXjBlRZ8/Sq1gwkXEi6akYiJePIHYEoerqJeV8ATAcNEVrHb1M0BARHn7DmA6tZIk6K0RNHP7EbbyY/xTvNhv5tdY3GN9anJWjpccFD/X9mi7X/+p9x5fXKHDRyUSU9O1gRgyX6sUigZdhhUBTn0O2NDUXtUVt37Nt8O1N0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769180443; c=relaxed/simple; bh=TR8Wv5ycc+2AvBtNRmnwUDkwXK3rxb5okVi7Q7pIqzQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=F/ybB9Oy9wfq1G9YNjzGZrPS6QCaf+V69FZ4lkDCF50Xpa1LOe//NVL3sigMIG5HPo9UvlWJwidczrGBYJaxaqb02ENpwAUPtOz6xx1LzbG1Za0DCQRBUEzIhhOj65VbdzpUdC7Q3txTfBLc9oh0lIyfvFFft278+9R5/HTp7Xk= 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=E9COFoZA; arc=none smtp.client-ip=192.198.163.17 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="E9COFoZA" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1769180441; x=1800716441; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=TR8Wv5ycc+2AvBtNRmnwUDkwXK3rxb5okVi7Q7pIqzQ=; b=E9COFoZAAFrnvNUZvt7HC6muAY1iLwkgLzdaPyLY77L0SjM5W/0PQFVb Ueq2XcZX5xVXg841fxTlTmMR3sCPhrDh0YHlwzZ0Ot8eUzIMvTHd3KymW HnFhOp1MFgsYk/Ho4ibyghQ8egXAARr1LOmXb7NnXbSjPsPUiJ+66I0ma mZy28LatMzfYJ02Pi+wtUCfmAtQwdsp89ue7bA3u/lIyghXyEMU0649Es cO/LWUKJA+QlH7s1QQMXZmartq9dJfc3pVwdMicdWBG9d6+AiD6cEuNDi C5ZrumDyFiE6Am+M7xqNrjRdecsDEJQPwMz9p7YU+9NJgl/7aHRn4cBR0 A==; X-CSE-ConnectionGUID: 1BuCiVt0SKWQPH2sxjABHA== X-CSE-MsgGUID: KzbSnrSUQXOLCPFnxNESEw== X-IronPort-AV: E=McAfee;i="6800,10657,11680"; a="70334550" X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="70334550" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:22 -0800 X-CSE-ConnectionGUID: rsVdXnvvQZWVc2vCYKRzdw== X-CSE-MsgGUID: ZAde7awbTDGOUW/OXNJHpw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,248,1763452800"; d="scan'208";a="237697258" Received: from 984fee019967.jf.intel.com ([10.23.153.244]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Jan 2026 07:00:22 -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, Chao Gao Subject: [PATCH v3 26/26] coco/tdx-host: Set and document TDX Module update expectations Date: Fri, 23 Jan 2026 06:55:34 -0800 Message-ID: <20260123145645.90444-27-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260123145645.90444-1-chao.gao@intel.com> References: <20260123145645.90444-1-chao.gao@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In rare cases, TDX Module updates may cause TD management operations to fail if they occur during phases of the TD lifecycle that are sensitive to update compatibility. But not all combinations of P-SEAMLDR, kernel, and TDX Module have the capability to detect and prevent said incompatibilities. Completely disabling TDX Module updates on platforms without the capability would be overkill, as these incompatibility cases are rare and can be addressed by userspace through coordinated scheduling of updates and TD management operations. To set clear expectations for TDX Module updates, expose the capability to detect and prevent these incompatibility cases via sysfs and document the compatibility criteria and indications when those criteria are violated. Signed-off-by: Chao Gao Reviewed-by: Dan Williams Reviewed-by: Tony Lindgren --- v3: - new, based on a reference patch from Dan Williams --- .../ABI/testing/sysfs-devices-faux-tdx-host | 45 +++++++++++++++++++ drivers/virt/coco/tdx-host/tdx-host.c | 13 ++++++ 2 files changed, 58 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-devices-faux-tdx-host b/Docume= ntation/ABI/testing/sysfs-devices-faux-tdx-host index a3f155977016..81cb13e91f2a 100644 --- a/Documentation/ABI/testing/sysfs-devices-faux-tdx-host +++ b/Documentation/ABI/testing/sysfs-devices-faux-tdx-host @@ -29,3 +29,48 @@ Description: (RO) Report the number of remaining updates= that can be performed. 4.2 "SEAMLDR.INSTALL" for more information. The documentation is available at: https://cdrdv2-public.intel.com/739045/intel-tdx-seamldr-interface-speci= fication.pdf + +What: /sys/devices/faux/tdx_host/firmware/seamldr_upload +Contact: linux-coco@lists.linux.dev +Description: (Directory) The seamldr_upload directory implements the + fw_upload sysfs ABI, see + Documentation/ABI/testing/sysfs-class-firmware for the general + description of the attributes @data, @cancel, @error, @loading, + @remaining_size, and @status. This ABI facilitates "Compatible + TDX Module Updates". A compatible update is one that meets the + following criteria: + + Does not interrupt or interfere with any current TDX + operation or TD VM. + + Does not invalidate any previously consumed Module metadata + values outside of the TEE_TCB_SVN_2 field (updated Security + Version Number) in TD Quotes. + + Does not require validation of new Module metadata fields. By + implication, new Module features and capabilities are only + available by installing the Module at reboot (BIOS or EFI + helper loaded). + + See tdx_host/compat_capable and + tdx_host/firmware/seamldr_upload/error. For details. + +What: /sys/devices/faux/tdx_host/compat_capable +Contact: linux-coco@lists.linux.dev +Description: (RO) When present this attribute returns "1" to indicate that + the current seamldr, kernel, and TDX Module combination can + detect when an update conforms with the "Compatible TDX Module + Updates" criteria in the tdx_host/firmware/seamldr_upload description. + When this attribute is missing it is indeterminate whether an + update will violate the criteria. + +What: /sys/devices/faux/tdx_host/firmware/seamldr_upload/error +Contact: linux-coco@lists.linux.dev +Description: (RO) See Documentation/ABI/testing/sysfs-class-firmware for + baseline expectations for this file. Updates that fail + compatibility checks end with the "device-busy" error in the + : format of this attribute. When this is + signalled current TDs and the current TDX Module stay running. + Other failures may result in all TDs being lost and further + TDX operations becoming impossible. This occurs when + /sys/devices/faux/tdx_host/version becomes unreadable. diff --git a/drivers/virt/coco/tdx-host/tdx-host.c b/drivers/virt/coco/tdx-= host/tdx-host.c index 06487de2ebfe..8cc48e276533 100644 --- a/drivers/virt/coco/tdx-host/tdx-host.c +++ b/drivers/virt/coco/tdx-host/tdx-host.c @@ -45,8 +45,21 @@ static ssize_t version_show(struct device *dev, struct d= evice_attribute *attr, } static DEVICE_ATTR_RO(version); =20 +static ssize_t compat_capable_show(struct device *dev, struct device_attri= bute *attr, + char *buf) +{ + const struct tdx_sys_info *tdx_sysinfo =3D tdx_get_sysinfo(); + + if (!tdx_sysinfo) + return -ENXIO; + + return sysfs_emit(buf, "%i\n", tdx_supports_update_compatibility(tdx_sysi= nfo)); +} +static DEVICE_ATTR_RO(compat_capable); + static struct attribute *tdx_host_attrs[] =3D { &dev_attr_version.attr, + &dev_attr_compat_capable.attr, NULL, }; =20 --=20 2.47.3