Files
linux/arch/x86/virt/vmx/tdx/tdx_global_metadata.c
Kai Huang 4caf32daf0 x86/virt/tdx: Read essential global metadata for KVM
KVM needs two classes of global metadata to create and run TDX guests:

 - "TD Control Structures"
 - "TD Configurability"

The first class contains the sizes of TDX guest per-VM and per-vCPU
control structures.  KVM will need to use them to allocate enough space
for those control structures.

The second class contains info which reports things like which features
are configurable to TDX guest etc.  KVM will need to use them to
properly configure TDX guests.

Read them for KVM TDX to use.

The code change is auto-generated by re-running the script in [1] after
uncommenting the "td_conf" and "td_ctrl" part to regenerate the
tdx_global_metadata.{hc} and update them to the existing ones in the
kernel.

  #python tdx.py global_metadata.json tdx_global_metadata.h \
	tdx_global_metadata.c

The 'global_metadata.json' can be fetched from [2].

Note that as of this writing, the JSON file only allows a maximum of 32
CPUID entries.  While this is enough for current contents of the CPUID
leaves, there were plans to change the JSON per TDX module release which
would change the ABI and potentially prevent future versions of the TDX
module from working with older kernels.

While discussions are ongoing with the TDX module team on what exactly
constitutes an ABI breakage, in the meantime the TDX module team has
agreed to not increase the number of CPUID entries beyond 128 without
an opt in.  Therefore the file was tweaked by hand to change the maximum
number of CPUID_CONFIGs.

Link: https://lore.kernel.org/kvm/0853b155ec9aac09c594caa60914ed6ea4dc0a71.camel@intel.com/ [1]
Link: https://cdrdv2.intel.com/v1/dl/getContent/795381 [2]
Signed-off-by: Kai Huang <kai.huang@intel.com>
Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
Message-ID: <20241030190039.77971-4-rick.p.edgecombe@intel.com>
Acked-by: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-03-14 14:20:49 -04:00

99 lines
3.4 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Automatically generated functions to read TDX global metadata.
*
* This file doesn't compile on its own as it lacks of inclusion
* of SEAMCALL wrapper primitive which reads global metadata.
* Include this file to other C file instead.
*/
static int get_tdx_sys_info_features(struct tdx_sys_info_features *sysinfo_features)
{
int ret = 0;
u64 val;
if (!ret && !(ret = read_sys_metadata_field(0x0A00000300000008, &val)))
sysinfo_features->tdx_features0 = val;
return ret;
}
static int get_tdx_sys_info_tdmr(struct tdx_sys_info_tdmr *sysinfo_tdmr)
{
int ret = 0;
u64 val;
if (!ret && !(ret = read_sys_metadata_field(0x9100000100000008, &val)))
sysinfo_tdmr->max_tdmrs = val;
if (!ret && !(ret = read_sys_metadata_field(0x9100000100000009, &val)))
sysinfo_tdmr->max_reserved_per_tdmr = val;
if (!ret && !(ret = read_sys_metadata_field(0x9100000100000010, &val)))
sysinfo_tdmr->pamt_4k_entry_size = val;
if (!ret && !(ret = read_sys_metadata_field(0x9100000100000011, &val)))
sysinfo_tdmr->pamt_2m_entry_size = val;
if (!ret && !(ret = read_sys_metadata_field(0x9100000100000012, &val)))
sysinfo_tdmr->pamt_1g_entry_size = val;
return ret;
}
static int get_tdx_sys_info_td_ctrl(struct tdx_sys_info_td_ctrl *sysinfo_td_ctrl)
{
int ret = 0;
u64 val;
if (!ret && !(ret = read_sys_metadata_field(0x9800000100000000, &val)))
sysinfo_td_ctrl->tdr_base_size = val;
if (!ret && !(ret = read_sys_metadata_field(0x9800000100000100, &val)))
sysinfo_td_ctrl->tdcs_base_size = val;
if (!ret && !(ret = read_sys_metadata_field(0x9800000100000200, &val)))
sysinfo_td_ctrl->tdvps_base_size = val;
return ret;
}
static int get_tdx_sys_info_td_conf(struct tdx_sys_info_td_conf *sysinfo_td_conf)
{
int ret = 0;
u64 val;
int i, j;
if (!ret && !(ret = read_sys_metadata_field(0x1900000300000000, &val)))
sysinfo_td_conf->attributes_fixed0 = val;
if (!ret && !(ret = read_sys_metadata_field(0x1900000300000001, &val)))
sysinfo_td_conf->attributes_fixed1 = val;
if (!ret && !(ret = read_sys_metadata_field(0x1900000300000002, &val)))
sysinfo_td_conf->xfam_fixed0 = val;
if (!ret && !(ret = read_sys_metadata_field(0x1900000300000003, &val)))
sysinfo_td_conf->xfam_fixed1 = val;
if (!ret && !(ret = read_sys_metadata_field(0x9900000100000004, &val)))
sysinfo_td_conf->num_cpuid_config = val;
if (!ret && !(ret = read_sys_metadata_field(0x9900000100000008, &val)))
sysinfo_td_conf->max_vcpus_per_td = val;
if (sysinfo_td_conf->num_cpuid_config > ARRAY_SIZE(sysinfo_td_conf->cpuid_config_leaves))
return -EINVAL;
for (i = 0; i < sysinfo_td_conf->num_cpuid_config; i++)
if (!ret && !(ret = read_sys_metadata_field(0x9900000300000400 + i, &val)))
sysinfo_td_conf->cpuid_config_leaves[i] = val;
if (sysinfo_td_conf->num_cpuid_config > ARRAY_SIZE(sysinfo_td_conf->cpuid_config_values))
return -EINVAL;
for (i = 0; i < sysinfo_td_conf->num_cpuid_config; i++)
for (j = 0; j < 2; j++)
if (!ret && !(ret = read_sys_metadata_field(0x9900000300000500 + i * 2 + j, &val)))
sysinfo_td_conf->cpuid_config_values[i][j] = val;
return ret;
}
static int get_tdx_sys_info(struct tdx_sys_info *sysinfo)
{
int ret = 0;
ret = ret ?: get_tdx_sys_info_features(&sysinfo->features);
ret = ret ?: get_tdx_sys_info_tdmr(&sysinfo->tdmr);
ret = ret ?: get_tdx_sys_info_td_ctrl(&sysinfo->td_ctrl);
ret = ret ?: get_tdx_sys_info_td_conf(&sysinfo->td_conf);
return ret;
}