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