[PATCH v7 075/120] x86/cpuid: Parse CPUID(0x12)
From: Ahmed S. Darwish
Date: Thu May 28 2026 - 12:08:50 EST
Parse CPUID(0x12).0, CPUID(0x12).1, and CPUID(0x12).n so that their call
sites can be converted to the CPUID API next.
Parse 8 subleaves for CPUID(0x12).n to match SGX_MAX_EPC_SECTIONS
definition at kernel/cpu/sgx/sgx.h.
Limit CPUID parsing to Intel x86 machines.
As stated in the hardware manuals, CPUID(0x12).0 and CPUID(0x12).1 are
valid only if CPUID(0x7).EBX.SGX is true. Ensure that their CPUID parser
read functions follow this.
Introduce cpuid_read_sgx_epc_sections() for CPUID(0x12).n parsing where an
EPC section type of 0 (SGX_CPUID_EPC_INVALID) means an invalid EPC section
subleaf. This matches the hardware manuals and the existing subleaf
iteration logic at kernel/cpu/sgx/main.c::sgx_page_cache_init().
Signed-off-by: Ahmed S. Darwish <darwi@xxxxxxxxxxxxx>
---
arch/x86/include/asm/cpuid/types.h | 3 +++
arch/x86/kernel/cpu/cpuid_parser.c | 14 ++++++++++++++
arch/x86/kernel/cpu/cpuid_parser.h | 4 ++++
3 files changed, 21 insertions(+)
diff --git a/arch/x86/include/asm/cpuid/types.h b/arch/x86/include/asm/cpuid/types.h
index 2949584e85cc..91ed4dd3c6c2 100644
--- a/arch/x86/include/asm/cpuid/types.h
+++ b/arch/x86/include/asm/cpuid/types.h
@@ -215,6 +215,9 @@ struct cpuid_leaves {
CPUID_LEAF ( 0x5, 0 );
CPUID_LEAF ( 0x6, 0 );
CPUID_LEAF ( 0x9, 0 );
+ CPUID_LEAF ( 0x12, 0 );
+ CPUID_LEAF ( 0x12, 1 );
+ CPUID_LEAF_N ( 0x12, 8 );
CPUID_LEAF ( 0x15, 0 );
CPUID_LEAF ( 0x16, 0 );
CPUID_LEAF ( 0x80000000, 0 );
diff --git a/arch/x86/kernel/cpu/cpuid_parser.c b/arch/x86/kernel/cpu/cpuid_parser.c
index f563834a082e..7ab4e01c6c33 100644
--- a/arch/x86/kernel/cpu/cpuid_parser.c
+++ b/arch/x86/kernel/cpu/cpuid_parser.c
@@ -115,6 +115,20 @@ cpuid_read_0x9(const struct cpuid_parse_entry *e, const struct cpuid_read_output
cpuid_read_generic(e, output);
}
+static void
+cpuid_read_0x12(const struct cpuid_parse_entry *e, const struct cpuid_read_output *output)
+{
+ struct leaf_0x7_0 l7;
+
+ cpuid_read(0x7, &l7);
+ if (!l7.sgx)
+ return;
+
+ cpuid_read_generic(e, output);
+}
+
+define_cpuid_read_function(sgx_epc_sections, leaf_0x12_n, l, l->subleaf_type == 0);
+
/*
* Define an extended range CPUID read function
*
diff --git a/arch/x86/kernel/cpu/cpuid_parser.h b/arch/x86/kernel/cpu/cpuid_parser.h
index 800a7bd6dca2..d12d1c2b459b 100644
--- a/arch/x86/kernel/cpu/cpuid_parser.h
+++ b/arch/x86/kernel/cpu/cpuid_parser.h
@@ -149,6 +149,9 @@ struct cpuid_parse_entry {
CPUID_PARSE_ENTRY ( 0x5, 0, generic ), \
CPUID_PARSE_ENTRY ( 0x6, 0, generic ), \
CPUID_PARSE_ENTRY ( 0x9, 0, 0x9 ), \
+ CPUID_PARSE_ENTRY ( 0x12, 0, 0x12 ), \
+ CPUID_PARSE_ENTRY ( 0x12, 1, 0x12 ), \
+ CPUID_PARSE_ENTRY_N ( 0x12, sgx_epc_sections ), \
CPUID_PARSE_ENTRY ( 0x15, 0, generic ), \
CPUID_PARSE_ENTRY ( 0x16, 0, generic ), \
CPUID_PARSE_ENTRY ( 0x80000000, 0, 0x80000000 ), \
@@ -202,6 +205,7 @@ struct cpuid_vendor_entry {
/* Leaf Vendor list */ \
CPUID_VENDOR_ENTRY(0x2, X86_VENDOR_INTEL, X86_VENDOR_CENTAUR, X86_VENDOR_ZHAOXIN),\
CPUID_VENDOR_ENTRY(0x4, X86_VENDOR_INTEL, X86_VENDOR_CENTAUR, X86_VENDOR_ZHAOXIN),\
+ CPUID_VENDOR_ENTRY(0x12, X86_VENDOR_INTEL), \
CPUID_VENDOR_ENTRY(0x15, X86_VENDOR_INTEL, X86_VENDOR_CENTAUR, X86_VENDOR_ZHAOXIN),\
CPUID_VENDOR_ENTRY(0x16, X86_VENDOR_INTEL), \
CPUID_VENDOR_ENTRY(0x8000001d, X86_VENDOR_AMD, X86_VENDOR_HYGON), \
--
2.54.0