[PATCH v1 5/8] x86/virt/tdx: Convert td_conf reader
From: Chao Gao
Date: Tue Aug 04 2026 - 07:43:33 EST
From: Dave Hansen <dave@xxxxxxxx>
Convert the "TD Configuration" class to the table-driven reader.
This class has two parts:
- Six scalar fields (attributes_fixed{0,1}, xfam_fixed{0,1},
num_cpuid_config, max_vcpus_per_td) that fit straight into a
TD_SYSINFO_MAP table.
- Two arrays (cpuid_config_leaves[] and cpuid_config_values[][])
whose lengths come from num_cpuid_config and whose field IDs
are computed from a base announced by the spec:
field_id(leaves[i]) = MD_FIELD_ID_CPUID_CONFIG_LEAVES + i
field_id(values[i][j]) = MD_FIELD_ID_CPUID_CONFIG_VALUES + i*2 + j
The arrays can't be expressed as a static table, so read them
explicitly after the scalar block has populated num_cpuid_config.
Bounds-check num_cpuid_config against the C array sizes before
indexing, matching the prior generated code.
Drop the corresponding function from the auto-generated file.
Assisted-by: Claude:claude-opus-5
Not-yet-signed-off-by: Dave Hansen <dave@xxxxxxxx>
Signed-off-by: Chao Gao <chao.gao@xxxxxxxxx>
---
arch/x86/virt/vmx/tdx/tdx.c | 56 +++++++++++++++++++++
arch/x86/virt/vmx/tdx/tdx_global_metadata.c | 33 ------------
2 files changed, 56 insertions(+), 33 deletions(-)
diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
index 89055afeef68..98534e702144 100644
--- a/arch/x86/virt/vmx/tdx/tdx.c
+++ b/arch/x86/virt/vmx/tdx/tdx.c
@@ -471,6 +471,62 @@ static int get_tdx_sys_info_handoff(struct tdx_sys_info_handoff *sysinfo_handoff
sysinfo_handoff);
}
+#define MAP_TD_CONF(_field_id, _member) \
+ TD_SYSINFO_MAP(_field_id, tdx_sys_info_td_conf, _member)
+
+/*
+ * Scalar fields of the "TD Configuration" class. num_cpuid_config
+ * must be present here (and must be read before the CPUID arrays
+ * below) because it sizes them.
+ */
+static const struct tdx_sys_field td_conf_fields[] __initconst = {
+ MAP_TD_CONF(ATTRIBUTES_FIXED0, attributes_fixed0),
+ MAP_TD_CONF(ATTRIBUTES_FIXED1, attributes_fixed1),
+ MAP_TD_CONF(XFAM_FIXED0, xfam_fixed0),
+ MAP_TD_CONF(XFAM_FIXED1, xfam_fixed1),
+ MAP_TD_CONF(NUM_CPUID_CONFIG, num_cpuid_config),
+ MAP_TD_CONF(MAX_VCPUS_PER_TD, max_vcpus_per_td),
+};
+
+static __init int get_tdx_sys_info_td_conf(struct tdx_sys_info_td_conf *td_conf)
+{
+ int ret, i, j;
+
+ ret = read_sys_metadata_table(td_conf_fields,
+ ARRAY_SIZE(td_conf_fields),
+ td_conf);
+ if (ret)
+ return ret;
+
+ /*
+ * The configurable-CPUID arrays are sized at runtime by
+ * num_cpuid_config, so they can't be expressed in a static
+ * TD_SYSINFO_MAP table. Their field IDs are contiguous from
+ * the bases announced by the spec.
+ */
+ if (td_conf->num_cpuid_config > ARRAY_SIZE(td_conf->cpuid_config_leaves) ||
+ td_conf->num_cpuid_config > ARRAY_SIZE(td_conf->cpuid_config_values))
+ return -EINVAL;
+
+ for (i = 0; i < td_conf->num_cpuid_config; i++) {
+ ret = read_sys_metadata_field(MD_FIELD_ID_CPUID_CONFIG_LEAVES + i,
+ &td_conf->cpuid_config_leaves[i]);
+ if (ret)
+ return ret;
+
+ for (j = 0; j < 2; j++) {
+ u64 fid = MD_FIELD_ID_CPUID_CONFIG_VALUES + i * 2 + j;
+
+ ret = read_sys_metadata_field(fid,
+ &td_conf->cpuid_config_values[i][j]);
+ if (ret)
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
#include "tdx_global_metadata.c"
static __init int check_features(struct tdx_sys_info *sysinfo)
diff --git a/arch/x86/virt/vmx/tdx/tdx_global_metadata.c b/arch/x86/virt/vmx/tdx/tdx_global_metadata.c
index 0c2cc99f1af1..4d673cac0976 100644
--- a/arch/x86/virt/vmx/tdx/tdx_global_metadata.c
+++ b/arch/x86/virt/vmx/tdx/tdx_global_metadata.c
@@ -7,39 +7,6 @@
* Include this file to other C file instead.
*/
-static __init 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 __init int get_tdx_sys_info(struct tdx_sys_info *sysinfo)
{
int ret = 0;
--
2.52.0