All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chao Gao <chao.gao@intel.com>
To: linux-kernel@vger.kernel.org, linux-coco@lists.linux.dev,
	kvm@vger.kernel.org
Cc: rick.p.edgecombe@intel.com, kas@kernel.org,
	dave.hansen@linux.intel.com, chao.gao@intel.com
Subject: [PATCH v1 3/8] x86/virt/tdx: Add a table-driven TDX global metadata reader
Date: Tue,  4 Aug 2026 04:29:31 -0700	[thread overview]
Message-ID: <20260804112941.19894-4-chao.gao@intel.com> (raw)
In-Reply-To: <20260804112941.19894-1-chao.gao@intel.com>

From: Dave Hansen <dave@sr71.net>

The auto-generated tdx_global_metadata.c populates each member of
'struct tdx_sys_info' with a chain like

	if (!ret && !(ret = read_sys_metadata_field(0x..., &val)))
		sysinfo_xxx->member = val;

repeated once per field, with a bare hex literal for the field ID and an
implicit narrowing assignment.  Reading it requires the JSON file, and
reviewing any change to it requires the out-of-tree script.

Replace it with a small table-driven reader. Each table entry pairs
a named MD_FIELD_ID_* with the C member that holds its value:

	#define MAP_FEATURES(_field_id, _member)	\
		TD_SYSINFO_MAP(_field_id, tdx_sys_info_features, _member)

	static const struct tdx_sys_field features_fields[] __initconst = {
		MAP_FEATURES(TDX_FEATURES0,	tdx_features0),
	};

TD_SYSINFO_MAP() derives the destination offset and width from the
struct via offsetof()/sizeof_field().

Add read_sys_metadata_table() to walk such a table, reading each field
and populating the C struct.

Three things fall out of this table-driven reader, all of which matter now
that the code is hand-maintained rather than auto-generated:

  - The field-to-member pairing becomes data rather than code embedded
    in control flow.
  - The read logic exists once instead of once per field.
  - The width is recorded explicitly instead of being implied by a
    narrowing assignment.

Convert the 'features' class only, as an example. The remaining classes
follow in later patches.

Assisted-by: Claude:claude-opus-5
Not-yet-signed-off-by: Dave Hansen <dave@sr71.net>
Signed-off-by: Chao Gao <chao.gao@intel.com>
---
 arch/x86/virt/vmx/tdx/tdx.c                 | 60 +++++++++++++++++++++
 arch/x86/virt/vmx/tdx/tdx_global_metadata.c | 11 ----
 2 files changed, 60 insertions(+), 11 deletions(-)

diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
index 42df8ea464c4..fb21433e7851 100644
--- a/arch/x86/virt/vmx/tdx/tdx.c
+++ b/arch/x86/virt/vmx/tdx/tdx.c
@@ -347,6 +347,66 @@ static int read_sys_metadata_field(u64 field_id, u64 *data)
 	return 0;
 }
 
