From nobody Tue Sep 29 14:57:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.12]) (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 C0DF6376481; Fri, 21 Aug 2026 03:29:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.12 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787282970; cv=none; b=gsZFxv/CISK3pZBcMcB1BrqIa7rt34EWg42bUSa1oUtaAhGgP7/5Iq8AH1uJKx4+7AvRDz3jINNk/aRJU+ozI7y6PkW0g/OMOflhhADNDAAqMewvNppQhX1QPiFDLFq9poizccF0flBxVA1rFgX+glMIbZ24JQJlfLp5vh1H8wo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787282970; c=relaxed/simple; bh=jQ/6jTsL7xHFq0CUQFu2tng7jbSNUzKL86CMcOyZm+U=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=tnmm3Q6II3T/3wDIj/R0XBa80fJSwAI42GfeOhQfgbMa52TbsafgHJqX3C1OBZ+EWHeBOEjPzcGS6lYcIV1O8JGDTHx8Cv3Y9bTHhmKlH+8F8CbS+J1CkPgJGOuO8DnfNErRoS2o6vuePL4H611M3Zut1ZrzKG0gIjMBW3W1xlQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=VgD3qO8w; arc=none smtp.client-ip=192.198.163.12 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="VgD3qO8w" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1787282969; x=1818818969; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=jQ/6jTsL7xHFq0CUQFu2tng7jbSNUzKL86CMcOyZm+U=; b=VgD3qO8w5fo/UgB2hI1IBm7jiMu3c3XJo16tUDslCb6MLprFqhFZaxME 885KAP9Sr2ZkbAQW6fk9oP+FZe3qBvHu3JjjNUAuH21kN6nsWOQz9H8cX UaXQh4gNInb4Sp8PmR6rnxCSXfTOftxT7BsWj2sf/tPC2ysy4IdYLxS71 dpP4zOPoqv30mKk1GEWP4KoTDy6mHnOiFZZG+vld7+1g4rTqm5p8TLJYF /yaiBOpODBaCmy+Lnk/97oBeCfxPBVGtKifrNhMkWKEuh7/5bo4Y97Cau 6aRVni9whvpdIyuT17wWLAtmJHbwH2exuWYRfu1y6lZ/m0segCrHve2qK g==; X-CSE-ConnectionGUID: DxNF1m13Qgiw3uNmQC9IAw== X-CSE-MsgGUID: f8BmwCoLSyqVzR1zCmbh9g== X-IronPort-AV: E=McAfee;i="6800,10657,11881"; a="91640226" X-IronPort-AV: E=Sophos;i="6.25,234,1779174000"; d="scan'208";a="91640226" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Aug 2026 20:29:28 -0700 X-CSE-ConnectionGUID: 3k0a7FsUS0CVVHP2rfb5Dw== X-CSE-MsgGUID: 9evOJi/nSJSWDEJ02DEWyw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.25,234,1779174000"; d="scan'208";a="264451590" Received: from yilunxu-optiplex-7050.sh.intel.com ([10.239.47.46]) by orviesa006.jf.intel.com with ESMTP; 20 Aug 2026 20:29:25 -0700 From: Xu Yilun To: x86@kernel.org, linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org Cc: kas@kernel.org, rick.p.edgecombe@intel.com, yilun.xu@linux.intel.com, yilun.xu@intel.com, xiaoyao.li@intel.com, sohil.mehta@intel.com, adrian.hunter@intel.com, kishen.maloor@intel.com, tony.lindgren@linux.intel.com, peter.fang@intel.com, baolu.lu@linux.intel.com, zhenzhong.duan@intel.com, chao.gao@intel.com, artem.bityutskiy@linux.intel.com, kvm@vger.kernel.org Subject: [PATCH 1/6] x86/virt/tdx: Wrap TDH.SYS.CONFIG/UPDATE operations in helpers Date: Fri, 21 Aug 2026 11:29:15 +0800 Message-Id: <20260821032920.256225-2-yilun.xu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20260821032920.256225-1-yilun.xu@linux.intel.com> References: <20260821032920.256225-1-yilun.xu@linux.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" As part of the TDX module initialization, the kernel configures the TDX module with several information, such as TDX-usable memory regions (TDMRs) and the global KeyID for protecting TDX metadata. During the configuration, the kernel does 2 operations: constructing kernel data types for the SEAMCALL leaf arguments and turning these data types into u64's according to TDX ABI. Both operations are implemented in one function - config_tdx_module(). This blurs the boundary between kernel managed structures and TDX ABI definitions. Moreover, future kernel change will need to add more nuances mandated by TDX ABI, such as setting the TDH.SYS.CONFIG leaf version to allow configuring add-on features. Keeping these operations tangled would further clutter the code. Just like other SEAMCALL leaf helpers, wrap the invocation of TDH.SYS.CONFIG in a helper. Introduce a more descriptive kernel data type for the physical address array of TDMR information. This data type is similar to struct seamldr_params in that it is the container of the PA array layout which is an in-memory ABI. So the previous u64 * type for the array is not wrong, but a named structure provides better type safety and self-documentation. Use the data type as the argument of the TDH.SYS.CONFIG helper. Future kernel change will also need to set the TDH.SYS.UPDATE leaf version for the same purpose. Add a similar helper to prepare for the change. Signed-off-by: Xu Yilun Reviewed-by: Nikolay Borisov --- v1: - This patch is split out from the last series (Rick) --- arch/x86/virt/vmx/tdx/tdx.c | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 7a89e29b118c..e6b664b76141 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -998,11 +998,26 @@ static __init int construct_tdmrs(struct list_head *t= mb_list, return ret; } =20 +struct tdmr_info_pa_array { + DECLARE_FLEX_ARRAY(u64, phys); +}; + +static __init int tdx_sys_config(struct tdmr_info_pa_array *tdmr_pa_array, + u64 nr_tdmr_pa, u64 global_keyid) +{ + struct tdx_module_args args =3D { + .rcx =3D __pa(tdmr_pa_array), + .rdx =3D nr_tdmr_pa, + .r8 =3D global_keyid, + }; + + return seamcall_prerr(TDH_SYS_CONFIG, &args); +} + static __init int config_tdx_module(struct tdmr_info_list *tdmr_list, u64 global_keyid) { - struct tdx_module_args args =3D {}; - u64 *tdmr_pa_array; + struct tdmr_info_pa_array *tdmr_pa_array; size_t array_sz; int i, ret; =20 @@ -1021,12 +1036,10 @@ static __init int config_tdx_module(struct tdmr_inf= o_list *tdmr_list, return -ENOMEM; =20 for (i =3D 0; i < tdmr_list->nr_consumed_tdmrs; i++) - tdmr_pa_array[i] =3D __pa(tdmr_entry(tdmr_list, i)); + tdmr_pa_array->phys[i] =3D __pa(tdmr_entry(tdmr_list, i)); =20 - args.rcx =3D __pa(tdmr_pa_array); - args.rdx =3D tdmr_list->nr_consumed_tdmrs; - args.r8 =3D global_keyid; - ret =3D seamcall_prerr(TDH_SYS_CONFIG, &args); + ret =3D tdx_sys_config(tdmr_pa_array, tdmr_list->nr_consumed_tdmrs, + global_keyid); =20 /* Free the array as it is not required anymore. */ kfree(tdmr_pa_array); @@ -1306,12 +1319,18 @@ int tdx_module_shutdown(void) return 0; } =20 -int tdx_module_run_update(void) +static int tdx_sys_update(void) { struct tdx_module_args args =3D {}; + + return seamcall_prerr(TDH_SYS_UPDATE, &args); +} + +int tdx_module_run_update(void) +{ int ret; =20 - ret =3D seamcall_prerr(TDH_SYS_UPDATE, &args); + ret =3D tdx_sys_update(); if (ret) return ret; =20 --=20 2.25.1 From nobody Tue Sep 29 14:57:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.12]) (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 A4B54375ABE; Fri, 21 Aug 2026 03:29:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.12 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787282975; cv=none; b=Wr+tM2H06GR9pP1jPz+bGSh9EXRctN2H0D408Za/WULF5G7U5SdfgFxuG31jqZq37HpAN4eteJs8YjyWOnJjp0FSljPw4K4DA1R9JuA5wpwOxcrca6GcN9tHdlS0RiljrZ3xkRyQiTH3x0ZT0Hg4wwOLtMdbdR5SvhVU72zGtLE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787282975; c=relaxed/simple; bh=6rvVFKxEnernaSvmYoh25XXuJSQ+q6hKX3xaltJL/Wk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=JlyeffI8P6cttXc7TdkGkL9ALS4CO+V9UZuCFQYhroCCsvGPGaflwnRfXuEgMyrmqVeNWbZRkyuTA3z25X7HXREM3tbUstLUA+AOrYPluLV8F7GLWaMpn7ErT0wqtcBTSl3RYRJi/Pw6PUCV2tMO7rOminfXbinb91IVfNUyz60= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=kyltVBrG; arc=none smtp.client-ip=192.198.163.12 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="kyltVBrG" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1787282972; x=1818818972; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=6rvVFKxEnernaSvmYoh25XXuJSQ+q6hKX3xaltJL/Wk=; b=kyltVBrGSDbUSDsVy+uu+xS0mMvWW6YKgM613TbMDgAPYxpEhEBCMU8q 74/khRBqvwlJyzLOgP+cBUqga0iWuSlCK8+GuQs82hkY+2YTtBZNxQiV4 5oDgiu++jNejQwAEhtKiL8X59Q1fiO+6T1eNAi2OgiLcKdcmpXXTLTWLM UZg7/gAGrjTU32OHhCpJ5QDCoXSXEJyYHJR3PW7H+a4vpMVuGsWCveEbj rxXcUKkDPXuXu/j+oqpdl9pj8DJzUX+odjafWlccEm12iMV2C4eMJghBG sL57ycFxiHp5CF1YxOBXNbmGWRDuvOc5k5bJrhgPGpc95AUVVMVC1AUNZ Q==; X-CSE-ConnectionGUID: 2sVdjlvyQNqTZuzjtgKqUw== X-CSE-MsgGUID: ezbatukYQvCnUULJBYUlZQ== X-IronPort-AV: E=McAfee;i="6800,10657,11881"; a="91640230" X-IronPort-AV: E=Sophos;i="6.25,234,1779174000"; d="scan'208";a="91640230" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Aug 2026 20:29:32 -0700 X-CSE-ConnectionGUID: ej9bZVR0QWKoAcw3GavhhQ== X-CSE-MsgGUID: jargdX2nSzS+DkYr60TYLQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.25,234,1779174000"; d="scan'208";a="264451594" Received: from yilunxu-optiplex-7050.sh.intel.com ([10.239.47.46]) by orviesa006.jf.intel.com with ESMTP; 20 Aug 2026 20:29:29 -0700 From: Xu Yilun To: x86@kernel.org, linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org Cc: kas@kernel.org, rick.p.edgecombe@intel.com, yilun.xu@linux.intel.com, yilun.xu@intel.com, xiaoyao.li@intel.com, sohil.mehta@intel.com, adrian.hunter@intel.com, kishen.maloor@intel.com, tony.lindgren@linux.intel.com, peter.fang@intel.com, baolu.lu@linux.intel.com, zhenzhong.duan@intel.com, chao.gao@intel.com, artem.bityutskiy@linux.intel.com, kvm@vger.kernel.org Subject: [PATCH 2/6] x86/virt/tdx: Configure add-on features on TDX module init and update Date: Fri, 21 Aug 2026 11:29:16 +0800 Message-Id: <20260821032920.256225-3-yilun.xu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20260821032920.256225-1-yilun.xu@linux.intel.com> References: <20260821032920.256225-1-yilun.xu@linux.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 architecture identifies some features that must be explicitly enabled when the kernel supports them. These add-on features affect existing TDX systems: they may change existing feature behavior, reserve more memory, or impact TDX initialization performance. The kernel must enable these add-on features at boot or post-update time. TDISP, DICE-based quoting and TD migration are among those add-on features, as their SEAMCALL leaves depend on a SEAMCALL execution context built by the TDX module extensions. On the other hand, the TDX architecture doesn't allow the extensions to be initialized if none of these features are enabled. Add support for configuring add-on features, as the prerequisite for enabling the extensions. The TDX module extends TDH.SYS.CONFIG and TDH.SYS.UPDATE with new bitmap parameters to specify which add-on features to enable. The bitmap uses the same feature bits as TDX_FEATURES0. Add a get_tdx_addon_features0() helper to return the bitmap of the add-on features that the module & kernel both support. Initially, this helper returns 0. It will be updated to return specific feature bits as full kernel support lands. Pass this extra bitmap to TDH.SYS.CONFIG helper. The TDX module requires SEAMCALL leaf version 1 for TDH.SYS.CONFIG and TDH.SYS.UPDATE when passing the new bitmap parameter. A previous change [1] supports the versioned SEAMCALL leaves by adding a "version" field in struct tdx_module_args. Set the version field to 1 if any bit is set in this bitmap. Compatible updates keep the reported features unchanged across updates, so that existing TDX users can continue to operate without disruption. To adhere to this, provide TDH.SYS.UPDATE with the same bitmap returned by get_tdx_addon_features0(). This works because the module supported feature bits are cached at boot and never refreshed after updates, so the returned bitmap always matches the initial TDH.SYS.CONFIG input. Signed-off-by: Xu Yilun Link: https://lore.kernel.org/all/20260722084634.131020-1-yilun.xu@linux.in= tel.com/ # [1] --- v1: - Use tdx_module_args.version to assign SEAMCALL leaf versions (Dave) - Remove DICE specific descriptions (Rick) - Remove the global var tdx_addon_features0 (Chao) - Add a Macro to collect kernel supported add-on feature bits (Rick) - Changelog & code comments change --- arch/x86/virt/vmx/tdx/tdx.c | 38 +++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index e6b664b76141..66b43350c6c3 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -998,12 +998,22 @@ static __init int construct_tdmrs(struct list_head *t= mb_list, return ret; } =20 +/* List all kernel supported add-on features0 bits here */ +#define TDX_KERNEL_SUPPORTED_ADDON_FEATURES0 (0) + +static u64 get_tdx_addon_features0(void) +{ + return tdx_sysinfo.features.tdx_features0 & + TDX_KERNEL_SUPPORTED_ADDON_FEATURES0; +} + struct tdmr_info_pa_array { DECLARE_FLEX_ARRAY(u64, phys); }; =20 static __init int tdx_sys_config(struct tdmr_info_pa_array *tdmr_pa_array, - u64 nr_tdmr_pa, u64 global_keyid) + u64 nr_tdmr_pa, u64 global_keyid, + u64 addon_features0) { struct tdx_module_args args =3D { .rcx =3D __pa(tdmr_pa_array), @@ -1011,12 +1021,22 @@ static __init int tdx_sys_config(struct tdmr_info_p= a_array *tdmr_pa_array, .r8 =3D global_keyid, }; =20 + /* + * Use SEAMCALL version 1 that supports add-on features if any are + * requested. Use version 0 if none for backward compatibility. + */ + if (addon_features0) { + args.r9 =3D addon_features0; + args.version =3D 1; + } + return seamcall_prerr(TDH_SYS_CONFIG, &args); } =20 static __init int config_tdx_module(struct tdmr_info_list *tdmr_list, u64 global_keyid) { + u64 addon_features0 =3D get_tdx_addon_features0(); struct tdmr_info_pa_array *tdmr_pa_array; size_t array_sz; int i, ret; @@ -1039,7 +1059,7 @@ static __init int config_tdx_module(struct tdmr_info_= list *tdmr_list, tdmr_pa_array->phys[i] =3D __pa(tdmr_entry(tdmr_list, i)); =20 ret =3D tdx_sys_config(tdmr_pa_array, tdmr_list->nr_consumed_tdmrs, - global_keyid); + global_keyid, addon_features0); =20 /* Free the array as it is not required anymore. */ kfree(tdmr_pa_array); @@ -1319,18 +1339,28 @@ int tdx_module_shutdown(void) return 0; } =20 -static int tdx_sys_update(void) +static int tdx_sys_update(u64 addon_features0) { struct tdx_module_args args =3D {}; =20 + /* + * Use SEAMCALL version 1 that supports add-on features if any are + * requested. Use version 0 if none for backward compatibility. + */ + if (addon_features0) { + args.r9 =3D addon_features0; + args.version =3D 1; + } + return seamcall_prerr(TDH_SYS_UPDATE, &args); } =20 int tdx_module_run_update(void) { + u64 addon_features0 =3D get_tdx_addon_features0(); int ret; =20 - ret =3D tdx_sys_update(); + ret =3D tdx_sys_update(addon_features0); if (ret) return ret; =20 --=20 2.25.1 From nobody Tue Sep 29 14:57:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.12]) (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 8D7F73793DE; Fri, 21 Aug 2026 03:29:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.12 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787282978; cv=none; b=CM/fiL0jKMB53rKgeSxAXsYHAFBBi5SED+K9taplvHh9/gdb9JabEjAkH/jnigy+NsRj/KCwSkpTBOgfL8f9k4qrw9hE1tblAfVKfmKmrx90XrcZ3EVdM4PYdmDq758P+Bt/GPYlmb8o91EQVDu6bUGsMNWmgTf0Wjy9xzu+DXE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787282978; c=relaxed/simple; bh=znetrghf6ys/CPFLpyjpzXAtsRZnYs4HpIExNFpBIac=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=B7k6fjBOnxcACzOD7kh8qdpHqTbIMF80M+mpSpeDubnYfcyEoIX149Xb3MD7u6tsX1VrMMJPPfGecwdmga0tSyGwTbUuSvbd9pReOmdxSiia1jU3KJN6ch4mEDjB06yMVVagBTsYrbk3JqQqgRG3uxWfd/i6gLENgjnzCKPvVKM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=N2EH4pHS; arc=none smtp.client-ip=192.198.163.12 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="N2EH4pHS" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1787282976; x=1818818976; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=znetrghf6ys/CPFLpyjpzXAtsRZnYs4HpIExNFpBIac=; b=N2EH4pHSqJXiRH4M6vWGVwyYG8Rs3Fmcx5JkZ7vbfIK3T35g5qUTfLAK BdgSHy9zvcgIoH/7y5Jdd2TOwIvFqkaq+7mwYB3eC9I8IbgcThs965O6a SFxrvuUox9sOIrFUYwlJEqs5eVbzYJMR4xMV0MwcFuqxn8BUi9pPD9aJw 5VivL+ishBAIOHKZgz/25/Kf5OD8rRaPH854oKXaE/CTTtlhNF66zDFCx hWRDo9Es3N+0hufWuc10QSxHAFWLBG4XIqSiu2QpaROsbbEjQywTznByJ LZEGVGAEdggbYbJdm1E9UsQk0ufVTo9FyeZkmfI+hpRyWUgJ+k5ZzPnKs A==; X-CSE-ConnectionGUID: lmllmSy/SfShkistCrH8wQ== X-CSE-MsgGUID: uLQXwdo0SPqXJjPIwdx/vw== X-IronPort-AV: E=McAfee;i="6800,10657,11881"; a="91640234" X-IronPort-AV: E=Sophos;i="6.25,234,1779174000"; d="scan'208";a="91640234" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Aug 2026 20:29:36 -0700 X-CSE-ConnectionGUID: auoBD2X3S5OW0iH1anPlaA== X-CSE-MsgGUID: otBEypIySkqAjkcRsgUWTQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.25,234,1779174000"; d="scan'208";a="264451600" Received: from yilunxu-optiplex-7050.sh.intel.com ([10.239.47.46]) by orviesa006.jf.intel.com with ESMTP; 20 Aug 2026 20:29:33 -0700 From: Xu Yilun To: x86@kernel.org, linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org Cc: kas@kernel.org, rick.p.edgecombe@intel.com, yilun.xu@linux.intel.com, yilun.xu@intel.com, xiaoyao.li@intel.com, sohil.mehta@intel.com, adrian.hunter@intel.com, kishen.maloor@intel.com, tony.lindgren@linux.intel.com, peter.fang@intel.com, baolu.lu@linux.intel.com, zhenzhong.duan@intel.com, chao.gao@intel.com, artem.bityutskiy@linux.intel.com, kvm@vger.kernel.org Subject: [PATCH 3/6] x86/virt/tdx: Detect if the extensions initialization is required Date: Fri, 21 Aug 2026 11:29:17 +0800 Message-Id: <20260821032920.256225-4-yilun.xu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20260821032920.256225-1-yilun.xu@linux.intel.com> References: <20260821032920.256225-1-yilun.xu@linux.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" Some add-on features require TDX module extensions. The TDX module provides a metadata field "ext_required" to indicate this requirement. Add the first step of TDX module extensions initialization by detecting if the extensions are required: 1. Check if the extensions are supported via TDX_FEATURES0_EXT. If not, ext_required is not readable. 2. Check if any TDX feature needs the extensions via ext_required. Skip the extensions initialization when it is not required. Currently all metadata fields are read at the very beginning of TDX module initialization. However, ext_required is only valid after the add-on feature configuration, so it cannot use the existing metadata reading method. Add a dedicated metadata reading interface for the extensions, call it after add-on feature configuration. Signed-off-by: Xu Yilun Reviewed-by: Tony Lindgren --- v1: - Include struct tdx_sys_info_ext in struct tdx_sys_info. --- arch/x86/include/asm/tdx.h | 1 + arch/x86/include/asm/tdx_global_metadata.h | 5 ++++ arch/x86/virt/vmx/tdx/tdx.c | 28 +++++++++++++++++++++ arch/x86/virt/vmx/tdx/tdx_global_metadata.c | 14 +++++++++++ 4 files changed, 48 insertions(+) diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h index 89e97d5761d8..6657f2db0330 100644 --- a/arch/x86/include/asm/tdx.h +++ b/arch/x86/include/asm/tdx.h @@ -36,6 +36,7 @@ /* Bit definitions of TDX_FEATURES0 metadata field */ #define TDX_FEATURES0_TD_PRESERVING BIT_ULL(1) #define TDX_FEATURES0_NO_RBP_MOD BIT_ULL(18) +#define TDX_FEATURES0_EXT BIT_ULL(39) =20 #ifndef __ASSEMBLER__ =20 diff --git a/arch/x86/include/asm/tdx_global_metadata.h b/arch/x86/include/= asm/tdx_global_metadata.h index 41150d546589..fe3fe91de71f 100644 --- a/arch/x86/include/asm/tdx_global_metadata.h +++ b/arch/x86/include/asm/tdx_global_metadata.h @@ -44,12 +44,17 @@ struct tdx_sys_info_handoff { u16 module_hv; }; =20 +struct tdx_sys_info_ext { + bool ext_required; +}; + 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_ext ext; }; =20 #endif diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 66b43350c6c3..a0c370894c0b 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -1175,6 +1175,30 @@ static __init int init_tdmrs(struct tdmr_info_list *= tdmr_list) return 0; } =20 +static __init int init_tdx_module_extensions(void) +{ + int ret; + + if (!(tdx_sysinfo.features.tdx_features0 & TDX_FEATURES0_EXT)) + return 0; + + ret =3D get_tdx_sys_info_ext(&tdx_sysinfo.ext); + if (ret) + return ret; + + /* + * ext_required indicates if any add-on features requiring TDX module + * extensions are configured via TDH.SYS.CONFIG. If none, skip the + * initialization. + */ + if (!tdx_sysinfo.ext.ext_required) + return 0; + + /* TODO: add the extensions enabling steps here */ + + return 0; +} + static __init int init_tdx_module(void) { int ret; @@ -1229,6 +1253,10 @@ static __init int init_tdx_module(void) if (ret) goto err_reset_pamts; =20 + ret =3D init_tdx_module_extensions(); + if (ret) + goto err_reset_pamts; + pr_info("%lu KB allocated for PAMT\n", tdmrs_count_pamt_kb(&tdx_tdmr_list= )); =20 out_put_tdxmem: diff --git a/arch/x86/virt/vmx/tdx/tdx_global_metadata.c b/arch/x86/virt/vm= x/tdx/tdx_global_metadata.c index e49c300f23d4..b9e1c011a990 100644 --- a/arch/x86/virt/vmx/tdx/tdx_global_metadata.c +++ b/arch/x86/virt/vmx/tdx/tdx_global_metadata.c @@ -131,3 +131,17 @@ static __init int get_tdx_sys_info(struct tdx_sys_info= *sysinfo) =20 return ret; } + +static __init int get_tdx_sys_info_ext(struct tdx_sys_info_ext *sysinfo_ex= t) +{ + int ret; + u64 val; + + ret =3D read_sys_metadata_field(0x3100000000000001, &val); + if (ret) + return ret; + + sysinfo_ext->ext_required =3D val; + + return 0; +} --=20 2.25.1 From nobody Tue Sep 29 14:57:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.12]) (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 68895379C5A; Fri, 21 Aug 2026 03:29:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.12 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787282982; cv=none; b=sLk8SS8synyt8oqdeRAB+KohnNeko8TAYK3Q7BJtHuTUMtNhABIytNcGA85wDJT6aDLzzqM0pqyYLLc/kseZVElaE15juUQFUG23Ie+KVe1ZaIUF9SKiDvUFVWX4c7ac7gyI4uzv22AtAACAlOa2oXOv1YAgr6SYEVBhMD+PHlU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787282982; c=relaxed/simple; bh=p6kkjag7sbnyDiWJWN/yPpqzbtkf9ykV8qQAUhwAJd0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=uif7TuyeV18d8n8nYUYYOhdLn2CrXQQq0jdqgCszqCNaltIq/xHzEpQjJjvoqVwzlVNm3K+siu9fgHsQE7lXN1rJ9ArFZFdxnRlz0j5Egx5aDZNpF+C3vIBjZgU7g9kS+daoHonVO+1S7aWNmzG8a9gb4Nxto2Vkppp9idPohEk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=mcm0yxAj; arc=none smtp.client-ip=192.198.163.12 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="mcm0yxAj" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1787282980; x=1818818980; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=p6kkjag7sbnyDiWJWN/yPpqzbtkf9ykV8qQAUhwAJd0=; b=mcm0yxAjcjqWwqiJaZSGMoCe72geTmb4lVS0QlS9bLEJoRIzVw82VHG1 J8Yzm57c4YyCwJv/2vWYtDEON6ZWp0aKXna7hkr0nvZZ961Dqcd3o1N7/ r/JRzAcYFY/C+0lVvxI3+ZrqaWwQiIjXjn7BiueUCOCo0Tmf5WnP3ec4W jjhwC0czPfEPkcSxdJ5g3lxdcpejFXTGtl01XdKdRtKIrz8kceWnNGTdp nZWWswEvijiKMeMy/roL1q+Ucs0s7VOXIp12ILfLF/pcZRfh6vNikoCrI 8O3Rk6uhi9FspyOl92kMWNWLAL5+VU5HlfDazYLvBUMbxNCgAXEforzu8 w==; X-CSE-ConnectionGUID: XN/djrIvQ+ucnuOthJTaZQ== X-CSE-MsgGUID: RozNxvmNREWLnHpmM6v5AQ== X-IronPort-AV: E=McAfee;i="6800,10657,11881"; a="91640238" X-IronPort-AV: E=Sophos;i="6.25,234,1779174000"; d="scan'208";a="91640238" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Aug 2026 20:29:40 -0700 X-CSE-ConnectionGUID: E+bUqs3hTbWu2DzFHGdsKQ== X-CSE-MsgGUID: E0ZNPXfFQbWI0IHSBLkr1Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.25,234,1779174000"; d="scan'208";a="264451605" Received: from yilunxu-optiplex-7050.sh.intel.com ([10.239.47.46]) by orviesa006.jf.intel.com with ESMTP; 20 Aug 2026 20:29:36 -0700 From: Xu Yilun To: x86@kernel.org, linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org Cc: kas@kernel.org, rick.p.edgecombe@intel.com, yilun.xu@linux.intel.com, yilun.xu@intel.com, xiaoyao.li@intel.com, sohil.mehta@intel.com, adrian.hunter@intel.com, kishen.maloor@intel.com, tony.lindgren@linux.intel.com, peter.fang@intel.com, baolu.lu@linux.intel.com, zhenzhong.duan@intel.com, chao.gao@intel.com, artem.bityutskiy@linux.intel.com, kvm@vger.kernel.org Subject: [PATCH 4/6] x86/virt/tdx: Add extra memory to TDX module for the extensions Date: Fri, 21 Aug 2026 11:29:18 +0800 Message-Id: <20260821032920.256225-5-yilun.xu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20260821032920.256225-1-yilun.xu@linux.intel.com> References: <20260821032920.256225-1-yilun.xu@linux.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 extensions need memory for their own internal state and data to serve SEAMCALL leaves. The TDX architecture implements the extensions in such a way that they use the memory outside of SEAM range, so the kernel should add the memory upfront at initialization time. Introduce a new memory adding process backed by a new SEAMCALL leaf TDH.EXT.MEM.ADD. The kernel queries TDX module how much memory needed, allocates it, add it to the module, and never gets it back. The TDX module accepts the memory in the form of a PFN array. This array is passed via a single 64-bit SEAMCALL leaf parameter, which encodes two values: the PFN of the container page holding the array, and the number of entries in the array. Create a helper to encode this format and name it after the TDX module term: HPA_LIST_INFO. TDX module extensions consume tens of megabytes memory that will never be returned to host. Use contiguous page allocation to isolate these large blocks entirely, avoiding permanent memory fragmentation and buddy allocator efficiency loss. Print the allocation amount on TDX module extensions initialization for visibility. Signed-off-by: Xu Yilun --- v1: - Fix return value for SEAMCALL helpers (Chao) - Print SEAMCALL error code for SEAMCALL helpers (Xiaoyao) - Rename local vars to make the ext memory adding loop clear (Rick) - Remove input parameters for tdx_ext_mem_setup() (Kevin) - Add a Macro for tdh_hpa_list size. - Change the SEAMALL helper parameter type, struct page *hpa_list =3D> struct tdx_hpa_list *hpa_list - changelog & code comments --- arch/x86/include/asm/tdx_global_metadata.h | 1 + arch/x86/virt/vmx/tdx/tdx.h | 1 + arch/x86/virt/vmx/tdx/tdx.c | 118 +++++++++++++++++++- arch/x86/virt/vmx/tdx/tdx_global_metadata.c | 6 + 4 files changed, 123 insertions(+), 3 deletions(-) diff --git a/arch/x86/include/asm/tdx_global_metadata.h b/arch/x86/include/= asm/tdx_global_metadata.h index fe3fe91de71f..43b8761c0854 100644 --- a/arch/x86/include/asm/tdx_global_metadata.h +++ b/arch/x86/include/asm/tdx_global_metadata.h @@ -45,6 +45,7 @@ struct tdx_sys_info_handoff { }; =20 struct tdx_sys_info_ext { + u32 memory_pool_required_pages; bool ext_required; }; =20 diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h index 63e3acfb5d0c..52888424fe7d 100644 --- a/arch/x86/virt/vmx/tdx/tdx.h +++ b/arch/x86/virt/vmx/tdx/tdx.h @@ -48,6 +48,7 @@ #define TDH_SYS_CONFIG 45 #define TDH_SYS_SHUTDOWN 52 #define TDH_SYS_UPDATE 53 +#define TDH_EXT_MEM_ADD 61 #define TDH_SYS_DISABLE 69 =20 /* TDX page types */ diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index a0c370894c0b..8c2fdaf0b8c0 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -1175,6 +1175,120 @@ static __init int init_tdmrs(struct tdmr_info_list = *tdmr_list) return 0; } =20 +#define TDX_HPA_LIST_MAX_NR_PAGES (PAGE_SIZE / sizeof(u64)) + +struct tdx_hpa_list { + u64 phys[TDX_HPA_LIST_MAX_NR_PAGES]; +}; + +static_assert(sizeof(struct tdx_hpa_list) =3D=3D PAGE_SIZE); + +#define HPA_LIST_INFO_FIRST_ENTRY GENMASK_U64(11, 3) +#define HPA_LIST_INFO_PFN GENMASK_U64(51, 12) +#define HPA_LIST_INFO_LAST_ENTRY GENMASK_U64(63, 55) + +static __init u64 to_hpa_list_info(struct tdx_hpa_list *hpa_list, + unsigned int nr_pages) +{ + return FIELD_PREP(HPA_LIST_INFO_FIRST_ENTRY, 0) | + FIELD_PREP(HPA_LIST_INFO_PFN, PFN_DOWN(__pa(hpa_list))) | + FIELD_PREP(HPA_LIST_INFO_LAST_ENTRY, nr_pages - 1); +} + +static __init int tdx_ext_mem_add(struct tdx_hpa_list *hpa_list, + unsigned int nr_pages) +{ + struct tdx_module_args args =3D { + .rcx =3D to_hpa_list_info(hpa_list, nr_pages), + }; + u64 ret; + + do { + /* + * The TDX module overwrites RCX to track progress when this + * SEAMCALL leaf is interrupted. Use seamcall_ret() to save and + * pass the updated value back on retry. + */ + ret =3D seamcall_ret(TDH_EXT_MEM_ADD, &args); + } while (ret =3D=3D TDX_INTERRUPTED_RESUMABLE); + + if (ret !=3D TDX_SUCCESS) { + pr_err("TDH.EXT.MEM.ADD failed: 0x%016llx\n", ret); + return -EIO; + } + + return 0; +} + +static __init int tdx_ext_mem_setup(void) +{ + unsigned int required_pages =3D tdx_sysinfo.ext.memory_pool_required_page= s; + struct tdx_hpa_list *hpa_list; + unsigned int added_pages; + struct page *page; + int ret; + + /* + * TDX module uses the metadata memory_pool_required_pages to indicate + * how much memory is still needed. This value decreases each time + * memory is added via TDH.EXT.MEM.ADD. + * + * On first time initialization, a value of 0 before any memory is + * added is unusual. But host makes no assumptions. Skip the memory + * setup and let subsequent steps catch any actual errors. + */ + if (!required_pages) + return 0; + + hpa_list =3D kzalloc_obj(*hpa_list); + if (!hpa_list) + return -ENOMEM; + + page =3D alloc_contig_pages(required_pages, GFP_KERNEL, numa_mem_id(), + &node_online_map); + if (!page) { + ret =3D -ENOMEM; + goto out_free_hpa_list; + } + + added_pages =3D 0; + while (added_pages < required_pages) { + unsigned int chunk_pages =3D min(required_pages - added_pages, + TDX_HPA_LIST_MAX_NR_PAGES); + struct page *chunk =3D page + added_pages; + unsigned int i; + + for (i =3D 0; i < chunk_pages; i++) + hpa_list->phys[i] =3D page_to_phys(chunk + i); + + ret =3D tdx_ext_mem_add(hpa_list, chunk_pages); + if (ret) { + /* + * This SEAMCALL leaf shouldn't fail, and if it does, + * things are broken enough that complex error handling + * isn't worth it. Intentionally leak all pages, + * including un-added pages. + */ + WARN(1, "Fatal: TDX module rejected memory for extensions, stranded all= pages\n"); + break; + } + + added_pages +=3D chunk_pages; + } + + /* + * Memory for TDX module extensions is never reclaimed and can be tens + * of megabytes. Print the amount so users know the cost. + */ + pr_info("%lu KB consumed for TDX module extensions\n", + required_pages * PAGE_SIZE / 1024); + +out_free_hpa_list: + kfree(hpa_list); + + return ret; +} + static __init int init_tdx_module_extensions(void) { int ret; @@ -1194,9 +1308,7 @@ static __init int init_tdx_module_extensions(void) if (!tdx_sysinfo.ext.ext_required) return 0; =20 - /* TODO: add the extensions enabling steps here */ - - return 0; + return tdx_ext_mem_setup(); } =20 static __init int init_tdx_module(void) diff --git a/arch/x86/virt/vmx/tdx/tdx_global_metadata.c b/arch/x86/virt/vm= x/tdx/tdx_global_metadata.c index b9e1c011a990..720cdaf76492 100644 --- a/arch/x86/virt/vmx/tdx/tdx_global_metadata.c +++ b/arch/x86/virt/vmx/tdx/tdx_global_metadata.c @@ -137,6 +137,12 @@ static __init int get_tdx_sys_info_ext(struct tdx_sys_= info_ext *sysinfo_ext) int ret; u64 val; =20 + ret =3D read_sys_metadata_field(0x3100000200000000, &val); + if (ret) + return ret; + + sysinfo_ext->memory_pool_required_pages =3D val; + ret =3D read_sys_metadata_field(0x3100000000000001, &val); if (ret) return ret; --=20 2.25.1 From nobody Tue Sep 29 14:57:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.12]) (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 1D3CE37B016; Fri, 21 Aug 2026 03:29:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.12 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787282985; cv=none; b=NVP2pWYo0BwqkFeC0HtTHaDOtmTJ2sFEvZ6DL+dH9UJ/sjAdTiiHPjpWNzB/XfdRxOAnREEN6V+Ee7rDkgjzfkT9CefxfRm95Dv87ewWCXD8o9ACfc9xYrX1bzPHJY5bc6o2SwzwZ+DdvLhDH2Ao6uryOqC00flZ33/g6e5/Qlw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787282985; c=relaxed/simple; bh=l/irF7qWRI3dA5cb2ldWh+ucpLVHW7zJqzz459U2Jlg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=dOdJ+y/OAEYCWvxrdHI00yiMfsMiuxZwOmQyNhYoxnJCg+SFhM74BDQy5SgWRzc8+OkGVMbNVEhA26X1RxVGgP/MYq8TSYzY7zQH6z1UnSOM+2Ky/1v4XE8gcIkEM3Irl92Ec2z6RrGeEPtbOaEccUVs4lUDrXImzpDSQMo5CQ8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=JwLOuY7U; arc=none smtp.client-ip=192.198.163.12 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="JwLOuY7U" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1787282984; x=1818818984; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=l/irF7qWRI3dA5cb2ldWh+ucpLVHW7zJqzz459U2Jlg=; b=JwLOuY7UFjB8hEXKtX1sY3AwpmJLzrSwSqnTLlfUEWIqVb7F26xxl1qe /l0ajtcqGvi9uIXwzjBGM69D1yZ+TAhCyCH7w2IWr/b5w/gcUHrs1ZcJ9 ejnUmGEsexqGvtnpF0wA5SqrK82V6Na6fXRpkqJ8S23g8yBH6zU0bhA7k VTBzepkiWiqN8RnC6qmmyJJHefQgf8zgvzvlNJJaIKZEfRYC3yU8/gpEh ZUbQbetu2u7dhc5dnqORMUH1Nv6Z2+xzSrk1QbZUI0IsJQjgKAF39fWQE CGgrrm7j2uzB2lG564Jyss/BdKy9qja/o3Rw4zVTYrLCnrews2Xr+NwD5 Q==; X-CSE-ConnectionGUID: dhXjCZytSJSWgMmxGVrJKA== X-CSE-MsgGUID: mLKuupcgTnSxCeGEKnGAbw== X-IronPort-AV: E=McAfee;i="6800,10657,11881"; a="91640243" X-IronPort-AV: E=Sophos;i="6.25,234,1779174000"; d="scan'208";a="91640243" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Aug 2026 20:29:44 -0700 X-CSE-ConnectionGUID: CtKNlnNdTSiTYB2EO/BDQQ== X-CSE-MsgGUID: o30ALhBSSYGroWvagdFF5A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.25,234,1779174000"; d="scan'208";a="264451610" Received: from yilunxu-optiplex-7050.sh.intel.com ([10.239.47.46]) by orviesa006.jf.intel.com with ESMTP; 20 Aug 2026 20:29:40 -0700 From: Xu Yilun To: x86@kernel.org, linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org Cc: kas@kernel.org, rick.p.edgecombe@intel.com, yilun.xu@linux.intel.com, yilun.xu@intel.com, xiaoyao.li@intel.com, sohil.mehta@intel.com, adrian.hunter@intel.com, kishen.maloor@intel.com, tony.lindgren@linux.intel.com, peter.fang@intel.com, baolu.lu@linux.intel.com, zhenzhong.duan@intel.com, chao.gao@intel.com, artem.bityutskiy@linux.intel.com, kvm@vger.kernel.org Subject: [PATCH 5/6] x86/virt/tdx: Make TDX module initialize the extensions Date: Fri, 21 Aug 2026 11:29:19 +0800 Message-Id: <20260821032920.256225-6-yilun.xu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20260821032920.256225-1-yilun.xu@linux.intel.com> References: <20260821032920.256225-1-yilun.xu@linux.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 extensions need memory for their own internal state and data to serve SEAMCALL leaves. Several add-on features depend on the extensions to execute their SEAMCALL leaves. After providing all required memory to the TDX module, initialize TDX module extensions via TDH.EXT.INIT, then those add-on features can use their SEAMCALL leaves normally. Signed-off-by: Xu Yilun Reviewed-by: Xiaoyao Li Reviewed-by: Tony Lindgren Reviewed-by: Adrian Hunter --- v1: - Fix return value for SEAMCALL helpers (Chao) - Print SEAMCALL error code for SEAMCALL helpers (Xiaoyao) - Changelog & code comments --- arch/x86/virt/vmx/tdx/tdx.h | 1 + arch/x86/virt/vmx/tdx/tdx.c | 23 ++++++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h index 52888424fe7d..1f43d2eb2345 100644 --- a/arch/x86/virt/vmx/tdx/tdx.h +++ b/arch/x86/virt/vmx/tdx/tdx.h @@ -48,6 +48,7 @@ #define TDH_SYS_CONFIG 45 #define TDH_SYS_SHUTDOWN 52 #define TDH_SYS_UPDATE 53 +#define TDH_EXT_INIT 60 #define TDH_EXT_MEM_ADD 61 #define TDH_SYS_DISABLE 69 =20 diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 8c2fdaf0b8c0..873b8393f32f 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -1289,6 +1289,23 @@ static __init int tdx_ext_mem_setup(void) return ret; } =20 +static __init int tdx_ext_init(void) +{ + struct tdx_module_args args =3D {}; + u64 ret; + + do { + ret =3D seamcall(TDH_EXT_INIT, &args); + } while (ret =3D=3D TDX_INTERRUPTED_RESUMABLE); + + if (ret !=3D TDX_SUCCESS) { + pr_err("TDH.EXT.INIT failed: 0x%016llx\n", ret); + return -EIO; + } + + return 0; +} + static __init int init_tdx_module_extensions(void) { int ret; @@ -1308,7 +1325,11 @@ static __init int init_tdx_module_extensions(void) if (!tdx_sysinfo.ext.ext_required) return 0; =20 - return tdx_ext_mem_setup(); + ret =3D tdx_ext_mem_setup(); + if (ret) + return ret; + + return tdx_ext_init(); } =20 static __init int init_tdx_module(void) --=20 2.25.1 From nobody Tue Sep 29 14:57:29 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.12]) (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 1E73437BE81; Fri, 21 Aug 2026 03:29:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.12 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787282989; cv=none; b=uywOz+Qf8eMH6giM4a2kim+VAp3w4bmuWE4nbDdHAwsEBoZRw2cLTODKK7AQTP+pBLKQYrX+9hE3mcI+7qshNYztooh/Kq9ShxhvBfZTO4SobUuxQNyEeNo5Ld7odn1dBuOLtbRrxYVmvoDP5mIHfEfRyEBowBt+kEefVgkXUH0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787282989; c=relaxed/simple; bh=fzUOMAIqwO0DVyi3x/N/fYS/A72QSG8Go1HWcQQ+AeQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=pd8OjdT/ooQtxPOlstf4yRQMbMYH8PFbVr7l9mEyVnnA6WApp6vujapsV8lOkeXdnpYWCu+UJBrLEYhwVhSdymANQe38vzUnu2j8lsxRgv0r2ttVXTmBqZTbx9/g1/WWY+BjkkBs1NZiVmyOKY1bq43t2VXNHGJG2I0w3mh16/E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=hlz8q1qm; arc=none smtp.client-ip=192.198.163.12 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="hlz8q1qm" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1787282988; x=1818818988; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=fzUOMAIqwO0DVyi3x/N/fYS/A72QSG8Go1HWcQQ+AeQ=; b=hlz8q1qmVkILA7/Xqrn9rmvljSxfK5yzfEjBGAh+jEKMU9wxq6Qrl+IH tJMjp50MZaU8G67KW3pDBWTqxvmEGMzjHlw2JeidqIh71wFniN+SHmW4X Nmntlyva6wpADwW794F6aO9oRAu6P7l/OGrkue0a5BnWhPk/PXgaNIIdd SsbpZizcX7SAyDjf4ccZ1kfG2uERANoR3BKMrA5M4jqsy4d+sYolwAR3o 1MHkBNPM1XzUzHAyiUR3jcXS2U2yxNrfWCgWWmGZVdBWGl82zKXm1JayM a4ThFa2gVMX3o1ivqrBaxo5SuyFXayI0fWsQrtvs6i9GCXMKLi5Xeo7/k Q==; X-CSE-ConnectionGUID: bwynWMNmSySkdQ67pdK9Ag== X-CSE-MsgGUID: 6qrG6ip3SWesBdildYcM4Q== X-IronPort-AV: E=McAfee;i="6800,10657,11881"; a="91640248" X-IronPort-AV: E=Sophos;i="6.25,234,1779174000"; d="scan'208";a="91640248" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Aug 2026 20:29:48 -0700 X-CSE-ConnectionGUID: xvuB3YbHTviLia6tARPfSQ== X-CSE-MsgGUID: iZHs2rGVTYWm7r4Vac2riA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.25,234,1779174000"; d="scan'208";a="264451614" Received: from yilunxu-optiplex-7050.sh.intel.com ([10.239.47.46]) by orviesa006.jf.intel.com with ESMTP; 20 Aug 2026 20:29:44 -0700 From: Xu Yilun To: x86@kernel.org, linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org Cc: kas@kernel.org, rick.p.edgecombe@intel.com, yilun.xu@linux.intel.com, yilun.xu@intel.com, xiaoyao.li@intel.com, sohil.mehta@intel.com, adrian.hunter@intel.com, kishen.maloor@intel.com, tony.lindgren@linux.intel.com, peter.fang@intel.com, baolu.lu@linux.intel.com, zhenzhong.duan@intel.com, chao.gao@intel.com, artem.bityutskiy@linux.intel.com, kvm@vger.kernel.org Subject: [PATCH 6/6] x86/virt/tdx: Re-initialize the extensions on runtime TDX module update Date: Fri, 21 Aug 2026 11:29:20 +0800 Message-Id: <20260821032920.256225-7-yilun.xu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20260821032920.256225-1-yilun.xu@linux.intel.com> References: <20260821032920.256225-1-yilun.xu@linux.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" Runtime TDX module update introduces a mechanism to update the module firmware while preserving and restoring TDX operations. As part of the restoration process, the host must re-initialize the extensions to restore their functionality. Linux runs the updates in stop_machine() context, which prevents memory allocation. This introduces a hard restriction that the updated TDX environment must not consume more memory for the extensions. The impact of the memory allocation restriction can be mitigated by another requirement. Runtime updates should keep the add-on features unchanged across updates, so that existing TDX users can continue to operate without disruption. This requirement minimizes the chance of increased memory demand. As a result, the restriction only affects the compatibility rule for choosing the update image. To adhere to these requirements, the post-update initialization for the extensions can be simplified as: - Check if the extensions were originally initialized during boot up. If not, skip the re-initialization. - Assume no more memory needed, skip the memory adding step. - Re-initialize the extensions via TDH.EXT.INIT. The SEAMCALL leaf will fail if the updated module requires more memory, or if it drops the extensions initialization entirely, which indicates the update image is not compatible. Signed-off-by: Xu Yilun --- v1: - Don't update the extensions metadata any more, only check the metadata originated at boot time. - Remove memory_pool_required_pages check, let TDH.EXT.INIT fail if more memory required. - Changelog & code comments --- arch/x86/virt/vmx/tdx/tdx.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 873b8393f32f..1ca3996f32dc 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -1289,7 +1289,7 @@ static __init int tdx_ext_mem_setup(void) return ret; } =20 -static __init int tdx_ext_init(void) +static int tdx_ext_init(void) { struct tdx_module_args args =3D {}; u64 ret; @@ -1332,6 +1332,19 @@ static __init int init_tdx_module_extensions(void) return tdx_ext_init(); } =20 +/* + * Don't update the extensions metadata, just follow the requirement origi= nated + * during TDX module initialization. Let the extensions re-initialization = fail + * if more memory is needed, or if ext_required is dropped after updates. + */ +static int update_tdx_module_extensions(void) +{ + if (!tdx_sysinfo.ext.ext_required) + return 0; + + return tdx_ext_init(); +} + static __init int init_tdx_module(void) { int ret; @@ -1532,6 +1545,10 @@ int tdx_module_run_update(void) */ WARN_ON_ONCE(ret); =20 + ret =3D update_tdx_module_extensions(); + if (ret) + return ret; + tdx_module_state.initialized =3D true; return 0; } --=20 2.25.1