[PATCH v6 79/90] x86/cpuid: Introduce a compile-time X86_FEATURE word map

Ahmed S. Darwish posted 90 patches 6 days, 16 hours ago
[PATCH v6 79/90] x86/cpuid: Introduce a compile-time X86_FEATURE word map
Posted by Ahmed S. Darwish 6 days, 16 hours ago
Prepare for routing X86_FEATURE queries to the CPUID tables instead of to
cpuinfo_x86::x86_capability[].  The latter will be later removed to make
the CPUID tables a "single source of Truth" for all x86 feature state.

Build a compile time map from an <asm/cpufeatures.h> X86_FEATURE word to
its cached CPUID leaf/subleaf register output.

Use a compile time table to preserve the feature querying optimizations at
<asm/cpufeature.h>.

Signed-off-by: Ahmed S. Darwish <darwi@linutronix.de>
---
 arch/x86/include/asm/cpuid/types.h | 59 +++++++++++++++++++++++++++++-
 1 file changed, 57 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/cpuid/types.h b/arch/x86/include/asm/cpuid/types.h
index 263e82e89f70..6b0790408b85 100644
--- a/arch/x86/include/asm/cpuid/types.h
+++ b/arch/x86/include/asm/cpuid/types.h
@@ -168,9 +168,12 @@ struct leaf_parse_info {
  * Use an array of storage entries to accommodate CPUID leaves with multiple subleaves
  * having the same output format.  This is common for hierarchical enumeration; e.g.,
  * CPUID(0x4), CPUID(0x12), and CPUID(0x8000001d).
+ *
+ * Align all CPUID outputs to unsigned long.  They're passed to bitops for X86_FEATURE
+ * queries, which require the alignment.
  */
 #define __CPUID_LEAF(_name, _count)				\
-	struct _name		_name[_count];			\
+	struct _name		_name[_count] __aligned(sizeof(unsigned long));\
 	struct leaf_parse_info	_name##_info
 
 /**
@@ -267,9 +270,61 @@ struct cpuid_leaves {
  *
  * This is to be embedded inside 'struct cpuinfo_x86' to provide parsed and
  * sanitized CPUID data per CPU.
+ *
+ * Align the leaves to unsigned long since their elements are passed to bitops
+ * for X86_FEATURE querying.
  */
 struct cpuid_table {
-	struct cpuid_leaves	leaves;
+	struct cpuid_leaves	leaves __aligned(sizeof(unsigned long));
+};
+
+/*
+ * X86_FEATURE word mappings:
+ *
+ * Build a compile-time mapping table from an <asm/cpufeatures.h> X86_FEATURE
+ * word to its corresponding cached entry in a CPUID table.
+ */
+
+#define __BUG(n)	(NCAPINTS + (n))
+
+struct cpuid_cpufeature {
+	unsigned int	leaves_offset;	/* Offset from a struct cpuid_leaves instance */
+	unsigned int	cpuid_reg;	/* Output register: CPUID_EAX -> CPUID_EDX */
 };
 
+#define __cpu_feature_word(_word, _leaf, _subleaf, _reg)				\
+	[_word] = {									\
+		.leaves_offset	= offsetof(struct cpuid_leaves, leaf_##_leaf##_##_subleaf),\
+		.cpuid_reg	= _reg,							\
+	}
+
+#define CPUID_FEATURE_WORDS_MAP								\
+{											\
+	/*   X86_FEATURE word,		Leaf,		Subleaf,	Output reg */	\
+	__cpu_feature_word(0,		0x1,		0,		CPUID_EDX),	\
+	__cpu_feature_word(1,		0x80000001,	0,		CPUID_EDX),	\
+	__cpu_feature_word(2,		0x80860001,	0,		CPUID_EDX),	\
+	__cpu_feature_word(3,		0x4c780001,	0,		CPUID_EAX),	\
+	__cpu_feature_word(4,		0x1,		0,		CPUID_ECX),	\
+	__cpu_feature_word(5,		0xc0000001,	0,		CPUID_EDX),	\
+	__cpu_feature_word(6,		0x80000001,	0,		CPUID_ECX),	\
+	__cpu_feature_word(7,		0x4c780001,	0,		CPUID_EBX),	\
+	__cpu_feature_word(8,		0x4c780001,	0,		CPUID_ECX),	\
+	__cpu_feature_word(9,		0x7,		0,		CPUID_EBX),	\
+	__cpu_feature_word(10,		0xd,		1,		CPUID_EAX),	\
+	__cpu_feature_word(11,		0x4c780001,	0,		CPUID_EDX),	\
+	__cpu_feature_word(12,		0x7,		1,		CPUID_EAX),	\
+	__cpu_feature_word(13,		0x80000008,	0,		CPUID_EBX),	\
+	__cpu_feature_word(14,		0x6,		0,		CPUID_EAX),	\
+	__cpu_feature_word(15,		0x8000000a,	0,		CPUID_EDX),	\
+	__cpu_feature_word(16,		0x7,		0,		CPUID_ECX),	\
+	__cpu_feature_word(17,		0x4c780001,	1,		CPUID_EAX),	\
+	__cpu_feature_word(18,		0x7,		0,		CPUID_EDX),	\
+	__cpu_feature_word(19,		0x8000001f,	0,		CPUID_EAX),	\
+	__cpu_feature_word(20,		0x80000021,	0,		CPUID_EAX),	\
+	__cpu_feature_word(21,		0x4c780001,	1,		CPUID_EBX),	\
+	__cpu_feature_word(__BUG(0),	0x4c780002,	0,		CPUID_EAX),	\
+	__cpu_feature_word(__BUG(1),	0x4c780002,	0,		CPUID_EBX),	\
+}
+
 #endif /* _ASM_X86_CPUID_TYPES_H */
-- 
2.53.0