[PATCH v1 5/8] x86/virt/tdx: Convert td_conf reader
Chao Gao <[email protected]> Tue, 4 Aug 2026 04:29:33 -0700
| Newsgroups | org.kernel.vger.kvm,dev.linux.lists.linux-coco,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
From: Dave Hansen <[email protected]> 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 <[email protected]> Signed-off-by: Chao Gao <[email protected]> --- 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