[PATCH v6 77/90] x86/cpuid: Parse leaves backing X86_FEATURE words

Ahmed S. Darwish posted 90 patches 6 days, 16 hours ago
[PATCH v6 77/90] x86/cpuid: Parse leaves backing X86_FEATURE words
Posted by Ahmed S. Darwish 6 days, 16 hours ago
Add CPUID parser support for:

    CPUID(0x6)
    CPUID(0x7)
    CPUID(0x7).1
    CPUID(0xd).1
    CPUID(0x80000001)
    CPUID(0x8000000a)
    CPUID(0x8000001f)
    CPUID(0x80000021)

where one or more of these leaves output registers back the X86_FEATURE
words at <asm/cpufeatures.h>.

Handle CPUID(0x7).1 via a custom reader.  Its availability depends on the
subleaf count reported by CPUID(0x7).0, so check that first.

Do not use a custom reader for CPUID(0xd).1.  Per the Intel SDM regarding
CPUID(0xd)'s subleaf availability: "sub-leafs 0 and 1 are always valid".

Note, this prepares for later changes that will route X86_FEATURE queries
from cpuinfo_x86::x86_capability[] to the system's CPUID tables.

Signed-off-by: Ahmed S. Darwish <darwi@linutronix.de>
---
 arch/x86/include/asm/cpuid/types.h |  8 ++++++++
 arch/x86/kernel/cpu/cpuid_parser.c | 13 +++++++++++++
 arch/x86/kernel/cpu/cpuid_parser.h |  8 ++++++++
 3 files changed, 29 insertions(+)