+/*
+ * Mapping between a TDX global metadata field and the C member that
+ * holds its value. Use TD_SYSINFO_MAP() to populate entries.
+ */
+struct tdx_sys_field {
+	u64 field_id;
+	u16 offset;
+	u8  size;
+};
+
+#define TD_SYSINFO_MAP(_field_id, _struct, _member)				\
+	{									\
+		.field_id = MD_FIELD_ID_##_field_id,				\
+		.offset   = offsetof(struct _struct, _member),			\
+		.size     = sizeof_field(struct _struct, _member),		\
+	}
+
+/*
+ * Walk a table of TDX global metadata fields, read each via TDH.SYS.RD,
+ * and store the result into the matching C member of *@base.
+ */
+static int read_sys_metadata_table(const struct tdx_sys_field *fields,
+				   int nr_fields, void *base)
+{
+	int i, ret;
+	u64 val;
+
+	for (i = 0; i < nr_fields; i++) {
+		const struct tdx_sys_field *f = &fields[i];
+
+		ret = read_sys_metadata_field(f->field_id, &val);
+		if (ret)
+			return ret;
+
+		switch (f->size) {
+		case 1: *(u8  *)(base + f->offset) = val; break;
+		case 2: *(u16 *)(base + f->offset) = val; break;
+		case 4: *(u32 *)(base + f->offset) = val; break;
+		case 8: *(u64 *)(base + f->offset) = val; break;
+		default:
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+#define MAP_FEATURES(_field_id, _member)	\
+	TD_SYSINFO_MAP(_field_id, tdx_sys_info_features, _member)
+
+static const struct tdx_sys_field features_fields[] __initconst = {
+	MAP_FEATURES(TDX_FEATURES0,	tdx_features0),
+};
+
+static __init int get_tdx_sys_info_features(struct tdx_sys_info_features *sysinfo_features)
+{
+	return read_sys_metadata_table(features_fields,
+				       ARRAY_SIZE(features_fields),
+				       sysinfo_features);
+}
+
 #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 e49c300f23d4..e69c655a91a0 100644
--- a/arch/x86/virt/vmx/tdx/tdx_global_metadata.c
+++ b/arch/x86/virt/vmx/tdx/tdx_global_metadata.c
@@ -22,17 +22,6 @@ static int get_tdx_sys_info_version(struct tdx_sys_info_version *sysinfo_version
 	return ret;
 }
 
-static __init 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 __init int get_tdx_sys_info_tdmr(struct tdx_sys_info_tdmr *sysinfo_tdmr)
 {
 	int ret = 0;
-- 
2.52.0


  parent reply	other threads:[~2026-08-04 11:31 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-04 11:29 [PATCH v1 0/8] TDX: Stop auto-generating the global metadata code Chao Gao
2026-08-04 11:29 ` [PATCH v1 1/8] x86/virt/tdx: Stop treating tdx_global_metadata.h as auto-generated Chao Gao
2026-08-04 23:43   ` Dave Hansen
2026-08-05 12:06     ` Chao Gao
2026-08-05 15:26       ` Dave Hansen
2026-08-04 11:29 ` [PATCH v1 2/8] x86/virt/tdx: Name the TDX module global metadata field IDs Chao Gao
2026-08-04 23:52   ` Dave Hansen
2026-08-05 12:45     ` Chao Gao
2026-08-05 17:10   ` Edgecombe, Rick P
2026-08-10  6:35     ` Chao Gao
2026-08-04 11:29 ` Chao Gao [this message]
2026-08-05 17:48   ` [PATCH v1 3/8] x86/virt/tdx: Add a table-driven TDX global metadata reader Edgecombe, Rick P
2026-08-10  6:43     ` Chao Gao
2026-08-10 18:32       ` Edgecombe, Rick P
2026-08-04 11:29 ` [PATCH v1 4/8] x86/virt/tdx: Convert version/tdmr/td_ctrl/handoff readers Chao Gao
2026-08-04 11:29 ` [PATCH v1 5/8] x86/virt/tdx: Convert td_conf reader Chao Gao
2026-08-04 11:29 ` [PATCH v1 6/8] x86/virt/tdx: Remove the auto-generated tdx_global_metadata.c Chao Gao
2026-08-04 11:29 ` [PATCH v1 7/8] x86/virt/tdx: Clean up error handling in get_tdx_sys_info() Chao Gao
2026-08-04 11:29 ` [PATCH v1 8/8] x86/virt/tdx: Verify the C member size against the metadata field ID Chao Gao
2026-08-04 23:38 ` [PATCH v1 0/8] TDX: Stop auto-generating the global metadata code Dave Hansen
2026-08-05 12:11   ` Chao Gao
2026-08-05 17:19 ` Edgecombe, Rick P
2026-08-10  8:49   ` Chao Gao

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260804112941.19894-4-chao.gao@intel.com \
    --to=chao.gao@intel.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=kas@kernel.org \
    --cc=kvm@vger.kernel.org \
    --cc=linux-coco@lists.linux.dev \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rick.p.edgecombe@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.