Re: [PATCH v4 1/6] x86/virt/tdx: Move TDH.SYS.CONFIG operations into a wrapper

From: Xu Yilun

Date: Wed Oct 14 2026 - 23:35:16 EST


On Wed, Oct 14, 2026 at 08:59:32AM -0700, Dave Hansen wrote:
> On 10/13/26 08:28, Xu Yilun wrote:
> > SEAMCALL wrappers are introduced to avoid broad SEAMCALL access by
> > exposing only a selection of SEAMCALL leafs, but also to abstract the
> > SEAMCALL register ABIs. The abstraction improves readability and reuse
> > for SEAMCALL leafs that are called multiple times.
> >
> > Some SEAMCALL leafs are not explicitly wrapped because the level of TDX
> > ABI details needed to perform the call is low enough to flow well with
> > the calling code.
> >
> > For some of the currently unwrapped SEAMCALL leafs, the TDX architecture
> > has evolved the ABI to introduce new leaf versions. The host can select
> > the version to call based on what is supported by the loaded TDX module.
> > When future kernel implements this version selection, more ABI details
> > will leak into the surrounding caller code, which decreases the
> > readability of the caller logic. To keep the ABI details contained, move
> > the SEAMCALL leaf that will need version selection into a wrapper.
> >
> > When defining the wrapper, the cleanest separation would be to have
> > kernel data types for the SEAMCALL wrapper arguments, and have them
> > marshaled into SEAMCALL leaf ABI types (often u64s) inside the wrapper.
> > This works for many SEAMCALL leafs but becomes cumbersome when the
> > register ABI type is a physical address which points to a buffer for an
> > in-memory ABI. If the SEAMCALL wrapper only accepts kernel data types,
> > it may need duplicate buffer allocation and copies to match the
> > in-memory ABI. Another solution is to define a named helper structure
> > that mirrors the in-memory ABI, populate it in a separate flow, then
> > pass it to the SEAMCALL wrapper. struct seamldr_params is an existing
> > example of this pattern.
> >
> > TDH.SYS.CONFIG requires a list of TDMR information in the form of a PA
> > array. The PA array is the in-memory ABI. Create a structure for the PA
> > array, use it as the argument when creating the wrapper for
> > TDH.SYS.CONFIG.
> >
> > For readability, adjust a bit of the existing PA array size calculation:
> > use the new PA array structure's element type instead of hardcoding u64.
> >
> > AI was used under supervision to review code and workshop logs.
>
> I'm wondering if this is a case of AI gone wild. There's a *LOT* of info
> there, but I'm not seeing the thing I really want to see: Why is it
> worth creating this helper _now_?

The leaf version of TDH.SYS.CONFIG will be selected based on what
features are supported by the loaded TDX module. We think this is a
lower level knowledge than the surrounding code. So does the existing
r8 tweak for DPAMT.

We have r8 tweak now, and in next patch, we will set "leaf version=1" as
a second case. So we think it's time to make a lower level abstraction
for these selection logic.

Some early discussion:
https://lore.kernel.org/lkml/2d138a8acb685385016e0bb0535e7213952e44e5.camel@xxxxxxxxx/

>
> Also, the move to tdmr_info_pa_array seems 100% orthogonal to me. Why is
> it here?

The change is motivated by the wrapping. Now the type of tdmr_pa_array
is u64 *, which is a local detail of config_tdx_module(). Once we have a
wrapper, it would look like:

int tdx_sys_config(u64 *tdmr_pa_array, unsigned int nr_tdmr_pa,
u64 global_keyid)

"u64 *" would become a vague argument type.

Is it better to split the wrapper & the new struct into 2 patches, the
new struct first, then the wrapper?