diff --git a/arch/x86/include/asm/cpuid/types.h b/arch/x86/include/asm/cpuid/types.h
index 6180acd35f59..204d6277c8cd 100644
--- a/arch/x86/include/asm/cpuid/types.h
+++ b/arch/x86/include/asm/cpuid/types.h
@@ -212,7 +212,11 @@ struct cpuid_leaves {
 	CPUID_LEAF   (	0x1,		0  );
 	CPUID_LEAF   (  0x2,		0  );
 	CPUID_LEAF_N (  0x4,		8  );
+	CPUID_LEAF   (  0x6,		0  );
+	CPUID_LEAF   (  0x7,		0  );
+	CPUID_LEAF   (  0x7,		1  );
 	CPUID_LEAF   (  0xa,		0  );
+	CPUID_LEAF   (  0xd,		1  );
 	CPUID_LEAF   (  0x1c,		0  );
 	CPUID_LEAF   (	0x16,		0  );
 	CPUID_LEAF   (  0x23,		0  );
@@ -222,6 +226,7 @@ struct cpuid_leaves {
 	CPUID_LEAF   (  0x23,		4  );
 	CPUID_LEAF   (  0x23,		5  );
 	CPUID_LEAF   (  0x80000000,	0  );
+	CPUID_LEAF   (  0x80000001,	0  );
 	CPUID_LEAF   (  0x80000002,	0  );
 	CPUID_LEAF   (  0x80000003,	0  );
 	CPUID_LEAF   (  0x80000004,	0  );
@@ -229,7 +234,10 @@ struct cpuid_leaves {
 	CPUID_LEAF   (  0x80000006,	0  );
 	CPUID_LEAF   (  0x80000007,	0  );
 	CPUID_LEAF   (  0x80000008,	0  );
+	CPUID_LEAF   (  0x8000000a,	0  );
 	CPUID_LEAF_N (  0x8000001d,	8  );
+	CPUID_LEAF   (  0x8000001f,	0  );
+	CPUID_LEAF   (  0x80000021,	0  );
 	CPUID_LEAF   (  0x80000022,	0  );
 	CPUID_LEAF   (  0x80860000,	0  );
 	CPUID_LEAF   (  0x80860001,	0  );
diff --git a/arch/x86/kernel/cpu/cpuid_parser.c b/arch/x86/kernel/cpu/cpuid_parser.c
index de11fb4116f2..b3bf4141db15 100644
--- a/arch/x86/kernel/cpu/cpuid_parser.c
+++ b/arch/x86/kernel/cpu/cpuid_parser.c
@@ -99,6 +99,19 @@ cpuid_read_0x2(const struct cpuid_parse_entry *e, const struct cpuid_read_output
 	output->info->nr_entries = 1;
 }
 
+static void
+cpuid_read_0x7_1(const struct cpuid_parse_entry *e, const struct cpuid_read_output *output)
+{
+	struct leaf_0x7_0 l7;
+
+	cpuid_read_subleaf(0x7, 0, &l7);
+	if (l7.leaf7_n_subleaves == 0)
+		return;
+
+	cpuid_read_subleaf(e->leaf, e->subleaf, output->regs);
+	output->info->nr_entries = 1;
+}
+
 /*
  * Shared read function for Intel CPUID(0x4) and AMD CPUID(0x8000001d), as both have
  * the same subleaf enumeration logic and register output format.
diff --git a/arch/x86/kernel/cpu/cpuid_parser.h b/arch/x86/kernel/cpu/cpuid_parser.h
index c81f76c1c077..f6a620a03312 100644
--- a/arch/x86/kernel/cpu/cpuid_parser.h
+++ b/arch/x86/kernel/cpu/cpuid_parser.h
@@ -146,7 +146,11 @@ struct cpuid_parse_entry {
 	/*			Leaf		Subleaf		Reader function */		\
 	CPUID_PARSE_ENTRY   (	0x2,		0,		0x2			),	\
 	CPUID_PARSE_ENTRY_N (	0x4,				deterministic_cache	),	\
+	CPUID_PARSE_ENTRY   (	0x6,		0,		generic			),	\
+	CPUID_PARSE_ENTRY   (	0x7,		0,		generic			),	\
+	CPUID_PARSE_ENTRY   (	0x7,		1,		0x7_1			),	\
 	CPUID_PARSE_ENTRY   (	0xa,		0,		generic			),	\
+	CPUID_PARSE_ENTRY   (	0xd,		1,		generic			),	\
 	CPUID_PARSE_ENTRY   (	0x1c,		0,		generic			),	\
 	CPUID_PARSE_ENTRY   (	0x16,		0,		generic			),	\
 	CPUID_PARSE_ENTRY   (	0x23,		0,		generic			),	\
@@ -156,6 +160,7 @@ struct cpuid_parse_entry {
 	CPUID_PARSE_ENTRY   (	0x23,		4,		0x23_4			),	\
 	CPUID_PARSE_ENTRY   (	0x23,		5,		0x23_5			),	\
 	CPUID_PARSE_ENTRY   (	0x80000000,	0,		0x80000000		),	\
+	CPUID_PARSE_ENTRY   (	0x80000001,	0,		generic			),	\
 	CPUID_PARSE_ENTRY   (	0x80000002,	0,		generic			),	\
 	CPUID_PARSE_ENTRY   (	0x80000003,	0,		generic			),	\
 	CPUID_PARSE_ENTRY   (	0x80000004,	0,		generic			),	\
@@ -163,7 +168,10 @@ struct cpuid_parse_entry {
 	CPUID_PARSE_ENTRY   (	0x80000006,	0,		generic			),	\
 	CPUID_PARSE_ENTRY   (	0x80000007,	0,		generic			),	\
 	CPUID_PARSE_ENTRY   (	0x80000008,	0,		generic			),	\
+	CPUID_PARSE_ENTRY   (	0x8000000a,	0,		generic			),	\
 	CPUID_PARSE_ENTRY_N (	0x8000001d,			deterministic_cache	),	\
+	CPUID_PARSE_ENTRY   (	0x8000001f,	0,		generic			),	\
+	CPUID_PARSE_ENTRY   (	0x80000021,	0,		generic			),	\
 	CPUID_PARSE_ENTRY   (	0x80000022,	0,		generic			),	\
 	CPUID_PARSE_ENTRY   (	0x80860000,	0,		0x80860000		),	\
 	CPUID_PARSE_ENTRY   (	0x80860001,	0,		generic			),	\
-- 
2.53.0