From nobody Wed Oct 1 21:27:10 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 CA56627A927 for ; Wed, 1 Oct 2025 02:54:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287292; cv=none; b=DOQbLupVWtchkqoxtf2/g6e5xSvCFEhMWVHBfQCe8vBSJszZ5dgewzPS1yIWlBkFthVpdJKowWSMV4XrBCFiS9mZuq5bWcXLKECkk45pOyDUN2JR73r1XOb80wHo18fd82Qcu18ZZHOEVPIy7vDiZbjXoi06VbZkYlJLrlWJlnk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287292; c=relaxed/simple; bh=yzXsG45V6hDY5JoOy9A7+02aECqQ79Pt6rGJt6bu3fw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hh9qwXTv85ULJEycMmXDf55b6QTiK9gzssbuGA9o/PmKqifOFWqiYhBlPLlT585GHh61x04jnE4Mwy5mz7jpwCaXekxOF+QkFjoEF9bdGCeICsV3hpySCmyxTjXG6JMrH0nidLfsNXXljJ9zo2DiFYTf+i/ycYIYID1BoWCcAfo= 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=NaH+9oQc; arc=none smtp.client-ip=192.198.163.15 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="NaH+9oQc" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1759287291; x=1790823291; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=yzXsG45V6hDY5JoOy9A7+02aECqQ79Pt6rGJt6bu3fw=; b=NaH+9oQcWhD1jpDbg/kSGH+PJKb1wB7xEvMdGRTpl9RT+WLRjLsagqWV ohyYzwTVjQmG6eQofvSB8y50BxE1UR6/JqFhj7Z9LO7IMrO7gMZVNwfp6 DYvrktmcLllVWPZdzeCRyd91X29HLoeluGnzkXn7zl7jJh3+uR7utCBK1 PeITrlvQXvq/daN1reDdIUmLwuflHHQ90qgI+BXz1pXzmZ6gzrFuQASrC SoWSJHKnzKVBzwoUQlikJa5wTnJ+qcJUmSvY1/8OgkzvC3qvfVEiaa24g WGVFLX256S9oVwtu8vN/kp3pX/wXpcUNvtvOTdfzJIC3ZcdXrVMSAqZZl w==; X-CSE-ConnectionGUID: Ga9Vh3jeTa2wwHPF8PwxlA== X-CSE-MsgGUID: 48f7RWn+Ro2ribqlsQxJeg== X-IronPort-AV: E=McAfee;i="6800,10657,11569"; a="61662199" X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="61662199" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:54:49 -0700 X-CSE-ConnectionGUID: Svg5KCFMQYy8fx0wjCFHbg== X-CSE-MsgGUID: azAPzeZzTNKGpMY4cQfWfA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="178629025" Received: from 984fee019967.jf.intel.com ([10.165.54.94]) by fmviesa006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:54:48 -0700 From: Chao Gao To: linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org, x86@kernel.org, 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 Cc: Chao Gao , "Kirill A. Shutemov" , Farrah Chen , "Kirill A. Shutemov" , Dave Hansen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v2 01/21] x86/virt/tdx: Print SEAMCALL leaf numbers in decimal Date: Tue, 30 Sep 2025 19:52:45 -0700 Message-ID: <20251001025442.427697-2-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251001025442.427697-1-chao.gao@intel.com> References: <20251001025442.427697-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 --- 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 ada2fd4c2d54..e406edd28687 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -62,7 +62,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 Wed Oct 1 21:27:10 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 CCC4927AC21 for ; Wed, 1 Oct 2025 02:54:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287293; cv=none; b=StxpILQRrykdj/Pd5Dx1wQxWR/K5B6fUVZBeDDmgUjvZmOk0V8xYTPIhRBTGKVGTbjf8QGQ5axNg375UExS0wL9gS9gRt2EkOq35OeFubxoXA53JBdhb0dj0BQfWX3MHv7CAaidOHynME0fLPxAsTI5HkvzWjOx8xOv4PkD7iJ4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287293; c=relaxed/simple; bh=Bm1Rky4SqDIX2DDhUjvproP1XyUcq4gPtKHSlGNNq5w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=aQVf/9BmjEBFFb2Il8BYIxslmz/iNpawX4yxg6mktwsQEBJ/pr74PF7GWKWwfDYzZwz09MqDqdxHtpFW//m93bUCDkU29BhypoKWrn/sp63JHbPXge40DbZWU6091fhYj2Y4hM+kVTHsyxbR8WWZMBJ8E5kfVFxiVkSawcqu91Y= 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=H4MCSfyz; arc=none smtp.client-ip=192.198.163.15 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="H4MCSfyz" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1759287292; x=1790823292; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Bm1Rky4SqDIX2DDhUjvproP1XyUcq4gPtKHSlGNNq5w=; b=H4MCSfyz5Bu3Tp7DulQRtYQhA4sFxEjgwMBsa5uKYmWs3LCXsLoS6Zn8 b1Um1P1yNW+XzSa71dyenAxmHr083aZX303fEruBvvRuUmDpKiRYgh1il W8j7FVp8DjX2I3yCpchiZ/BJ5JnwuwRQAS5/xbHZ3F3tGMS4W8m9aemev GW7a1nhuIhqfaAtljChuSoZ43vQ5p0V5ceMRfN+5mtwUD9Wt8CBbIIWzo vzI7gB80CP5PVocIKWRV3p4i6mzJ66nDfSqCQv9chV9xJhbDgh9SqeG9h Axa30KsP7yhrGSzPJaUTwZ8Vm2rz+r1YVUFBdjcNzPv02kcrgkcmCrgnn g==; X-CSE-ConnectionGUID: tcEQGaO7RPaIqI9NU9E0aw== X-CSE-MsgGUID: rs9EPoMbQZqpKU1/Gd6aoA== X-IronPort-AV: E=McAfee;i="6800,10657,11569"; a="61662208" X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="61662208" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:54:50 -0700 X-CSE-ConnectionGUID: vAnsVhtyR16BsSuEgoGrGQ== X-CSE-MsgGUID: PdnsPp/CRnCQox3bofkB0g== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="178629035" Received: from 984fee019967.jf.intel.com ([10.165.54.94]) by fmviesa006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:54:49 -0700 From: Chao Gao To: linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org, x86@kernel.org, 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 Cc: Chao Gao , "Kirill A. Shutemov" , Dave Hansen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v2 02/21] x86/virt/tdx: Use %# prefix for hex values in SEAMCALL error messages Date: Tue, 30 Sep 2025 19:52:46 -0700 Message-ID: <20251001025442.427697-3-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251001025442.427697-1-chao.gao@intel.com> References: <20251001025442.427697-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 --- "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 e406edd28687..f429a5fdced2 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -62,16 +62,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 Wed Oct 1 21:27:10 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 9F74D27B346 for ; Wed, 1 Oct 2025 02:54:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287295; cv=none; b=IAPD7mmQ/zJsavR0jUGyvoCE9hHHhsaqaFu0i99tDcsjieMynkuiEUVhT2t5eCV2JumtMVZRepZLc/klX2liwfBH9XqSdHwvzPYWgt4/0iLqe2K9wvIELuB69oCeT0I2PGNZuyNxAKXin2IXmCDASGcCiZ2MLHmJpbQrMPYicYM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287295; c=relaxed/simple; bh=ywSaXaJwOa73ESjkbxV1uYIawVM2AD2ld4kYPgNvf+w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NQDXvQqmn9+8U1kGqtu/HVwBAO9c+gHvcdYhuBWUtOki/K5O4ykocZWOBQxvrPSX6/i5utRdGzMf6QRPOabpMdUApsVvFdBKu/DeUPCXKWpv4msurGNpLqGTOtC1qo8wBVLCQBTY1uMRTnDQcKjwshF9Pa4taxRA+6riBYphtqI= 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=M5+/N+mJ; arc=none smtp.client-ip=192.198.163.15 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="M5+/N+mJ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1759287294; x=1790823294; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ywSaXaJwOa73ESjkbxV1uYIawVM2AD2ld4kYPgNvf+w=; b=M5+/N+mJX+i1CfHyHRyBK4BBLUF6KcE0pqfOr+2P4KP+Pt4l1p18saWf WaCZyjaLGfiLs3IUcIpGj0yIdbPcRNb5ZuxBO1t09ccLcEHbRUnnnI6AW fQbSmwZMKazhzAFQ8XneEA5EZxzBcZDqsC+Eci9wLj7US/bMp52yoNd4e 9dcurE9astqUbhwUmUijTI4hhe+qaGHmfY9r97xMF+EABBa/7mLVbK6q5 F8RYeiyvvALbuKHgvGaCehCMU8qm2dqOSJrbSXNR1AHpajSasPkwhqCa4 bpCwhzJd6J2ZgNNxYkfgV25d1GV3IfSs7+7fSsQLCPl8DIRbkfp6Z/ZhW w==; X-CSE-ConnectionGUID: ifuVdQ/tTg65DEOcUW3GDg== X-CSE-MsgGUID: meq5BFaET22s6q188SXLYQ== X-IronPort-AV: E=McAfee;i="6800,10657,11569"; a="61662220" X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="61662220" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:54:52 -0700 X-CSE-ConnectionGUID: Ki9Qj/Y3Sj23MqwyRnL7EA== X-CSE-MsgGUID: wNCp/jOfSNKe60j4TIz5UA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="178629044" Received: from 984fee019967.jf.intel.com ([10.165.54.94]) by fmviesa006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:54:51 -0700 From: Chao Gao To: linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org, x86@kernel.org, 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 Cc: Chao Gao , "Kirill A. Shutemov" , Dave Hansen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v2 03/21] x86/virt/tdx: Move low level SEAMCALL helpers out of Date: Tue, 30 Sep 2025 19:52:47 -0700 Message-ID: <20251001025442.427697-4-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251001025442.427697-1-chao.gao@intel.com> References: <20251001025442.427697-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 --- v2: - new --- arch/x86/include/asm/tdx.h | 24 ---------- arch/x86/virt/vmx/tdx/seamcall.h | 79 ++++++++++++++++++++++++++++++++ arch/x86/virt/vmx/tdx/tdx.c | 46 +------------------ 3 files changed, 80 insertions(+), 69 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 cbea169b5fa0..e872a411a359 100644 --- a/arch/x86/include/asm/tdx.h +++ b/arch/x86/include/asm/tdx.h @@ -97,31 +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 - -typedef u64 (*sc_func_t)(u64 fn, struct tdx_module_args *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)) int tdx_enable(void); const char *tdx_dump_mce_info(struct mce *m); const struct tdx_sys_info *tdx_get_sysinfo(void); diff --git a/arch/x86/virt/vmx/tdx/seamcall.h b/arch/x86/virt/vmx/tdx/seamc= all.h new file mode 100644 index 000000000000..71b6ffddfa40 --- /dev/null +++ b/arch/x86/virt/vmx/tdx/seamcall.h @@ -0,0 +1,79 @@ +/* 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 + +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 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 f429a5fdced2..b367bb1d94ed 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -38,6 +38,7 @@ #include #include #include +#include "seamcall.h" #include "tdx.h" =20 static u32 tdx_global_keyid __ro_after_init; @@ -58,51 +59,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 Wed Oct 1 21:27:10 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 F19C427E1D0 for ; Wed, 1 Oct 2025 02:54:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287295; cv=none; b=kgii8Et7UurEwbRitNDFUBf6YvKaFhYou3EenzGOUK/CkcgYEBJajox5DHu+VAGXc6F1u7AqiXpYmO80jq+wGxVuYueNgnsah9IEy8v8yqEqIYM2uNuUc4W8lVfJPWzWcIe4LdghxOQRg/ZwwUbVv7/ftjAlABlOru1Kx8YL1I4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287295; c=relaxed/simple; bh=YS73C+hBeSoRqaytIT9NA8P9FF+ljv00QzUK/USjtbU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VA+OWn7NkaW6uLwXE/P1+ZTQOsiTTaP6E9XSEFuxPU/nBryovny8C0hF3ma3PYGOYdJ3x7CbNd/8YIXcCnzD0mljsc1/KyDe+Lr/Pp4mfueRaAUGZiK6bydvRuA/HYXdJrq1Mg6QIYTmGN5gUL+9t3NQOnSjgJ/NOgPNFre0REI= 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=HgShaULn; arc=none smtp.client-ip=192.198.163.15 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="HgShaULn" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1759287294; x=1790823294; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=YS73C+hBeSoRqaytIT9NA8P9FF+ljv00QzUK/USjtbU=; b=HgShaULnk8A/N2s3PRwWHvwjPGjrmOjLIx7A4BX1m3SbSFMpQRVQvFjf rhGCcYG4HXvXDVcRI4Q/yKMC8ALTEMWmCw7fBLKm42IrgUrKCCBpAy5Ee k0fnVZ73U6FMJBLl6TutEqtUop9Q5zoD/3HcL+PMQPn1GRwuKeicbPbUC I4fLe3Dc2TcKE9QOyMA6f9Q2oboqYsWZURdFx0nORR8vNaYvlQnTyZsuA UMs/mzwyv93Rq8waKJ191PoosmZo5qIT5yK/S8hnzuj0MTdb58vDWbzmP XgLkloaV5wG75ywbcW5C29lbxeZ7CIZ9BdpE3CORjDXCOVcFzrsGiJxXQ g==; X-CSE-ConnectionGUID: wre8aySJQ4KZoM0JwN4/gw== X-CSE-MsgGUID: vYKUtyILQMG9s7BbzcUhIQ== X-IronPort-AV: E=McAfee;i="6800,10657,11569"; a="61662229" X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="61662229" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:54:54 -0700 X-CSE-ConnectionGUID: bzWHOaFnTyCXQJ1Li8MVag== X-CSE-MsgGUID: QbmrkhGFToSXPUBj6DeNOw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="178629049" Received: from 984fee019967.jf.intel.com ([10.165.54.94]) by fmviesa006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:54:52 -0700 From: Chao Gao To: linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org, x86@kernel.org, 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 Cc: Chao Gao , Farrah Chen , "Kirill A. Shutemov" , Dave Hansen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v2 04/21] x86/virt/tdx: Prepare to support P-SEAMLDR SEAMCALLs Date: Tue, 30 Sep 2025 19:52:48 -0700 Message-ID: <20251001025442.427697-5-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251001025442.427697-1-chao.gao@intel.com> References: <20251001025442.427697-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 --- 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. v2: - use a macro rather than an inline function for seamldr_err() for consistency. --- arch/x86/include/asm/tdx.h | 5 +++++ arch/x86/virt/vmx/tdx/seamcall.h | 29 ++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h index e872a411a359..7ad026618a23 100644 --- a/arch/x86/include/asm/tdx.h +++ b/arch/x86/include/asm/tdx.h @@ -32,6 +32,11 @@ #define TDX_SUCCESS 0ULL #define TDX_RND_NO_ENTROPY 0x8000020300000000ULL =20 +/* P-SEAMLDR SEAMCALL leaf function error codes */ +#define SEAMLDR_RND_NO_ENTROPY 0x8000000000030001ULL + +#define SEAMLDR_SEAMCALL_MASK _BITUL(63) + #ifndef __ASSEMBLER__ =20 #include diff --git a/arch/x86/virt/vmx/tdx/seamcall.h b/arch/x86/virt/vmx/tdx/seamc= all.h index 71b6ffddfa40..3f462e58d68e 100644 --- a/arch/x86/virt/vmx/tdx/seamcall.h +++ b/arch/x86/virt/vmx/tdx/seamcall.h @@ -14,6 +14,19 @@ u64 __seamcall_saved_ret(u64 fn, struct tdx_module_args = *args); =20 typedef u64 (*sc_func_t)(u64 fn, struct tdx_module_args *args); =20 +static inline bool is_seamldr_call(u64 fn) +{ + return fn & SEAMLDR_SEAMCALL_MASK; +} + +static inline bool sc_need_retry(u64 fn, u64 error_code) +{ + if (is_seamldr_call(fn)) + return error_code =3D=3D SEAMLDR_RND_NO_ENTROPY; + else + return error_code =3D=3D TDX_RND_NO_ENTROPY; +} + static __always_inline u64 sc_retry(sc_func_t func, u64 fn, struct tdx_module_args *args) { @@ -22,7 +35,7 @@ static __always_inline u64 sc_retry(sc_func_t func, u64 f= n, =20 do { ret =3D func(fn, args); - } while (ret =3D=3D TDX_RND_NO_ENTROPY && --retry); + } while (sc_need_retry(fn, ret) && --retry); =20 return ret; } @@ -48,6 +61,17 @@ 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) +{ + /* + * Get the actual leaf number. No need to print the bit used to + * differentiate between P-SEAMLDR and TDX module as the "P-SEAMLDR" + * string in the error message already provides that information. + */ + fn &=3D ~SEAMLDR_SEAMCALL_MASK; + pr_err("P-SEAMLDR (%lld) failed: 0x%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) @@ -76,4 +100,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 Wed Oct 1 21:27:10 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 8B4D728151C for ; Wed, 1 Oct 2025 02:54:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287297; cv=none; b=TO2P/7pW1F3li0NSt6HDpYZHdFLxRzHgFilhMTZqbGebfvcn98lTvLfRSDFwao0knVAWYITGNVCpsaz78KskU4baD+nCix1W3WGWixIaB1AVl0N3J13l+7ojyi/6/VknM8dMGpj4BBMdpSLIiYip+kICoNO8THasmDqpOu+wWsM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287297; c=relaxed/simple; bh=J3W0K4fipOWHJ7SpK74rYo8nvs1cADQeyZLuvxDLcBo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=p6FM020opVqpcEI0S1aSPGF62CSx5+oUh2hiQbhIsevSRfm5/wJYC2QYYLGvxUg+zBZ/97kc3RUqpfAewohz71ONBs6izlguKe7FpbF+GFWfzlk+MuaU5pn4OFG1KcigL1DUpW8/IoavkH6zNQyvzi1vxfvpYIHV0UVwpFdf6ow= 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=KK+BjZzz; arc=none smtp.client-ip=192.198.163.15 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="KK+BjZzz" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1759287296; x=1790823296; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=J3W0K4fipOWHJ7SpK74rYo8nvs1cADQeyZLuvxDLcBo=; b=KK+BjZzzLO3FbmKAy58BKQfAta4e8mVQLqRRuSARyPCDfiUehWiajC97 MF2lS6vPql1iA9C30qb0PfCAZoRX0PyNoNIbjs7ckIywYpIRNJNd2KozJ Ho0vsXw4RBHNrZlYXjM3pSxjWORJQquTCi3TEY43m0vI8bRuKDgMW6+AK /6VKqg7uPv2cuURI+Daizi/FEGb5rLqDheg6V5zoGY1LGN3npXIQ5gn2D c9Bb5R5iZXDZhxeeKWE+rR68vTwx6KMpjcEZTZCNyhoiBp7zuKIwikPzl qltR3UPxMNb2Konl/KeEbx845msuPrY2rAg9CCeXUE6UqDY8JO7iS9pkC g==; X-CSE-ConnectionGUID: GfR+NUBORUKM4ic0YYp3jA== X-CSE-MsgGUID: 5UMSGDa2QH+sR1cZGw2toQ== X-IronPort-AV: E=McAfee;i="6800,10657,11569"; a="61662243" X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="61662243" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:54:55 -0700 X-CSE-ConnectionGUID: 8NWfn1+FRDavsOl9jWqbtg== X-CSE-MsgGUID: vEe6Z6ScQdmWCDK05XrNsQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="178629061" Received: from 984fee019967.jf.intel.com ([10.165.54.94]) by fmviesa006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:54:54 -0700 From: Chao Gao To: linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org, x86@kernel.org, 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 Cc: Chao Gao , Farrah Chen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" , "Kirill A. Shutemov" Subject: [PATCH v2 05/21] x86/virt/seamldr: Introduce a wrapper for P-SEAMLDR SEAMCALLs Date: Tue, 30 Sep 2025 19:52:49 -0700 Message-ID: <20251001025442.427697-6-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251001025442.427697-1-chao.gao@intel.com> References: <20251001025442.427697-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] --- 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/Kconfig | 10 ++++++ arch/x86/virt/vmx/tdx/Makefile | 1 + arch/x86/virt/vmx/tdx/seamldr.c | 56 +++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 arch/x86/virt/vmx/tdx/seamldr.c diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 58d890fe2100..6b47383d2958 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1905,6 +1905,16 @@ config INTEL_TDX_HOST =20 If unsure, say N. =20 +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 the same or any newer + version without the need to terminate running TDX guests. + + If unsure, say N. + config EFI bool "EFI runtime service support" depends on ACPI 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; +} --=20 2.47.3 From nobody Wed Oct 1 21:27:10 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 8BCDA27B34A for ; Wed, 1 Oct 2025 02:54:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287301; cv=none; b=KmN8NDTAf2nQqN/Mm4D1IIvQm78nxswYBxSdDWCLMVlveU/frjSR5X2YeG5eQnj+NDfpiRr72E++O/aLeCipw4aNnSSxmd03awA1AfHNbAXE5dlEWdcHVLzHgsWhsOHGeD6a5NJuaYQZHKgw7Qoy5W+VXYdu2Is5v7fpFLUYkPw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287301; c=relaxed/simple; bh=dXgFGVx1BY/YWNfSeJVbcKd5Xksg+AFq8R3EqWGkTD0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BNaknzCp5HOQgcpF4niLTRfFUik/NGcIXCbZL50Np9rDVIIWFM1Ulz7DscGx7r0ftdrIp4uFMCvRSsjpi2GZqjcrORBIYJQ1jaUKGdeuin60nIOdLO2bUYbfU+NwFoBC/YNf9VejwwqE+wkgY5b1cjAs57EOJ1vrauNTfi3nZpo= 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=jtP7jKX8; arc=none smtp.client-ip=192.198.163.15 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="jtP7jKX8" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1759287300; x=1790823300; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=dXgFGVx1BY/YWNfSeJVbcKd5Xksg+AFq8R3EqWGkTD0=; b=jtP7jKX8LkQTq7PonkUvgidj70AwGw3oO9bZAkX2wWSJRYoSLEqd3STy I0Nxp0Zt/eJuQNkZzFqLbMeKPSFOfE7FCMCnDNKzuPGHpPEde/+szzprd axs0Ei8C+PHnghTLgEkT2qFcu9CYernCk4/Pey/XxvndLsgU+ZPuNCJ17 Gjk+tbukJNaipJMRKPvRaff+pWRbaNZr0K6XO++nLovMQs2e+0Xsw2XhM ldEkakRkXETXgNPvP8WC7i4PYtXs4xI1yn49sPiaW8uIYLtRsnMSiKggt zznUKKX/kyPW+uiMbiZV66qpfeD5xgHK6WRY5QcPRZFxAygPdKbK5t2xx Q==; X-CSE-ConnectionGUID: 9zDfSxrwSy6B3/E1h86skg== X-CSE-MsgGUID: ciz1/y4nQtytNLP/2mRxbg== X-IronPort-AV: E=McAfee;i="6800,10657,11569"; a="61662262" X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="61662262" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:54:59 -0700 X-CSE-ConnectionGUID: 6Rjw4Kl1Q7GZHRM+tu8pQg== X-CSE-MsgGUID: Ac6IyXQfRaGjY2J+V9O8qA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="178629084" Received: from 984fee019967.jf.intel.com ([10.165.54.94]) by fmviesa006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:54:59 -0700 From: Chao Gao To: linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org, x86@kernel.org, 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 Cc: Chao Gao , Farrah Chen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" , "Kirill A. Shutemov" Subject: [PATCH v2 06/21] x86/virt/seamldr: Retrieve P-SEAMLDR information Date: Tue, 30 Sep 2025 19:52:50 -0700 Message-ID: <20251001025442.427697-7-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251001025442.427697-1-chao.gao@intel.com> References: <20251001025442.427697-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 --- 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..08c2e3fe6071 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_GPL_FOR_MODULES(seamldr_get_info, "tdx-host"); --=20 2.47.3 From nobody Wed Oct 1 21:27:10 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 3AB6E27B34A for ; Wed, 1 Oct 2025 02:55:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287305; cv=none; b=nzOrXKM2vk1eCZIrvYO+I48aIuiq5mlvKGLEr0auAYD3OgmJCm2xH4czLinRxuzA+gmg9mplGuvc6Jn7sbwoQyJcFSp0AGIHpNjorLCIkfBR75OCfCYJBf1n6gioSsBEcQFAv1Ca6vnOcRzAWdIhCAM7oPqvA9xrQpW3vLnuStA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287305; c=relaxed/simple; bh=Necu2utP6C1MSshjc1bV8CGQp56cbkE2uL9gSCv/kUQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Z9fqTNjL12hQSjwKmnUBIA8uWvyALaClSipKFF++qGHWHNaBxQBXcb4+g7bhCbfzDO+CmEGbhWQxy/qmWRMi24nhgMEMawDuaVtnl1vrbbQqE1aFEcrGsWgYpOxDupApbfRHOH5qmFEi+cjB8D1gPEhF0B8uGRY+gpBZ8LaccJ4= 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=oFnUcCkM; arc=none smtp.client-ip=192.198.163.15 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="oFnUcCkM" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1759287304; x=1790823304; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Necu2utP6C1MSshjc1bV8CGQp56cbkE2uL9gSCv/kUQ=; b=oFnUcCkMJ9eYIJvXAMObsCr4JlTR2xLsaC2SvuHFzobaQnJg3ksBfRRi WgEky7ER//GlOKFQUUjmCTo+EkiiBDIJwxa/x5zelXvOawogEyqUOqY4v NCIagFcx70cDMu+ZdIBzhroWla7waoa9csYlC4MIiFDcqQr3lYdsvDf8S GiLrBKJyAl2qpzuD8Rg+WhDaISVA1wbW4BmFZGceqoRq1uGQRv7bs9K4J rMfXyl5KyZZCRIsQclyDVmBCZkeNaepKyrF+J0Ni60sV/qhsaF9nd0t2c WsMp5IQTNCmrXP9TeeGqiVHVUjQciHLJFaN/NwjDdPXdhDBl7hgWBqo7Q A==; X-CSE-ConnectionGUID: AuKOtvolTDCVZgrjvxh08A== X-CSE-MsgGUID: DWdkEBqkR/eqvsMh7hPm1w== X-IronPort-AV: E=McAfee;i="6800,10657,11569"; a="61662279" X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="61662279" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:04 -0700 X-CSE-ConnectionGUID: Ta4MbWwoQYe26SZPo5U+IA== X-CSE-MsgGUID: pP/yvJQRQQ6xHe4fFOGFKw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="178629117" Received: from 984fee019967.jf.intel.com ([10.165.54.94]) by fmviesa006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:03 -0700 From: Chao Gao To: linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org, x86@kernel.org, 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 Cc: Chao Gao , Farrah Chen , "Kirill A. Shutemov" , Dave Hansen Subject: [PATCH v2 07/21] coco/tdx-host: Expose P-SEAMLDR information via sysfs Date: Tue, 30 Sep 2025 19:52:51 -0700 Message-ID: <20251001025442.427697-8-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251001025442.427697-1-chao.gao@intel.com> References: <20251001025442.427697-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. Note that P-SEAMLDR sysfs nodes are hidden when INTEL_TDX_MODULE_UPDATE isn't enabled or when P-SEAMLDR isn't loaded by BIOS, both of which cause seamldr_get_info() to return NULL. Signed-off-by: Chao Gao Tested-by: Farrah Chen --- .../ABI/testing/sysfs-devices-faux-tdx-host | 25 ++++++++ drivers/virt/coco/tdx-host/tdx-host.c | 63 ++++++++++++++++++- 2 files changed, 87 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 18d4a4a71b80..13c1f4f9909c 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, TD-Preserving 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 968a19f4e01a..42570c5b221b 100644 --- a/drivers/virt/coco/tdx-host/tdx-host.c +++ b/drivers/virt/coco/tdx-host/tdx-host.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include =20 @@ -43,7 +44,67 @@ 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, +}; + +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.%u\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 the 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 umode_t seamldr_group_is_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + return seamldr_get_info() ? attr->mode : 0; +} + +static struct attribute_group seamldr_group =3D { + .name =3D "seamldr", + .attrs =3D seamldr_attrs, + .is_visible =3D seamldr_group_is_visible, +}; + +static const struct attribute_group *tdx_host_groups[] =3D { + &tdx_host_group, + &seamldr_group, + NULL, +}; =20 static int __init tdx_host_init(void) { --=20 2.47.3 From nobody Wed Oct 1 21:27:10 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 6251727F183 for ; Wed, 1 Oct 2025 02:55:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287315; cv=none; b=STUg/FBIS5ik5/24Bccime2ryUlJ5xkHBRu9LnICMvr5BY7rVxettoOLYsUs32s5X+D79oR5Iga9w4tbdgpTB2GLmEzLmg4SoUQgB5KK29meDSMTeNcAkcAY5+8FHd17G9VV+JFC05so6FXyINib8sEyte65v9T1V06jdGba5hk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287315; c=relaxed/simple; bh=C8Zuhysgp3LMzCPVS3MjoTNecQgW/tlNF212z84aDsw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=K+wquqLZu8eHg3PXNOJ929ylob4DzAMGgjdxMLU9WNcNtzaSadrz/Fwt4vhH1HipSyZxxjRncxJrNIrsiWe5MNtQ8T7vPm4IYzp5ltgZYEvM7H5QXiE3R+HOkz2+7HMMA1kIAzhBJXnCZsct4EaedD+ibn49vDkf3LZC9sBb/0s= 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=d7rX2L9H; arc=none smtp.client-ip=192.198.163.15 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="d7rX2L9H" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1759287313; x=1790823313; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=C8Zuhysgp3LMzCPVS3MjoTNecQgW/tlNF212z84aDsw=; b=d7rX2L9HRbBlWhYxsm37sZOf3AUnTuKQUIi2UN0MIxwjbP9ucCnV35mm K14FvVM8emeW0seghhonzT9xXnM4SNoFU/Dtc79Le3mpmY4LBkARvI5Yn 87JquGF0aD5VH7cGxcqrHCBM+OME/kD6cWlJCiRnms0Uv+y6aSCb4SKzS IEKVHOyoLeieCtF/PtVV5SETfReVf83lwRKWApVyDq5dmSi9JrEDkRWO4 4TtsD+LESZ6e0TQUxKYdunYLhOTOs8ooDtRuOS1zXSgs4JT4d4T2MJIPy OEuXFmwrSbITulO7x4Byy5ToJIRFkXX+iqwrX8V25PtJfa1Tn+trAEomp g==; X-CSE-ConnectionGUID: zqCF9BuDQDGWeyEc7BHSnQ== X-CSE-MsgGUID: pZzpNP85RuKgdhejtiujvQ== X-IronPort-AV: E=McAfee;i="6800,10657,11569"; a="61662289" X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="61662289" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:12 -0700 X-CSE-ConnectionGUID: 8MrapPLxTNW0+DzpxEVUzg== X-CSE-MsgGUID: TE3tkZLZTXORWVTZ8nHGXw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="178629159" Received: from 984fee019967.jf.intel.com ([10.165.54.94]) by fmviesa006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:11 -0700 From: Chao Gao To: linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org, x86@kernel.org, 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 Cc: Chao Gao , Farrah Chen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" , "Kirill A. Shutemov" Subject: [PATCH v2 08/21] coco/tdx-host: Implement FW_UPLOAD sysfs ABI for TDX Module updates Date: Tue, 30 Sep 2025 19:52:52 -0700 Message-ID: <20251001025442.427697-9-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251001025442.427697-1-chao.gao@intel.com> References: <20251001025442.427697-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 --- arch/x86/Kconfig | 2 + arch/x86/include/asm/seamldr.h | 2 + arch/x86/include/asm/tdx.h | 5 ++ arch/x86/virt/vmx/tdx/seamldr.c | 7 ++ drivers/virt/coco/tdx-host/tdx-host.c | 122 +++++++++++++++++++++++++- 5 files changed, 137 insertions(+), 1 deletion(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 6b47383d2958..2bf4bb3dfe71 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1908,6 +1908,8 @@ config INTEL_TDX_HOST 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 the same or any newer 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 7ad026618a23..2422904079a3 100644 --- a/arch/x86/include/asm/tdx.h +++ b/arch/x86/include/asm/tdx.h @@ -107,6 +107,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 08c2e3fe6071..69c059194c61 100644 --- a/arch/x86/virt/vmx/tdx/seamldr.c +++ b/arch/x86/virt/vmx/tdx/seamldr.c @@ -69,3 +69,10 @@ const struct seamldr_info *seamldr_get_info(void) return seamldr_call(P_SEAMLDR_INFO, &args) ? NULL : &seamldr_info; } EXPORT_SYMBOL_GPL_FOR_MODULES(seamldr_get_info, "tdx-host"); + +int seamldr_install_module(const u8 *data, u32 size) +{ + /* TODO: Update TDX Module here */ + return 0; +} +EXPORT_SYMBOL_GPL_FOR_MODULES(seamldr_install_module, "tdx-host"); diff --git a/drivers/virt/coco/tdx-host/tdx-host.c b/drivers/virt/coco/tdx-= host/tdx-host.c index 42570c5b221b..418e90797689 100644 --- a/drivers/virt/coco/tdx-host/tdx-host.c +++ b/drivers/virt/coco/tdx-host/tdx-host.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -21,6 +22,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 struct faux_device *fdev; =20 static ssize_t version_show(struct device *dev, struct device_attribute *a= ttr, @@ -106,6 +114,118 @@ 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; + + if (status->cancel_request) { + status->cancel_request =3D false; + return FW_UPLOAD_ERR_CANCELED; + } + + 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; + + 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); + if (seamldr_install_module(data, size)) + return FW_UPLOAD_ERR_FW_INVALID; + + *written =3D size; + return FW_UPLOAD_ERR_NONE; +} + +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 int seamldr_init(struct device *dev) +{ + const struct seamldr_info *seamldr_info =3D seamldr_get_info(); + const struct tdx_sys_info *tdx_sysinfo =3D tdx_get_sysinfo(); + int ret; + + if (!tdx_sysinfo || !seamldr_info) + return -ENXIO; + + if (!tdx_supports_runtime_update(tdx_sysinfo)) { + pr_info("Current TDX Module cannot be updated. Consider BIOS updates\n"); + return -EOPNOTSUPP; + } + + if (!seamldr_info->num_remaining_updates) { + pr_info("P-SEAMLDR doesn't support TDX Module updates\n"); + return -EOPNOTSUPP; + } + + 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); + + return ret; +} + +static void seamldr_deinit(void) +{ + if (tdx_fwl) + firmware_upload_unregister(tdx_fwl); +} + +static int tdx_host_probe(struct faux_device *fdev) +{ + /* Only support TDX Module updates now. More TDX features could be added = here. */ + return seamldr_init(&fdev->dev); +} + +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 int __init tdx_host_init(void) { int r; @@ -118,7 +238,7 @@ static int __init tdx_host_init(void) if (r) return r; =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 Wed Oct 1 21:27:10 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 D495327B33A for ; Wed, 1 Oct 2025 02:55:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287316; cv=none; b=WItGSucDU+LmtZ9YtQkya6X33whWy3cnSJFvKyjtf0MZ4ZKbwV60d63brb6BH67wXY6i5DC/xgrPUp1hGIWowibP7yC5m7LnMXmLx9BYMxILvGhwwwXRu8gfNY/rxAHu2JFXlKejJo7NYzJnIinLTVWpn4AsT7bfFm8W9lwqi8A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287316; c=relaxed/simple; bh=fpi5/RPbm05HDWO4cAa6H+2kjOpG/E/N/ORvroo4F8Q=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MbhcTpzeLpGcrw02Op0oPzSM1ss4zA0wLRW5pium34JgjzUixLb5R3rEMm+ZugZDsVKFYGPkuPm4K6nsoHK10m2anoSE/bYhnZA6vhrJ2NkmRxHvuxOKvogEFtCSbkDM+HTMFZiBywZ+o2FQNk+IRAiAw22+qJaSwc6WySJeZUs= 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=kezXtYn/; arc=none smtp.client-ip=192.198.163.15 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="kezXtYn/" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1759287315; x=1790823315; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=fpi5/RPbm05HDWO4cAa6H+2kjOpG/E/N/ORvroo4F8Q=; b=kezXtYn/i7ZLV9/fVwyVETPT3Eb+OZ7N5cpb5MlL+QfDpdWZec/E1B/9 Lo3hCJVxDKs5PrRv5txyhmb1SU4T1S26vN/p4jW3IHguBe3SY9tTiq9pu cUNqfidPZpxcMn+mzn6ERTvcgt08+kcJ0/xIbqhPqH8t4GEJBwXEtlGzF cppfYNwUGvrLi0LKoIUJ/MmGrWe371qZArnTMdysG5Cf9tno2+iCC13Ez 4ChtctNHSLPiYW5fJTLnHJmx8VRbyDeGRZBj2Tc8Pv4LTzuVkAIm3bBNS VL7JXCHsIcdF3fdXDo0fwY5CNGbrbkyKXiVcSf8moxbFPmY1RGM8LXq6G w==; X-CSE-ConnectionGUID: eVg7R3zsS5WD3ntDeejiLw== X-CSE-MsgGUID: MJwYehWVQpu17mKrZt9K6w== X-IronPort-AV: E=McAfee;i="6800,10657,11569"; a="61662300" X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="61662300" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:12 -0700 X-CSE-ConnectionGUID: lb3XwFedSMG2rJH2iztJLg== X-CSE-MsgGUID: iYEM/Dp8RSOFpX5bUNUltw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="178629166" Received: from 984fee019967.jf.intel.com ([10.165.54.94]) by fmviesa006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:11 -0700 From: Chao Gao To: linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org, x86@kernel.org, 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 Cc: Chao Gao , "Kirill A. Shutemov" , Dave Hansen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v2 09/21] x86/virt/seamldr: Block TDX Module updates if any CPU is offline Date: Tue, 30 Sep 2025 19:52:53 -0700 Message-ID: <20251001025442.427697-10-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251001025442.427697-1-chao.gao@intel.com> References: <20251001025442.427697-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 --- 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 69c059194c61..b9e025d0f0bc 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 =20 @@ -72,6 +74,12 @@ EXPORT_SYMBOL_GPL_FOR_MODULES(seamldr_get_info, "tdx-hos= t"); =20 int seamldr_install_module(const u8 *data, u32 size) { + 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 Wed Oct 1 21:27:10 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 86A7027F195 for ; Wed, 1 Oct 2025 02:55:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287317; cv=none; b=LzgqZZo9hPXREWRwb0zlPcCU0XK7tBq1eMTK6VQ3D29ewferk4+5dfQZUUWHMrJ6CDvv6Xe5CDQHbcYSILYZjzRJ4JZYbnwbD7yLLqh33O5a7Firk/4GHlAOTMJg14cjtPlfnURagLQIwEAeIcUspHRPe0zZ0P+89R2eqepqMz4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287317; c=relaxed/simple; bh=dvXGa0GxyCQ64Z7snw7KIY71r0fttLiv1/DWhLRD4/Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SV0RM88R9EBWVc+8KvFZqJnKIi2EeyLhJaePh5SjaG1XeB1FAo/1lUBnBTi3u/btNPMf9Qt5EQ4RwbPZdBuOMJ3J8D9DzaI7M8bd97howdx+iFHt8TgdTKHBNR48vyfS3L/A18jPI4i7MZU3TU2AoUpoPU63oimA4O3SSKJ320w= 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=YaUDxVCN; arc=none smtp.client-ip=192.198.163.15 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="YaUDxVCN" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1759287316; x=1790823316; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=dvXGa0GxyCQ64Z7snw7KIY71r0fttLiv1/DWhLRD4/Y=; b=YaUDxVCNJ8ptxeCBHK8+C7yrXqqYP2wRRdF318W3DB6g9C5sKmeAPqb3 n6Q5izCOIaMTejlMTDHW817LFYFprfQK9LQCmqzBeUuMWMI5M3EASmYZL 8FoaOiSUzfCgJHnr8ocTYrTbyxsZMYjPU5NTDnsgTqUeHcpBBlTxlcySA Aw23BERgJXTl2HgaTglHLpC9Rl2KdGYh1E/gRisfLWJZEb2MbnOGqS9UZ RpoxJSAbgJfEVzpsRsCq904pDnlGH8BTugz6oAPjn4SpYuvWiDWSp+Z8g sHHuJ6xfse6XY51GGiPYU7muLYkG/lho3xfiaQW0yqiEMjT5TA3eNpvLq A==; X-CSE-ConnectionGUID: U56W7V4uTBuLuveUhGvpLg== X-CSE-MsgGUID: 7q+sz18bQC6cFeYNUtDcGw== X-IronPort-AV: E=McAfee;i="6800,10657,11569"; a="61662310" X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="61662310" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:13 -0700 X-CSE-ConnectionGUID: zx65eUQOTQaOzn2/y21vng== X-CSE-MsgGUID: 605RYKm0QHeXoOT+Ag+9Sw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="178629171" Received: from 984fee019967.jf.intel.com ([10.165.54.94]) by fmviesa006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:12 -0700 From: Chao Gao To: linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org, x86@kernel.org, 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 Cc: Chao Gao , Farrah Chen , "Kirill A. Shutemov" , Dave Hansen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v2 10/21] x86/virt/seamldr: Verify availability of slots for TDX Module updates Date: Tue, 30 Sep 2025 19:52:54 -0700 Message-ID: <20251001025442.427697-11-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251001025442.427697-1-chao.gao@intel.com> References: <20251001025442.427697-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 --- 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 b9e025d0f0bc..9f7d96ca8b2f 100644 --- a/arch/x86/virt/vmx/tdx/seamldr.c +++ b/arch/x86/virt/vmx/tdx/seamldr.c @@ -74,6 +74,14 @@ EXPORT_SYMBOL_GPL_FOR_MODULES(seamldr_get_info, "tdx-hos= t"); =20 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; + 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 Wed Oct 1 21:27:10 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 269AF27FD4A for ; Wed, 1 Oct 2025 02:55:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287318; cv=none; b=X4SLiFDjl26IREyVknucpMA9VFCNtm+5BRQJjIK5/MfTl2HoAAo9Tjt8o5BoL2mZYCl43uXMVqlR9xnvps+Nr355hirXzkKzQgpgdO3EsYlnCncB+eMxYAoY7XKs7NaASAsuenEbzpnxXEmv+mM0W5ymgRcwYGZtyc3cEE2SdoY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287318; c=relaxed/simple; bh=Wv4BZruE2qoHDdg6egrEy/ofDkxl7FCgehZSO1fr7kU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jg6/X8os8orHUFURZ7gcqMV0ThHaYIUFiWNcrEqXzGO7keFay9irUD2bYXmf3zwY9q/UZ+kPMHh3ugGU9z0gMbzabCoTAIIS2t/10N2Eb+olWcmudx+QVpZjbjcnMqCCDYi4NkvlBCfKqTPZZjHEAEt2/D+SkJSK1I1l3QW99Y4= 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=FRa6LbNg; arc=none smtp.client-ip=192.198.163.15 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="FRa6LbNg" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1759287316; x=1790823316; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Wv4BZruE2qoHDdg6egrEy/ofDkxl7FCgehZSO1fr7kU=; b=FRa6LbNgXVNMFFErfImC6SK28JuDzYxRlYiJGGC6rKDl7+ZYt4w3zswD fJqREtFbNzFVAAxa2D3TReJOqAtEC0mRwFUM9OixOqBqrC0Lv8de4yNcZ bLLf3KKO08xyP8RkTMjwVEjb1p1sNILD1W0pEmujXXemVCTlrWXAZsQ4m 0ja1cd3ZGd8RkpThmpdvXTv53Le/6bxTtioABnOYI0VWO35uHw3bbOl5S x96ZWKWOfbbfC/MMiLQieQ8S52LsZNvrZuRp3eo87NOqKTXXgfYv2KNDO bvIhuiuSZOwDPpdAadnaNu1fQITJSC/Zcn9W2dcBsLWJl6dk9h2eLKfDI Q==; X-CSE-ConnectionGUID: ItVOkJpvS5SxQ/kqgLBbuw== X-CSE-MsgGUID: c8eHAvIpTDWPQIsQ7pLizg== X-IronPort-AV: E=McAfee;i="6800,10657,11569"; a="61662321" X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="61662321" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:14 -0700 X-CSE-ConnectionGUID: 5sNZTQEMT+envwnJwKOD2A== X-CSE-MsgGUID: bxDLgl2IS7eZOmw2/e28Ww== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="178629174" Received: from 984fee019967.jf.intel.com ([10.165.54.94]) by fmviesa006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:13 -0700 From: Chao Gao To: linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org, x86@kernel.org, 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 Cc: Chao Gao , Farrah Chen , "Kirill A. Shutemov" , Dave Hansen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v2 11/21] x86/virt/seamldr: Allocate and populate a module update request Date: Tue, 30 Sep 2025 19:52:55 -0700 Message-ID: <20251001025442.427697-12-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251001025442.427697-1-chao.gao@intel.com> References: <20251001025442.427697-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] --- v2: - Add a high level description of the bitstream in changelog - Document where the bitstream format is defined in comments - Add checks for the version and reserved fields in tdx_blob --- arch/x86/virt/vmx/tdx/seamldr.c | 155 ++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) diff --git a/arch/x86/virt/vmx/tdx/seamldr.c b/arch/x86/virt/vmx/tdx/seamld= r.c index 9f7d96ca8b2f..00a01acc15fd 100644 --- a/arch/x86/virt/vmx/tdx/seamldr.c +++ b/arch/x86/virt/vmx/tdx/seamldr.c @@ -6,9 +6,12 @@ */ #define pr_fmt(fmt) "seamldr: " fmt =20 +#include #include #include #include +#include +#include #include =20 #include @@ -18,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) @@ -72,6 +95,133 @@ const struct seamldr_info *seamldr_get_info(void) } EXPORT_SYMBOL_GPL_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 */ +static struct seamldr_params *alloc_seamldr_params(const void *module, int= module_size, + const void *sig, 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) || !IS_ALIGNED(sig_size, SZ_4K) || + !IS_ALIGNED((unsigned long)module, SZ_4K) || + !IS_ALIGNED((unsigned long)sig, SZ_4K)) + return ERR_PTR(-EINVAL); + + /* seamldr_params accepts one 4KB-page for sigstruct */ + if (sig_size !=3D 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; + 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: %u\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)) + int seamldr_install_module(const u8 *data, u32 size) { const struct seamldr_info *info =3D seamldr_get_info(); @@ -82,6 +232,11 @@ int seamldr_install_module(const u8 *data, u32 size) if (!info->num_remaining_updates) return -ENOSPC; =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 Wed Oct 1 21:27:10 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 902B7287519 for ; Wed, 1 Oct 2025 02:55:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287318; cv=none; b=Qnm2TSf45vqmB9dxrN/FHqstrtW0RRiMtmWNCdRXlmfnfotlxXn+bx3keSMczhM/pqj/w5AcwWKlAtaer2Q8BoBT34TfQ+ba1p2C+v22Rdp7wcgXAjqul9OFPgnRdHJju3/Gn9JJc7F1OCYKXPxi5R2yf+jEv5n0nAXz/hMdh5Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287318; c=relaxed/simple; bh=ZqSLoqdV7WFix8gZ0ngNRZRoX6vNJSZh42f+sjIXDNw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=DGAEHhOn1Muspw6TbO211fE9MX7ZVZMgoYuVHbF66Y0Dl9I5W7hWFchWSlE8aq+qdJ1Mm5AN3czVZtQ8GhMGODZH/9TBFmrIlzZq09iI3l3btSTfRAvEAu3iPks5O9CHV7C5s76cHZMc+uxD8qzzDkLS6sgxJi8Xts4i9U4/TVM= 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=c+Obq61N; arc=none smtp.client-ip=192.198.163.15 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="c+Obq61N" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1759287317; x=1790823317; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ZqSLoqdV7WFix8gZ0ngNRZRoX6vNJSZh42f+sjIXDNw=; b=c+Obq61Na/hzPTgALL8L7Q5LExehMZ17VBhHIWstS2tGs8Thv8vrOeLd zZ3tMO+PlCzH3K3WlLQnlSAkoTju0Au7o4NqSXTDYVB5ZPSNC6sFHTbp6 uwbQBnQbRSZ/I87yYcqbZllCkq2NwNM2WoDvZKLqMmU1ruu9oGxDwWQ15 fiUE6BadhUvVZ2JQd6+qBYj1NWG+fO4y6CUYmDGLFeLMz3HHckcOht8Lg x2DqcMxOdHPL1JxU26HVcQI5XkwMsGIDJQfF/q0cMM72qngW29cfzQyH5 VWCEYV+MeFWsvxBr/ME9gJo/fRr+a63j2YCfk/OIWwORmWKJHXHjQ0IJS w==; X-CSE-ConnectionGUID: gCdf14WoTn6iZxioAP+QJw== X-CSE-MsgGUID: bAZdXM9pSea621Kye9MiTA== X-IronPort-AV: E=McAfee;i="6800,10657,11569"; a="61662330" X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="61662330" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:15 -0700 X-CSE-ConnectionGUID: Ddn54KrnSjavx3zX85ew4w== X-CSE-MsgGUID: FmNWqG4UTr+snYAACtoH9w== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="178629181" Received: from 984fee019967.jf.intel.com ([10.165.54.94]) by fmviesa006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:14 -0700 From: Chao Gao To: linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org, x86@kernel.org, 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 Cc: Chao Gao , Farrah Chen , "Kirill A. Shutemov" , Dave Hansen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v2 12/21] x86/virt/seamldr: Introduce skeleton for TDX Module updates Date: Tue, 30 Sep 2025 19:52:56 -0700 Message-ID: <20251001025442.427697-13-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251001025442.427697-1-chao.gao@intel.com> References: <20251001025442.427697-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 --- 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 00a01acc15fd..b074630d42e3 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 @@ -219,12 +221,75 @@ static struct seamldr_params *init_seamldr_params(con= st 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 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; @@ -243,7 +308,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_GPL_FOR_MODULES(seamldr_install_module, "tdx-host"); --=20 2.47.3 From nobody Wed Oct 1 21:27:10 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 2DAFE280329 for ; Wed, 1 Oct 2025 02:55:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287318; cv=none; b=Tis7fTYeKFP155X4lHFjYuKX4+jbZuU6wEFm5fo3KvM3eM5oSrSp/+uWgbe2f4R/Pb2yZ0ydEXDq/eD79y1awLuqTgd8TFg4e96nC+aOj4Nzg/aoMQuaHY3nB2BCv+sIW6xGELc2JI4Yef1V2grClwTiTv7/C1KT1ZJKeOcrsMg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287318; c=relaxed/simple; bh=KUKjUzwVQn2FgmlvQBDS9HFLYMgv+qW5UWoLhq+xTz0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=D9kzuz/KXJFTEt29dtix4cqLHnqgX+nTtB0AuiSglIQrHH0IWt7467cxu43uS37jjfG+mboyhNqRB6Kxu+mmLARUPDYMD3lMjj0R/dTs2Nl39D1aRdZrF/0YcGgogKCqGHSL6jTNvtJiu/r81OzIZ2VYADXBRVUcxpv1kI0jgQ0= 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=Kspfsi7h; arc=none smtp.client-ip=192.198.163.15 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="Kspfsi7h" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1759287317; x=1790823317; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=KUKjUzwVQn2FgmlvQBDS9HFLYMgv+qW5UWoLhq+xTz0=; b=Kspfsi7hA1UNXTNmCofavVOmZ5FN2ZEYZJ7s08Vju588QKMmiUBQgktF X9+ZJ7hANc4soul6K0NRFcDstaTO+xJEv2xe46mchqP/cH3zor/8s0FsY PksX7S9Gt8xynrMCq8+bENq0Iqz7Lq0gsN1s4epCcMmFgQJrZrOObrFr3 +8rkQT8siN1ZcTtF88lMwtlu9jMFK/6Jk8J4r1wNz2sFj7b0jTZ9SGOub jWRF81OK1/85VoGH0xV4MNr0XzZ3Z0xIXSFeFBEQsDkZLGBauAQ/UrbN1 /7PrBgJcr7WT5+z/dkkjfNf9mL9dmORVgFRsXIokAK7q5fGMz2+eFD1QL w==; X-CSE-ConnectionGUID: UTv9pXVSTgeAtwPO608wag== X-CSE-MsgGUID: 0dgqsmLvRhatzl4XYlNEYQ== X-IronPort-AV: E=McAfee;i="6800,10657,11569"; a="61662339" X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="61662339" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:16 -0700 X-CSE-ConnectionGUID: Ry9PZvyUToG1F1n0ZVqUpQ== X-CSE-MsgGUID: 8ue/SW9gT/+WMvlpFYZweQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="178629190" Received: from 984fee019967.jf.intel.com ([10.165.54.94]) by fmviesa006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:15 -0700 From: Chao Gao To: linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org, x86@kernel.org, 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 Cc: Chao Gao , Farrah Chen , "Kirill A. Shutemov" , Dave Hansen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v2 13/21] x86/virt/seamldr: Abort updates if errors occurred midway Date: Tue, 30 Sep 2025 19:52:57 -0700 Message-ID: <20251001025442.427697-14-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251001025442.427697-1-chao.gao@intel.com> References: <20251001025442.427697-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. Add support of transitioning directly to the final stage on errors, effectively aborting the update and skipping all remaining stages. Signed-off-by: Chao Gao Tested-by: Farrah Chen --- arch/x86/virt/vmx/tdx/seamldr.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/arch/x86/virt/vmx/tdx/seamldr.c b/arch/x86/virt/vmx/tdx/seamld= r.c index b074630d42e3..fca558b90f72 100644 --- a/arch/x86/virt/vmx/tdx/seamldr.c +++ b/arch/x86/virt/vmx/tdx/seamldr.c @@ -235,6 +235,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) @@ -249,8 +250,16 @@ static void set_target_state(enum tdp_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); + if (atomic_dec_and_test(&tdp_data.thread_ack)) { + /* + * If an error occurred, abort the update by skipping to + * the final state + */ + if (atomic_read(&tdp_data.failed)) + set_target_state(TDP_DONE); + else + set_target_state(tdp_data.state + 1); + } } =20 /* @@ -273,6 +282,9 @@ static int do_seamldr_install_module(void *params) default: break; } + + if (ret) + atomic_inc(&tdp_data.failed); ack_state(); } else { touch_nmi_watchdog(); @@ -308,6 +320,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 Wed Oct 1 21:27:10 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 05BC82C08CD for ; Wed, 1 Oct 2025 02:55:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287322; cv=none; b=sZ1BJ3eu9uJrvvTl63wOtcKxWFCdIZMAimJAEY4hxK9t/EnBgnyugObqarhz9/RFo74e9wh8sVBuh2doy3XYbGanWKTqcZi+sddUmKNRsunm8XO+XObf2sSslZ9bigH85Jmw9l9iDm+8Nmxhpcl2HYqj/+4yalxgIfrH9RDdcmU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287322; c=relaxed/simple; bh=gOZl08xistsEVX4pEJ3Cv/6TjlFIW9xUdtZd1G6N6uA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=sQ30O+qbv0SnRjoiOTD2VP1nqbJQxyVivE6c/T8rAESs5/XG2ykodqt2ISvrmpLJbSLflrDVKuiciem49J7wz20hXnAj+wpnYq/prdrW+hY9WkVUzIc1KoCErUfGEHeU92zN7csZf6ii2x+tbZzwTk4zqzGnMMuuADXNaB9nQyQ= 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=kLjiBl3/; arc=none smtp.client-ip=192.198.163.15 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="kLjiBl3/" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1759287320; x=1790823320; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=gOZl08xistsEVX4pEJ3Cv/6TjlFIW9xUdtZd1G6N6uA=; b=kLjiBl3/7wpChsKxWJ0m7JGmS8wQmElRQ0T5XM0XGFEOJWj0fRc3ccVb xrsc45byesYkkRBAVasOJize7OYaE/+vdsFpIhvmDTwuy5ES03fAa2iNa Z/fzqRRJXGlc1ZOzHvhZmHpO6e7aB4KoizLBPA+mFzQRW2n6hQHXf4lOz kifyOy8yMyle2NMrj6Tq9sDQeSzj1Rxiv7ZwTmqvFZM1Xubr3iuEOObsh JKdix+EpI35zHlcaVZu4qPCGaZOxeWmaJWKGdSKmw7FC/ZjroxxSnXHaU ZwQrSLeIu/2w7NGFvRkLLSsBzOsj90dcf073kTe7bVJQHzzZnRZqFxtlX A==; X-CSE-ConnectionGUID: TlN1x0oGTwKMQk+Cs18fxQ== X-CSE-MsgGUID: UwsRKhWBR9yJanGwOFa9+w== X-IronPort-AV: E=McAfee;i="6800,10657,11569"; a="61662352" X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="61662352" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:20 -0700 X-CSE-ConnectionGUID: K7RwYJE2S4O6chRpPbbfsQ== X-CSE-MsgGUID: WIvb16QIT0+7mVEuedXloQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="178629217" Received: from 984fee019967.jf.intel.com ([10.165.54.94]) by fmviesa006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:19 -0700 From: Chao Gao To: linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org, x86@kernel.org, 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 Cc: Chao Gao , Farrah Chen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" , "Kirill A. Shutemov" , Paolo Bonzini , Rick Edgecombe Subject: [PATCH v2 14/21] x86/virt/seamldr: Shut down the current TDX module Date: Tue, 30 Sep 2025 19:52:58 -0700 Message-ID: <20251001025442.427697-15-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251001025442.427697-1-chao.gao@intel.com> References: <20251001025442.427697-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. Generate changes to tdx_global_metadata.{hc} by following the instructions detailed in [1], after adding the following section to the tdx.py script: "handoff": [ "MODULE_HV", ], Manually add a check in get_tdx_sys_info_handoff() to guard reading the "module_hv" field with TDX Module update support as otherwise the field doesn't exist. Signed-off-by: Chao Gao Tested-by: Farrah Chen Link: https://lore.kernel.org/kvm/20250226181453.2311849-12-pbonzini@redhat= .com/ # [1] --- 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 fca558b90f72..b9daf11e1064 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 @@ -229,6 +230,7 @@ static struct seamldr_params *init_seamldr_params(const= u8 *data, u32 size) */ enum tdp_state { TDP_START, + TDP_SHUTDOWN, TDP_DONE, }; =20 @@ -269,8 +271,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(); @@ -279,6 +285,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 b367bb1d94ed..89b51e270274 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -1191,6 +1191,22 @@ int tdx_enable(void) } EXPORT_SYMBOL_GPL(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 0454124803f3..3fdd5cbc21d8 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; @@ -109,6 +121,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 Wed Oct 1 21:27:10 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 EBC0F2C21ED for ; Wed, 1 Oct 2025 02:55:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287322; cv=none; b=Dqtr4qRzBv69jZg9732tHJUVuY+I+Iic4alkVNVGm3vnAV85gX3KBPnTcvc4omuj2IhkOz3GLfNvfLPUGsyKD96Bp/A8mylxgaySSUY9kkGZ53MvjedbygPjo1HNnwjP84mGkOFOTbAmxZE0xjd/J0VFIOQjxO8oKWkojwkV7GA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287322; c=relaxed/simple; bh=nzCXNZTa8N2Vjrk3FfPnD8JhlWNEhb7UIR48hd5iWug=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cN33RjCio8Eh7ARC+j1iNfhD0ziMW/3XEgeYvp7ccQiD17LgrNJ0dcbx6ymNBCYKGMUd7vbKUgqcd0bvISbIVTISZvlHslv9/auQ77PyOKqPWNSkFk2nFm9TO5p4xy5HAS9/jgHGVTYIMUx8ufQY4CoG4Ud1xpDjSouRuMujyco= 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=NSH4GSrt; arc=none smtp.client-ip=192.198.163.15 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="NSH4GSrt" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1759287321; x=1790823321; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=nzCXNZTa8N2Vjrk3FfPnD8JhlWNEhb7UIR48hd5iWug=; b=NSH4GSrtaVjyUIt5PZLIQQ7dIsfvimkCss70tckyTKZj+CXNXQggBLxg T76vG1czzVZwxCyVhc27gdojPekdmN0xdujorzxxhr2+Qj1rMS3IS1lS+ 0Pwi/h4i5zVtiy2EOYVczvT+yYsehhMOSfyps17k/WhlQ2y4NklYvNCju cVkwUGp39mwYD6ukGUnDNlTdg2Ff+kgtfK3Hu2CTsmOypzT6fLXkz/Ryw 7sWx7FR72IF0oSb8iHZ6L//D8ud1IR7Gtces7DmAVHldV9OH/EKf0xoIy L7El0SL/aGtG9IdpIcHJ8+ZhziXcy4TBaF/NTv/Pjwr8PhTzASIsGve96 Q==; X-CSE-ConnectionGUID: Xh7l8UxfQGyTN4i5db/iIQ== X-CSE-MsgGUID: alPb0VP6TAijpHDKzwYK+g== X-IronPort-AV: E=McAfee;i="6800,10657,11569"; a="61662363" X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="61662363" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:20 -0700 X-CSE-ConnectionGUID: ntN6U0OpQWOrEXctx4qbJQ== X-CSE-MsgGUID: tn38oSEGRuKC83Qy84j/uw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="178629223" Received: from 984fee019967.jf.intel.com ([10.165.54.94]) by fmviesa006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:20 -0700 From: Chao Gao To: linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org, x86@kernel.org, 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 Cc: Chao Gao , Farrah Chen , "Kirill A. Shutemov" , Dave Hansen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v2 15/21] x86/virt/tdx: Reset software states after TDX module shutdown Date: Tue, 30 Sep 2025 19:52:59 -0700 Message-ID: <20251001025442.427697-16-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251001025442.427697-1-chao.gao@intel.com> References: <20251001025442.427697-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 --- arch/x86/virt/vmx/tdx/tdx.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 89b51e270274..7019a149ec4b 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -54,6 +54,9 @@ static struct tdmr_info_list tdx_tdmr_list; static enum tdx_module_status_t tdx_module_status; static DEFINE_MUTEX(tdx_module_lock); =20 +static bool sysinit_done; +static int sysinit_ret; + /* All TDX-usable memory regions. Protected by mem_hotplug_lock. */ static LIST_HEAD(tdx_memlist); =20 @@ -68,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 @@ -1194,6 +1195,7 @@ EXPORT_SYMBOL_GPL(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 @@ -1204,7 +1206,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 Wed Oct 1 21:27:10 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 BA7FC2D24BA for ; Wed, 1 Oct 2025 02:55:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287327; cv=none; b=jrCSWrt0fRQd0xOP22O5iWjIp3swkWBpLNkZMztznbkOl/D4upnFgtlEOKVtx32SsWtDs1aPgWLj9fNeMLVUsTqxqUlMvupNe8vKvSdFbcaLc92vpfodBuyN2I04k52D9cnp10El7aoi/nTYz24d0GJsBH5Fal1l4C/ZgimqZ4Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287327; c=relaxed/simple; bh=+8oiFznQZ9fwld9yKP5Xmw2AlOstCofjF71+bnTOYg8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JtQBK7ShxfQly2Hv2BCvQLiQRlaSCDJDLB3+iwmYJ5yjx3if520uvgoANvM2EUyXplX0XXgZeOJ0YqrCbdARmd93DgIrIfnUJAc+TiRdbQV1hKwwUch2tb3tjvQRfgkXQRt6VwPsGHcz3QHCrUsm1Gb0Vr+oiG7sA2PLRcBnuzw= 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=h3qwmEBm; arc=none smtp.client-ip=192.198.163.15 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="h3qwmEBm" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1759287326; x=1790823326; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=+8oiFznQZ9fwld9yKP5Xmw2AlOstCofjF71+bnTOYg8=; b=h3qwmEBmtvPWiykW+E1PEx9TGHPg4zE0mIN2Bd5mREA/TuTuOr46dCah BdiaPGfQutbYVb2z7ytdfXYw3VSREjH/j0q0CqgDJqzPb6L7y32LcVfYx NH6u2Lp3bN1pgD3+t7+4+Z3n0qjnvLSNuw0o5pdpWoZ35C0d2PXCI0Ii3 NNJ+M0lnujHg/Bvz/fuMhqX+FAwLWWoD9vs4UB2H2Fa9k1JPcqc/t+mTz NzYW9228AKTybeGBbPHdniBw7B3mNvZClNmg/8qjgdImQ7uiL0Fl715UL cwFZDghEHfjuW7AL/nBLybUCFiccUbD/BhWKGs0+bm4J6iHlBmnNODcV4 A==; X-CSE-ConnectionGUID: 48fg3jkXS2ONPDQksslECg== X-CSE-MsgGUID: nOqiaj34SuOawBfOP8s+xQ== X-IronPort-AV: E=McAfee;i="6800,10657,11569"; a="61662376" X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="61662376" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:25 -0700 X-CSE-ConnectionGUID: 7MSVOtR2QSKp08gI6MXf8A== X-CSE-MsgGUID: ylnDmHplRPmZAF5dEpGKAQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="178629245" Received: from 984fee019967.jf.intel.com ([10.165.54.94]) by fmviesa006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:24 -0700 From: Chao Gao To: linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org, x86@kernel.org, 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 Cc: Chao Gao , Farrah Chen , "Kirill A. Shutemov" , Dave Hansen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v2 16/21] x86/virt/seamldr: Handle TDX Module update failures Date: Tue, 30 Sep 2025 19:53:00 -0700 Message-ID: <20251001025442.427697-17-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251001025442.427697-1-chao.gao@intel.com> References: <20251001025442.427697-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" Failures encountered after a successful module shutdown are unrecoverable, e.g., there is no way to restore the old TDX Module. All subsequent SEAMCALLs to the TDX Module will fail and so TDs have to be killed. Report failures through sysfs attributes and log a message to clarify that SEAMCALL errors are expected in this situation. 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 (unless the system's update limit is exceeded, but the kernel will prevent an update attempt in this case). 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] --- arch/x86/virt/vmx/tdx/seamldr.c | 15 ++++++++++++++- arch/x86/virt/vmx/tdx/tdx.c | 6 ++++++ arch/x86/virt/vmx/tdx/tdx.h | 1 + drivers/virt/coco/tdx-host/tdx-host.c | 4 ++++ 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/arch/x86/virt/vmx/tdx/seamldr.c b/arch/x86/virt/vmx/tdx/seamld= r.c index b9daf11e1064..a5aff04a85b9 100644 --- a/arch/x86/virt/vmx/tdx/seamldr.c +++ b/arch/x86/virt/vmx/tdx/seamldr.c @@ -264,6 +264,14 @@ static void ack_state(void) } } =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() @@ -293,8 +301,13 @@ static int do_seamldr_install_module(void *params) break; } =20 - if (ret) + if (ret) { atomic_inc(&tdp_data.failed); + if (curstate > TDP_SHUTDOWN) { + tdx_module_set_error(); + print_update_failure_message(); + } + } ack_state(); } else { touch_nmi_watchdog(); diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 7019a149ec4b..26357be18fa9 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -1219,6 +1219,12 @@ int tdx_module_shutdown(void) return 0; } =20 +void tdx_module_set_error(void) +{ + /* Called from stop_machine(). no need to hold tdx_module_lock */ + tdx_module_status =3D TDX_MODULE_ERROR; +} + 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..5b9a2d63808c 100644 --- a/arch/x86/virt/vmx/tdx/tdx.h +++ b/arch/x86/virt/vmx/tdx/tdx.h @@ -120,5 +120,6 @@ struct tdmr_info_list { }; =20 int tdx_module_shutdown(void); +void tdx_module_set_error(void); =20 #endif diff --git a/drivers/virt/coco/tdx-host/tdx-host.c b/drivers/virt/coco/tdx-= host/tdx-host.c index 418e90797689..47c5ba115993 100644 --- a/drivers/virt/coco/tdx-host/tdx-host.c +++ b/drivers/virt/coco/tdx-host/tdx-host.c @@ -37,6 +37,10 @@ static ssize_t version_show(struct device *dev, struct d= evice_attribute *attr, const struct tdx_sys_info *tdx_sysinfo =3D tdx_get_sysinfo(); const struct tdx_sys_info_version *ver; =20 + /* + * Inform userspace that the TDX module isn't in a usable state, + * possibly due to a failed update. + */ if (!tdx_sysinfo) return -ENXIO; =20 --=20 2.47.3 From nobody Wed Oct 1 21:27:10 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 6C23A2D29C7 for ; Wed, 1 Oct 2025 02:55:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287329; cv=none; b=W/WKiEjY/uojKYSsyjsQSgv1LwyZQOKkvvplCa0Et7RqYYc/g03DCoawMpi8ccfh/V8i7CkP6nNkypuTRMfGP1ray5hSdKJXJrtOdv5tJJxA/a+MbFE5d3ltfaSGO1EkDxJ8cMQ44cPEsYIY8mBOVb3U1expqWs3ozEfyQjx460= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287329; c=relaxed/simple; bh=PeNpMG7ytKGm7nAoGehssroVVx6QgPfNqakoTe2BCEo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rA53F2y42o4VRSswD5/kcN//ADz09obaQaKqdraBfvYx1JEqs/4dP4wTegQWT55rG7oG1kBdfu8NltKyF2u0YkUmNTDI/PRXHhSJ001M1eAE7CXsBeg8yeDBQb9QXmgbNC2r3pFvWhEZF9H0O6g1YHAv+BQwRhvymbaM6ZwAx3M= 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=CRnKx/nH; arc=none smtp.client-ip=192.198.163.15 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="CRnKx/nH" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1759287327; x=1790823327; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=PeNpMG7ytKGm7nAoGehssroVVx6QgPfNqakoTe2BCEo=; b=CRnKx/nHuc9QS09DOob5ZpSUdeZ0YnDEZkviMlK2N56UT3zYcc0HVark jGuUHAJP7l3Zin736viLUkv+DVG5gxbABM6lKyMuUp04Di/oPalb/ajqa n3DGXzreqydMWX6PK1/tMyHjmOzha9bqEXsSip+eYsVa+R3OjHEEOR0qU JCyIQ9RLuOfyGFyDAm/5tcLnJdtcwA9ubXjX32nxbbyfovWMgKPxv5PXZ pCzvfzHI5ih1R//f7WdrnRE7w/rhQsv9tKHg8PPjkB0IOjJegeoa1vO/N FSQRCs6goVWkjQB5iHvlj5PPXMZPRFt4J4Mm862Ba9Kk2aXWw+uYe/ANs w==; X-CSE-ConnectionGUID: Lk7xf38vTgWwLreB4L3k8w== X-CSE-MsgGUID: uVjZzl6ZQI2NcZ76ncKK5g== X-IronPort-AV: E=McAfee;i="6800,10657,11569"; a="61662386" X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="61662386" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:26 -0700 X-CSE-ConnectionGUID: ZKddDkwLQ5aTnVipd/DamA== X-CSE-MsgGUID: wKAAagDCS0GofjVUVGTVAA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="178629251" Received: from 984fee019967.jf.intel.com ([10.165.54.94]) by fmviesa006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:25 -0700 From: Chao Gao To: linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org, x86@kernel.org, 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 Cc: Chao Gao , Farrah Chen , "Kirill A. Shutemov" , Dave Hansen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v2 17/21] x86/virt/seamldr: Install a new TDX Module Date: Tue, 30 Sep 2025 19:53:01 -0700 Message-ID: <20251001025442.427697-18-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251001025442.427697-1-chao.gao@intel.com> References: <20251001025442.427697-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 --- arch/x86/virt/vmx/tdx/seamldr.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/x86/virt/vmx/tdx/seamldr.c b/arch/x86/virt/vmx/tdx/seamld= r.c index a5aff04a85b9..1bb4ae5ccb0a 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) { @@ -231,6 +234,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 @@ -278,6 +282,7 @@ static void print_update_failure_message(void) */ static int do_seamldr_install_module(void *params) { + struct tdx_module_args args =3D { .rcx =3D __pa(params) }; enum tdp_state newstate, curstate =3D TDP_START; int cpu =3D smp_processor_id(); bool primary; @@ -297,6 +302,10 @@ static int do_seamldr_install_module(void *params) if (primary) ret =3D tdx_module_shutdown(); break; + case TDP_CPU_INSTALL: + scoped_guard(raw_spinlock, &seamldr_lock) + ret =3D seamldr_call(P_SEAMLDR_INSTALL, &args); + break; default: break; } --=20 2.47.3 From nobody Wed Oct 1 21:27:10 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 E98AB283FD4 for ; Wed, 1 Oct 2025 02:55:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287329; cv=none; b=d683f5kzHYKMRCX2PybGZUmfBf+crVIi24lHQZXOQ/7WUAM7BZ2KcGG55LbBQL5RKWyj7nq/h67D9KPPN4O3khWOzP2+CC6GLpJpg3Xo+XM5pn1e8fW+1Eb22LMXyjpLI7UPXEh3suBx5ONwNG8FgeGPu9n7xCI8ZcwJUDirv8Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287329; c=relaxed/simple; bh=BC4Zro2fVNDXj3htnYcwR82Ii9j7SNQ7ta0nQBLTK60=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TJXGLtYKbTF+a/5R6/M0BJYOSwmz2aJsy+QtZmqEk5//2XwVFPd2ZAYmV/KpX6NUk8aqlIJ1jp1PQfUWUMgoc0O9UmIqEWXNbmPWe6/huO6POljWxaK0FdInpIQaH1cDRx+M1lGgrw7gQeZ4GHud9Jighv3N7fTxYMPBk7JXFYI= 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=ANLxStxt; arc=none smtp.client-ip=192.198.163.15 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="ANLxStxt" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1759287328; x=1790823328; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=BC4Zro2fVNDXj3htnYcwR82Ii9j7SNQ7ta0nQBLTK60=; b=ANLxStxtodfppOom9T7ETCPvqq/76b6+J6/hubnF3/7qV840J1rOxsmE TJWZYp0rxSHnofN64uBRQekpV5z0is9rT4wnWMWB1ou33LeuuuYitsfLM Et64+58o21YPInZyVCUQ2YssNsdc+30j3PzB0i/pjlIhxuH96tesm7coa E0uUIf7Vvh/nDTqxBdhu0hIDf7szwnvsRN9zaNeDN0NuTtsBQznjq3rbY VQ/0QfmUTeawx6Y8zwZjt22dAUrnr5yDF3FtgyLm9r+FbBzL2Mab6Jgqq KPLX5ZFFpOnGuGx83naCPChBmNOstPjTD7+3b8auiJV9FxIcV6rvCcRss Q==; X-CSE-ConnectionGUID: rNYv2gxGRlusOKtMocOJVw== X-CSE-MsgGUID: Z2NqUjUIQqmD36DYpUKSTA== X-IronPort-AV: E=McAfee;i="6800,10657,11569"; a="61662395" X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="61662395" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:27 -0700 X-CSE-ConnectionGUID: tT2APZjqTOmohqsFKmVSCw== X-CSE-MsgGUID: SeBglYPrSkSB/eowgyxc6A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="178629257" Received: from 984fee019967.jf.intel.com ([10.165.54.94]) by fmviesa006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:26 -0700 From: Chao Gao To: linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org, x86@kernel.org, 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 Cc: Chao Gao , Farrah Chen , "Kirill A. Shutemov" , Dave Hansen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v2 18/21] x86/virt/seamldr: Do TDX per-CPU initialization after updates Date: Tue, 30 Sep 2025 19:53:02 -0700 Message-ID: <20251001025442.427697-19-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251001025442.427697-1-chao.gao@intel.com> References: <20251001025442.427697-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 --- arch/x86/virt/vmx/tdx/seamldr.c | 4 ++++ arch/x86/virt/vmx/tdx/tdx.c | 2 +- arch/x86/virt/vmx/tdx/tdx.h | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/x86/virt/vmx/tdx/seamldr.c b/arch/x86/virt/vmx/tdx/seamld= r.c index 1bb4ae5ccb0a..75bb650d8a16 100644 --- a/arch/x86/virt/vmx/tdx/seamldr.c +++ b/arch/x86/virt/vmx/tdx/seamldr.c @@ -235,6 +235,7 @@ enum tdp_state { TDP_START, TDP_SHUTDOWN, TDP_CPU_INSTALL, + TDP_CPU_INIT, TDP_DONE, }; =20 @@ -306,6 +307,9 @@ static int do_seamldr_install_module(void *params) 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; } diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 26357be18fa9..280c2a9f3211 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -106,7 +106,7 @@ static int try_init_module_global(void) * * Return 0 on success, otherwise errors. */ -static int tdx_cpu_enable(void) +int tdx_cpu_enable(void) { struct tdx_module_args args =3D {}; int ret; diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h index 5b9a2d63808c..b903e479e46a 100644 --- a/arch/x86/virt/vmx/tdx/tdx.h +++ b/arch/x86/virt/vmx/tdx/tdx.h @@ -121,5 +121,6 @@ struct tdmr_info_list { =20 int tdx_module_shutdown(void); void tdx_module_set_error(void); +int tdx_cpu_enable(void); =20 #endif --=20 2.47.3 From nobody Wed Oct 1 21:27:10 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 A050C2D320E for ; Wed, 1 Oct 2025 02:55:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287330; cv=none; b=Vws9WkjCF05RjaKNG7ResOtukzuo8VXqoEuyWP/QraaT67WhNNh5gTjsWwKUeslXxwzoC/TByrhGj1sioizM3386sDZ/KQWJWu/mB+OOC/lPStjeMD5bZflarYe08P4vl7KBQCF8Hs42RCW0Un4gTC/kVo2lr0IHFXNXmfcEpc4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287330; c=relaxed/simple; bh=vADsV89PSmvJZOoaBeDe/Vak6cLIKJ6PGY9nGPDgAYw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cc9JrX7lPIgSX1eWa39w9E0sHXUSD3DgcRceAlLysmST6Pvu2l0W8nZgtpNQpUbGUUWXOlaPMdzPXjQ+KBwSU2yaQD32khZ5JQmCM6gPU/RSUngs8aAT4JjVCC4OT8wsPbyiPXbGUVOQMbDoH21lxpomHsMhfio1K3NoNVTcCzg= 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=OlsYRZY4; arc=none smtp.client-ip=192.198.163.15 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="OlsYRZY4" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1759287329; x=1790823329; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=vADsV89PSmvJZOoaBeDe/Vak6cLIKJ6PGY9nGPDgAYw=; b=OlsYRZY4izcJM37b0JkDw+H1CQR4TK1HeS004KzIOlS5zgCoPQt9fHWN T81oz1r1AbQR2eGdet0WosD5Kmkd9JpIFltn7ZF8r3vzSXe332fo5I301 vsqH5Khg1bNpHdmS5/IrfA/ofnPZyVmxDQjbPLShY8Vp4cPfeT6VMk3In VofH+BWCO1sn2ZObAgQUeh4qAgUtpJ8Iuxjcmbk3ngCxaWjbIkYQ+LwtE JfcMir6CP0IdxybkWNSEMQydGXgiRdRqXvG7NOUMmBPK5Bqcfl/eL625h 2XuZm3bugpBHi5O6e7i273nCcKA2kXe2XPSm4T4V6xWI3irshy09bghpm w==; X-CSE-ConnectionGUID: dk1hrcRZQhqF79FKGntv6w== X-CSE-MsgGUID: TnBigeeoQjSZ+V3swg+2/Q== X-IronPort-AV: E=McAfee;i="6800,10657,11569"; a="61662404" X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="61662404" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:28 -0700 X-CSE-ConnectionGUID: Ygo/JPnLTUSYx8mEOBB9fQ== X-CSE-MsgGUID: CRJU+fg4TNObl/3Kp/z9qw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="178629263" Received: from 984fee019967.jf.intel.com ([10.165.54.94]) by fmviesa006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:27 -0700 From: Chao Gao To: linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org, x86@kernel.org, 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 Cc: Chao Gao , Farrah Chen , "Kirill A. Shutemov" , Dave Hansen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v2 19/21] x86/virt/tdx: Establish contexts for the new TDX Module Date: Tue, 30 Sep 2025 19:53:03 -0700 Message-ID: <20251001025442.427697-20-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251001025442.427697-1-chao.gao@intel.com> References: <20251001025442.427697-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 --- 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 75bb650d8a16..a8ca6966beac 100644 --- a/arch/x86/virt/vmx/tdx/seamldr.c +++ b/arch/x86/virt/vmx/tdx/seamldr.c @@ -236,6 +236,7 @@ enum tdp_state { TDP_SHUTDOWN, TDP_CPU_INSTALL, TDP_CPU_INIT, + TDP_RUN_UPDATE, TDP_DONE, }; =20 @@ -310,6 +311,10 @@ static int do_seamldr_install_module(void *params) 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 280c2a9f3211..7613fd16a0ce 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -1225,6 +1225,22 @@ void tdx_module_set_error(void) tdx_module_status =3D TDX_MODULE_ERROR; } =20 +int tdx_module_run_update(void) +{ + struct tdx_module_args args =3D {}; + int ret; + + ret =3D seamcall(TDH_SYS_UPDATE, &args); + if (ret) { + tdx_module_status =3D TDX_MODULE_ERROR; + pr_info("module update failed: %d\n", ret); + 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 b903e479e46a..983c01c6949a 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: @@ -122,5 +123,6 @@ struct tdmr_info_list { int tdx_module_shutdown(void); void tdx_module_set_error(void); int tdx_cpu_enable(void); +int tdx_module_run_update(void); =20 #endif --=20 2.47.3 From nobody Wed Oct 1 21:27:10 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 6BC0D2D322E for ; Wed, 1 Oct 2025 02:55:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287331; cv=none; b=nUZYJYAdzCBIMqjKiZTOX9+4tvSpsRnvQ1U0UM+C4H162QUc+0Z4BjE/8GZarW0Fcmexbyrk/5oWcWqt6LnsBWCvMafct02jcOepAenDB0loiNENrsrGHRHzxWmUDAzVBSiEUVXkPBxrxqBwIhRKQYxyj6tR6X45q5yweCG0IZU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287331; c=relaxed/simple; bh=R1N6ZO22N35zpImTc/SKCF7m0x1qzhG+Jw9Z6fTFvVw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SMKAex0acs5W79UqN8/NY2ZPa6cr4qqP4UVMqCSYrxtNL923J+zIKBwOgWHT3gV9eMr57XRfDnQ+RH45JThZ0JnpTBNXPB16NyYp73aPdVwYmUm9aVBVTjCANZ8ddPoWKqMAP/EvYg8Fth1CzdwSl8P6yxXVmdXDHKwrJ9ziF90= 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=A7rqX/R9; arc=none smtp.client-ip=192.198.163.15 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="A7rqX/R9" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1759287329; x=1790823329; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=R1N6ZO22N35zpImTc/SKCF7m0x1qzhG+Jw9Z6fTFvVw=; b=A7rqX/R9uKI3kfdjzDT0svUvHX/DcMxUt/7BHrHEAuzYkNhKPmCM1VM3 D9UrujQwKEB3oiwpFbWYuqPJkWCGo8Wo4jafzqr6k7Y5CPTk7guTAbSxq mCWgejA6buTXwqDLQhJJ7fJYYXsI2FDDDSmxIMBj/0vKe1kCsD3kA7y8M 1INCP5vQP5dB3bT6Ywd+comCvcDttc7GF5+ZO4JuNDpE0c2tt7V7wu0Bz iKYw8odZcK/iPd+1y73Qu3J3hsV6IkUZXolIzDtc4M3ey8MSoqaoAoijt LWQyjm5UXIpY06rjRRZZwmA1kKVbPCa6DD9ODc17GxfHSWPryyA/e18Z5 g==; X-CSE-ConnectionGUID: zU7ifFu2ROaPxG3J5Pk9Dg== X-CSE-MsgGUID: KfO7B5wPRkCZfFcvpabOYA== X-IronPort-AV: E=McAfee;i="6800,10657,11569"; a="61662414" X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="61662414" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:29 -0700 X-CSE-ConnectionGUID: MFkBaBF3TWOrhtRoAtJh4A== X-CSE-MsgGUID: wes74529Q+e/VOq6FD/qHg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="178629272" Received: from 984fee019967.jf.intel.com ([10.165.54.94]) by fmviesa006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:28 -0700 From: Chao Gao To: linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org, x86@kernel.org, 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 Cc: Chao Gao , Farrah Chen , "Kirill A. Shutemov" , Dave Hansen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v2 20/21] x86/virt/tdx: Update tdx_sysinfo and check features post-update Date: Tue, 30 Sep 2025 19:53:04 -0700 Message-ID: <20251001025442.427697-21-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251001025442.427697-1-chao.gao@intel.com> References: <20251001025442.427697-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 --- 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 | 12 ++++++++- arch/x86/virt/vmx/tdx/tdx.c | 47 +++++++++++++++++++++++++++++++++ arch/x86/virt/vmx/tdx/tdx.h | 2 ++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/arch/x86/virt/vmx/tdx/seamldr.c b/arch/x86/virt/vmx/tdx/seamld= r.c index a8ca6966beac..a72f6b0b27e9 100644 --- a/arch/x86/virt/vmx/tdx/seamldr.c +++ b/arch/x86/virt/vmx/tdx/seamldr.c @@ -350,6 +350,16 @@ int seamldr_install_module(const u8 *data, u32 size) if (!info->num_remaining_updates) return -ENOSPC; =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)) @@ -367,6 +377,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_GPL_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 7613fd16a0ce..128e6ffba736 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -1241,6 +1241,53 @@ 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 *cur, *new; + int ret; + + /* Shouldn't fail as the update has succeeded */ + ret =3D get_tdx_sys_info(info); + if (ret) { + WARN_ONCE(1, "version retrieval failed after update, replace TDX Module\= n"); + return ret; + } + + guard(mutex)(&tdx_module_lock); + + cur =3D &tdx_sysinfo.version; + new =3D &info->version; + pr_info("version %u.%u.%02u -> %u.%u.%02u\n", cur->major_version, + cur->minor_version, + cur->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 a potential BIOS update.\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 983c01c6949a..ca76126880ee 100644 --- a/arch/x86/virt/vmx/tdx/tdx.h +++ b/arch/x86/virt/vmx/tdx/tdx.h @@ -3,6 +3,7 @@ #define _X86_VIRT_TDX_H =20 #include +#include =20 /* * This file contains both macros and data structures defined by the TDX @@ -124,5 +125,6 @@ int tdx_module_shutdown(void); void tdx_module_set_error(void); int tdx_cpu_enable(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 Wed Oct 1 21:27:10 2025 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 48F3E2D3731 for ; Wed, 1 Oct 2025 02:55:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287331; cv=none; b=X6renzE4bVMKJh7BUfU/engbm4XJLyNV/jZ3UW5+ZBHfyUNP9t4YTUa0Cp8aVstbv7RIzsU1e79bsKvZE961Tv0Q7uVaKP8XdjbiMuPpZH54PEu2euzL0TIl2CXq1fgxKV4Mj+oMtQD/sTyhBQQcWCoIHs5+S4G13clDXmGbTUM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759287331; c=relaxed/simple; bh=afH+CbWJk+R3QqJvXfANhF7hRA27nbMPG3qpLyeTTk4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IMNiuswgj8QGckXV4nXoKHuEESTs/73A3s6HF7YU3Z2BIQBiCWa2Vs0x4czFSVfZBK8b95+t4C4yBqhQ/dxQY1dzLCDxAfncQHuj7arqu1EYWyFlxqO532c/G0Yw4tbJu/uiLDDlOm84yBx5ih5ATOtgE0Xhw+MXITnromRQxfI= 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=ixUzme/5; arc=none smtp.client-ip=192.198.163.15 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="ixUzme/5" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1759287330; x=1790823330; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=afH+CbWJk+R3QqJvXfANhF7hRA27nbMPG3qpLyeTTk4=; b=ixUzme/5n2m7oreU6EIzGO9UYeOfpv/0+Q/mYWl4dJnyrX2anz5gh1cU 3qJH36eXBKUAWk3s4bBOLmQCD76yoWMuyrTBRPFhV/jYECXJwoc5e2e4O U6etZfGJdZ5tVPxSY3Gv1C/sm7+yG9HTgRrwb4BUkLZIClBDuDFFHlMX6 b0BBFl+JgRP755t/SefVx0L5QV98TZ/aXpFPJ2yLNQyfl80JXsmivcK8B 0zML4jjBFQzzoc4GhYWN9E2MkwfBQZeZSKBEfFLFTxuPRrSooFpGmROZc X/wQlSuBmvG08pZ+K9QZIKlgC2MdzgQHtPjd1iQPqgq893TXtpcUiSTm/ A==; X-CSE-ConnectionGUID: 1Bo4ObIMQgi1Oof+4BGXhA== X-CSE-MsgGUID: vBsOILCERNa3LBrwRxzKBQ== X-IronPort-AV: E=McAfee;i="6800,10657,11569"; a="61662423" X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="61662423" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:30 -0700 X-CSE-ConnectionGUID: eoSP3TlvTSm77f9WuV6SkA== X-CSE-MsgGUID: SOehwTZ6RM+3uNdxi5rK5w== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.18,305,1751266800"; d="scan'208";a="178629276" Received: from 984fee019967.jf.intel.com ([10.165.54.94]) by fmviesa006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2025 19:55:29 -0700 From: Chao Gao To: linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org, x86@kernel.org, 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 Cc: Chao Gao , "Kirill A. Shutemov" , Dave Hansen , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" Subject: [PATCH v2 21/21] x86/virt/tdx: Enable TDX Module runtime updates Date: Tue, 30 Sep 2025 19:53:05 -0700 Message-ID: <20251001025442.427697-22-chao.gao@intel.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251001025442.427697-1-chao.gao@intel.com> References: <20251001025442.427697-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 --- arch/x86/include/asm/tdx.h | 6 +++++- arch/x86/virt/vmx/tdx/tdx.h | 3 --- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h index 2422904079a3..94aa1237fef4 100644 --- a/arch/x86/include/asm/tdx.h +++ b/arch/x86/include/asm/tdx.h @@ -32,6 +32,10 @@ #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) + /* P-SEAMLDR SEAMCALL leaf function error codes */ #define SEAMLDR_RND_NO_ENTROPY 0x8000000000030001ULL =20 @@ -109,7 +113,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 ca76126880ee..1965adb63f1f 100644 --- a/arch/x86/virt/vmx/tdx/tdx.h +++ b/arch/x86/virt/vmx/tdx/tdx.h @@ -87,9 +87,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