]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
x86/cpu: Add platform ID to CPU matching structure
authorDave Hansen <dave.hansen@linux.intel.com>
Wed, 4 Mar 2026 18:10:22 +0000 (10:10 -0800)
committerDave Hansen <dave.hansen@linux.intel.com>
Thu, 5 Mar 2026 20:25:38 +0000 (12:25 -0800)
The existing x86_match_cpu() infrastructure can be used to match
a bunch of attributes of a CPU: vendor, family, model, steppings
and CPU features.

But, there's one more attribute that's missing and unable to be
matched against: the platform ID, enumerated on Intel CPUs in
MSR_IA32_PLATFORM_ID. It is a little more obscure and is only
queried during microcode loading. This is because Intel sometimes
has CPUs with identical family/model/stepping but which need
different microcode. These CPUs are differentiated with the
platform ID.

Add a field in 'struct x86_cpu_id' for the platform ID. Similar
to the stepping field, make the new field a mask of platform IDs.
Some examples:

0x01: matches only platform ID 0x0
0x02: matches only platform ID 0x1
0x03: matches platform IDs 0x0 or 0x1
0x80: matches only platform ID 0x7
0xff: matches all 8 possible platform IDs

Since the mask is only a byte wide, it nestles in next to another
u8 and does not even increase the size of 'struct x86_cpu_id'.

Reserve the all 0's value as the wildcard (X86_PLATFORM_ANY). This
avoids forcing changes to existing 'struct x86_cpu_id' users.  They
can just continue to fill the field with 0's and their matching will
work exactly as before.

Note: If someone is ever looking for space in 'struct x86_cpu_id',
this new field could probably get stuck over in ->driver_data
for the one user that there is.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: Sohil Mehta <sohil.mehta@intel.com>
Link: https://patch.msgid.link/20260304181022.058DF07C@davehans-spike.ostc.intel.com
arch/x86/kernel/cpu/match.c
include/linux/mod_devicetable.h

index 6af1e8baeb0f2485ecd992e437d056eb2326f557..4604802692dae1892ae2d8eb8aad1afb6eed1d83 100644 (file)
@@ -76,6 +76,9 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match)
                if (m->steppings != X86_STEPPING_ANY &&
                    !(BIT(c->x86_stepping) & m->steppings))
                        continue;
+               if (m->platform_mask != X86_PLATFORM_ANY &&
+                   !(BIT(c->intel_platform_id) & m->platform_mask))
+                       continue;
                if (m->feature != X86_FEATURE_ANY && !cpu_has(c, m->feature))
                        continue;
                if (!x86_match_vendor_cpu_type(c, m))
index 5b1725fe97076e97af0441540d111782332c9876..23ff24080dfd9087edb52882c93255250eb51889 100644 (file)
@@ -691,6 +691,7 @@ struct x86_cpu_id {
        __u16 feature;  /* bit index */
        /* Solely for kernel-internal use: DO NOT EXPORT to userspace! */
        __u16 flags;
+       __u8  platform_mask;
        __u8  type;
        kernel_ulong_t driver_data;
 };
@@ -702,6 +703,7 @@ struct x86_cpu_id {
 #define X86_STEPPING_ANY 0
 #define X86_STEP_MIN 0
 #define X86_STEP_MAX 0xf
+#define X86_PLATFORM_ANY 0x0
 #define X86_FEATURE_ANY 0      /* Same as FPU, you can't test for that */
 #define X86_CPU_TYPE_ANY 0