[PATCH v1 5/8] x86/virt/tdx: Convert td_conf reader

Chao Gao <[email protected]>
Newsgroups dev.linux.lists.linux-coco,org.kernel.vger.kvm,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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.