From nobody Wed Oct 1 22:30:46 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