Re: [PATCH v2 02/17] x86/virt/tdx: Configure add-on features on TDX module init and update

Xiaoyao Li <[email protected]> Fri, 24 Jul 2026 16:15:21 +0800
Newsgroups dev.linux.lists.linux-coco,org.kernel.vger.kvm,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
On 6/18/2026 4:13 PM, Xu Yilun wrote:
> In addition to basic TDX functionalities, TDX module provides add-on
> features that can be progressively enabled as the kernel supports them.

"add-on features" looks like a new term introduced by this sereis for 
TDX. So what is add-on features? all the features defined in 
TDX_FEATURE0/1? Or only the features needs to be explicitly enabled by 
R9 and R10 of TDH.SYS.CONFIG? ...

> The kernel should explicitly configure these features at boot or
> post-update initialization time. 

... So the answer is the latter. Then why only these bits are add-on 
features while the rest in TDX_FEATURES01 are not?

btw, s/should/needs/ is better?

> Configuring an add-on feature, such as
> TDX Quoting, that uses extension SEAMCALLs is the prerequisite for
> initializing TDX module extensions. 

Though the statement is right, it leads to the impression that the 
reason we are configuring the add-on feature is to initialize the TDX 
module extensions.

However, the truth is kenrel wants to enable/use an add-on feature and 
the add-on feature requires the functionalities provided by some TDX 
module extension. So kernel needs to enable the TDX module extensions.

> TDX Quoting is the target feature to
> enable but defer it for now until full kernel support is in place.
> 
> TDX module extends TDH.SYS.CONFIG and TDH.SYS.UPDATE with new bitmap
> input parameters to specify which add-on features to configure. The
> bitmap uses the same definitions as TDX_FEATURES0.
> 
> For runtime update, Linux applies a policy that no newer features should
> be added after update to avoid disrupting live TDX operations. To adhere
> to this, TDH.SYS.UPDATE must configure the same features as the
> TDH.SYS.CONFIG. Record the kernel required add-on feature bitmap in a
> global var so that both phases can use it.
> 
> TDX module advances the version of TDH.SYS.CONFIG and TDH.SYS.UPDATE for
> the change, so use the latest version (v1) for add-on feature enabling.
> But supporting existing modules which only support v0 is still necessary
> until they are deprecated. In fact, it is unlikely that TDH.SYS.CONFIG
> ever needs to change again and the code would stay in v1. So there is
> little value in worrying about deprecating v0 to save a couple lines of
> code in 5-7 years when these original TDX platforms sunset.
> 
> Signed-off-by: Xu Yilun <[email protected]>
> ---
>   arch/x86/virt/vmx/tdx/tdx.h |  6 ++++--
>   arch/x86/virt/vmx/tdx/tdx.c | 28 ++++++++++++++++++++++++++--
>   2 files changed, 30 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h
> index fbb520704662..a47e872480c7 100644
> --- a/arch/x86/virt/vmx/tdx/tdx.h
> +++ b/arch/x86/virt/vmx/tdx/tdx.h
> @@ -58,9 +58,11 @@
>   #define TDH_PHYMEM_CACHE_WB		40
>   #define TDH_PHYMEM_PAGE_WBINVD		41
>   #define TDH_VP_WR			43
> -#define TDH_SYS_CONFIG			45
> +#define TDH_SYS_CONFIG_V0		45
> +#define TDH_SYS_CONFIG			SEAMCALL_LEAF_VER(TDH_SYS_CONFIG_V0, 1)
>   #define TDH_SYS_SHUTDOWN		52
> -#define TDH_SYS_UPDATE			53
> +#define TDH_SYS_UPDATE_V0		53
> +#define TDH_SYS_UPDATE			SEAMCALL_LEAF_VER(TDH_SYS_UPDATE_V0, 1)
>   #define TDH_SYS_DISABLE			69
>   
>   /* TDX page types */
> diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
> index 2a03152796e6..92305b5ea90d 100644
> --- a/arch/x86/virt/vmx/tdx/tdx.c
> +++ b/arch/x86/virt/vmx/tdx/tdx.c
> @@ -57,6 +57,7 @@ static struct tdx_module_state tdx_module_state;
>   static u32 tdx_global_keyid __ro_after_init;
>   static u32 tdx_guest_keyid_start __ro_after_init;
>   static u32 tdx_nr_guest_keyids __ro_after_init;
> +static u64 tdx_addon_feature0 __ro_after_init;
>   
>   static DEFINE_IDA(tdx_guest_keyid_pool);
>   
> @@ -1004,9 +1005,18 @@ static __init int construct_tdmrs(struct list_head *tmb_list,
>   	return ret;
>   }
>   
> +static __init void set_tdx_addon_features(void)
> +{
> +	/*
> +	 * To add DICE-based TDX Quoting feature bit in tdx_addon_feature0 when
> +	 * kernel is ready.
> +	 */
> +}
> +
>   static __init int config_tdx_module(struct tdmr_info_list *tdmr_list,
>   				    u64 global_keyid)
>   {
> +	u64 seamcall_fn = TDH_SYS_CONFIG_V0;
>   	struct tdx_module_args args = {};
>   	u64 *tdmr_pa_array;
>   	size_t array_sz;
> @@ -1032,7 +1042,15 @@ static __init int config_tdx_module(struct tdmr_info_list *tdmr_list,
>   	args.rcx = __pa(tdmr_pa_array);
>   	args.rdx = tdmr_list->nr_consumed_tdmrs;
>   	args.r8 = global_keyid;
> -	ret = seamcall_prerr(TDH_SYS_CONFIG, &args);
> +
> +	set_tdx_addon_features();

Maybe move the set_tdx_addon_features() out of config_tdx_module()? how 
about putting it after check_features(). config_tdx_module() looks like 
just a wrapper to invoke TDH.SYS.CONFIG, while the params of it are 
determined outside of it.

Just my feeling.

> +
> +	if (tdx_addon_feature0) {
> +		args.r9 = tdx_addon_feature0;
> +		seamcall_fn = TDH_SYS_CONFIG;
> +	}
> +
> +	ret = seamcall_prerr(seamcall_fn, &args);
>   
>   	/* Free the array as it is not required anymore. */
>   	kfree(tdmr_pa_array);
> @@ -1314,10 +1332,16 @@ int tdx_module_shutdown(void)
>   
>   int tdx_module_run_update(void)
>   {
> +	u64 seamcall_fn = TDH_SYS_UPDATE_V0;
>   	struct tdx_module_args args = {};
>   	int ret;
>   
> -	ret = seamcall_prerr(TDH_SYS_UPDATE, &args);
> +	if (tdx_addon_feature0) {
> +		args.r9 = tdx_addon_feature0;
> +		seamcall_fn = TDH_SYS_UPDATE;
> +	}
> +
> +	ret = seamcall_prerr(seamcall_fn, &args);
>   	if (ret)
>   		return ret;
>