From: Ricardo Neri <[email protected]>

On processors with Intel Hybrid Technology (i.e., one having more than one
type of CPU in the same package), all CPUs support the same instruction
set and enumerate the same features on CPUID. Thus, all software can run
on any CPU without restrictions. However, there may be model-specific
differences among types of CPUs. For instance, each type of CPU may support
a different number of performance counters. Also, machine check error banks
may be wired differently. Even though most software will not care about
these differences, kernel subsystems dealing with these differences must
know. Add a new member to cpuinfo_x86 that subsystems can query to know
the type of CPU.

Hybrid processors also have a native model ID to uniquely identify the
micro-architecture of each CPU. Please note that the native model ID is not
related with the existing x86_model_id read from CPUID leaf 0x1.

In order to uniquely identify a CPU by type and micro-architecture, combine
the aforementioned identifiers into a single new member, x86_cpu_type.

Define also masks that subsystems can use to obtain the CPU type or native
model separately.

The Intel Software Developer's Manual defines the CPU type and the CPU
native model ID as 8-bit and 24-bit identifiers, respectively.

Cc: Andi Kleen <[email protected]>
Cc: Andy Lutomirski <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: Kan Liang <[email protected]>
Cc: "Rafael J. Wysocki" <[email protected]>
Cc: "Ravi V. Shankar" <[email protected]>
Cc: Sean Christopherson <[email protected]>
Cc: Srinivas Pandruvada <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Len Brown <[email protected]>
Cc: Tony Luck <[email protected]>
Reviewed-by: Len Brown <[email protected]>
Reviewed-by: Tony Luck <[email protected]>
Signed-off-by: Ricardo Neri <[email protected]>
---
 arch/x86/include/asm/processor.h | 13 +++++++++++++
 arch/x86/kernel/cpu/common.c     |  3 +++
 2 files changed, 16 insertions(+)

diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index c20a52b..1f25ac9 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -139,6 +139,16 @@ struct cpuinfo_x86 {
        u32                     microcode;
        /* Address space bits used by the cache internally */
        u8                      x86_cache_bits;
+       /*
+        * In hybrid processors, there is a CPU type and a native model ID. The
+        * CPU type (x86_cpu_type[31:24]) describes the type of micro-
+        * architecture families. The native model ID (x86_cpu_type[23:0])
+        * describes a specific microarchitecture version. Combining both
+        * allows to uniquely identify a CPU.
+        *
+        * Please note that the native model ID is not related to x86_model.
+        */
+       u32                     x86_cpu_type;
        unsigned                initialized : 1;
 } __randomize_layout;
 
@@ -166,6 +176,9 @@ enum cpuid_regs_idx {
 
 #define X86_VENDOR_UNKNOWN     0xff
 
+#define X86_HYBRID_CPU_TYPE_ID_SHIFT           24
+#define X86_HYBRID_CPU_NATIVE_MODEL_ID_MASK    0xffffff
+
 /*
  * capabilities of CPUs
  */
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 35ad848..a66c1fd 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -932,6 +932,9 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
                c->x86_capability[CPUID_D_1_EAX] = eax;
        }
 
+       if (cpu_has(c, X86_FEATURE_HYBRID_CPU))
+               c->x86_cpu_type = cpuid_eax(0x0000001a);
+
        /* AMD-defined flags: level 0x80000001 */
        eax = cpuid_eax(0x80000000);
        c->extended_cpuid_level = eax;
-- 
2.7.4

Reply via email to