From: Mario Limonciello <mario.limonciello@amd.com>
To: Borislav Petkov <bp@alien8.de>
Cc: Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@redhat.com>,
"Dave Hansen" <dave.hansen@linux.intel.com>,
"maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT)"
<x86@kernel.org>, "H . Peter Anvin" <hpa@zytor.com>,
"Rafael J . Wysocki" <rafael@kernel.org>,
"Gautham R . Shenoy" <gautham.shenoy@amd.com>,
Mario Limonciello <mario.limonciello@amd.com>,
Perry Yuan <perry.yuan@amd.com>,
Brijesh Singh <brijesh.singh@amd.com>,
Peter Zijlstra <peterz@infradead.org>,
Li RongQing <lirongqing@baidu.com>,
"open list:X86 ARCHITECTURE (32-BIT AND 64-BIT)"
<linux-kernel@vger.kernel.org>,
"open list:ACPI" <linux-acpi@vger.kernel.org>,
"open list:AMD PSTATE DRIVER" <linux-pm@vger.kernel.org>,
Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
Subject: [PATCH v2 4/5] x86/cpu: Add CPU type to struct cpuinfo_topology
Date: Mon, 21 Oct 2024 22:46:07 -0500 [thread overview]
Message-ID: <20241022034608.32396-5-mario.limonciello@amd.com> (raw)
In-Reply-To: <20241022034608.32396-1-mario.limonciello@amd.com>
From: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
Sometimes it is required to take actions based on if a CPU is a performance
or efficiency core. As an example, intel_pstate driver uses the Intel
core-type to determine CPU scaling. Also, some CPU vulnerabilities only
affect a specific CPU type, like RFDS only affects Intel Atom. Hybrid
systems that have variants P+E, P-only(Core) and E-only(Atom), it is not
straightforward to identify which variant is affected by a type specific
vulnerability.
Such processors do have CPUID field that can uniquely identify them. Like,
P+E, P-only and E-only enumerates CPUID.1A.CORE_TYPE identification, while
P+E additionally enumerates CPUID.7.HYBRID. Based on this information, it
is possible for boot CPU to identify if a system has mixed CPU types.
Add a new field hw_cpu_type to struct cpuinfo_topology that stores the
hardware specific CPU type. This saves the overhead of IPIs to get the CPU
type of a different CPU. CPU type is populated early in the boot process,
before vulnerabilities are enumerated.
Signed-off-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
Co-developed-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
---
* Take this patch from Pawan's series and fix up for feedback left on it.
* Add in AMD case as well
---
arch/x86/include/asm/cpu.h | 19 +++++++++++++++++++
arch/x86/include/asm/processor.h | 18 ++++++++++++++++++
arch/x86/include/asm/topology.h | 8 ++++++++
arch/x86/kernel/cpu/amd.c | 14 ++++++++++++++
arch/x86/kernel/cpu/debugfs.c | 1 +
arch/x86/kernel/cpu/intel.c | 18 ++++++++++++++++++
arch/x86/kernel/cpu/topology_amd.c | 3 +++
arch/x86/kernel/cpu/topology_common.c | 13 +++++++++++++
8 files changed, 94 insertions(+)
diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
index 98eced5084ca7..28bb177241131 100644
--- a/arch/x86/include/asm/cpu.h
+++ b/arch/x86/include/asm/cpu.h
@@ -53,6 +53,8 @@ static inline void bus_lock_init(void) {}
#ifdef CONFIG_CPU_SUP_INTEL
u8 get_this_hybrid_cpu_type(void);
u32 get_this_hybrid_cpu_native_id(void);
+u32 intel_native_model_id(struct cpuinfo_x86 *c);
+enum x86_topology_cpu_type intel_cpu_type(struct cpuinfo_x86 *c);
#else
static inline u8 get_this_hybrid_cpu_type(void)
{
@@ -63,6 +65,23 @@ static inline u32 get_this_hybrid_cpu_native_id(void)
{
return 0;
}
+
+static u32 intel_native_model_id(struct cpuinfo_x86 *c)
+{
+ return 0;
+}
+static enum x86_topology_cpu_type intel_cpu_type(struct cpuinfo_x86 *c)
+{
+ return TOPO_CPU_TYPE_UNKNOWN;
+}
+#endif
+#ifdef CONFIG_CPU_SUP_AMD
+enum x86_topology_cpu_type amd_cpu_type(struct cpuinfo_x86 *c);
+#else
+static inline enum x86_topology_cpu_type amd_cpu_type(struct cpuinfo_x86 *c)
+{
+ return TOPO_CPU_TYPE_UNKNOWN;
+}
#endif
#ifdef CONFIG_IA32_FEAT_CTL
void init_ia32_feat_ctl(struct cpuinfo_x86 *c);
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 4a686f0e5dbf6..872e5a429d00d 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -105,6 +105,24 @@ struct cpuinfo_topology {
// Cache level topology IDs
u32 llc_id;
u32 l2c_id;
+
+ // Hardware defined CPU-type
+ union {
+ u32 cpu_type;
+ struct {
+ // CPUID.1A.EAX[23-0]
+ u32 intel_native_model_id:24;
+ // CPUID.1A.EAX[31-24]
+ u32 intel_type:8;
+ };
+ struct {
+ // CPUID 0x80000026.EBX
+ u32 amd_num_processors :16,
+ amd_power_efficiency_ranking :8,
+ amd_native_model_id :4,
+ amd_type :4;
+ };
+ };
};
struct cpuinfo_x86 {
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index aef70336d6247..5b344ff81219d 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -114,6 +114,12 @@ enum x86_topology_domains {
TOPO_MAX_DOMAIN,
};
+enum x86_topology_cpu_type {
+ TOPO_CPU_TYPE_PERFORMANCE,
+ TOPO_CPU_TYPE_EFFICIENCY,
+ TOPO_CPU_TYPE_UNKNOWN,
+};
+
struct x86_topology_system {
unsigned int dom_shifts[TOPO_MAX_DOMAIN];
unsigned int dom_size[TOPO_MAX_DOMAIN];
@@ -149,6 +155,8 @@ extern unsigned int __max_threads_per_core;
extern unsigned int __num_threads_per_package;
extern unsigned int __num_cores_per_package;
+enum x86_topology_cpu_type topology_cpu_type(struct cpuinfo_x86 *c);
+
static inline unsigned int topology_max_packages(void)
{
return __max_logical_packages;
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index fab5caec0b72e..779073e5a6468 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -29,6 +29,9 @@
#include "cpu.h"
+#define TOPO_HW_CPU_TYPE_AMD_PERFORMANCE 0
+#define TOPO_HW_CPU_TYPE_AMD_EFFICIENCY 1
+
static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p)
{
u32 gprs[8] = { 0 };
@@ -1205,3 +1208,14 @@ void amd_check_microcode(void)
if (cpu_feature_enabled(X86_FEATURE_ZEN2))
on_each_cpu(zenbleed_check_cpu, NULL, 1);
}
+
+enum x86_topology_cpu_type amd_cpu_type(struct cpuinfo_x86 *c)
+{
+ switch (c->topo.amd_type) {
+ case TOPO_HW_CPU_TYPE_AMD_PERFORMANCE:
+ return TOPO_CPU_TYPE_PERFORMANCE;
+ case TOPO_HW_CPU_TYPE_AMD_EFFICIENCY:
+ return TOPO_CPU_TYPE_EFFICIENCY;
+ }
+ return TOPO_CPU_TYPE_UNKNOWN;
+}
diff --git a/arch/x86/kernel/cpu/debugfs.c b/arch/x86/kernel/cpu/debugfs.c
index 3baf3e4358347..c3361e496df99 100644
--- a/arch/x86/kernel/cpu/debugfs.c
+++ b/arch/x86/kernel/cpu/debugfs.c
@@ -22,6 +22,7 @@ static int cpu_debug_show(struct seq_file *m, void *p)
seq_printf(m, "die_id: %u\n", c->topo.die_id);
seq_printf(m, "cu_id: %u\n", c->topo.cu_id);
seq_printf(m, "core_id: %u\n", c->topo.core_id);
+ seq_printf(m, "cpu_type: %u\n", topology_cpu_type(c));
seq_printf(m, "logical_pkg_id: %u\n", c->topo.logical_pkg_id);
seq_printf(m, "logical_die_id: %u\n", c->topo.logical_die_id);
seq_printf(m, "llc_id: %u\n", c->topo.llc_id);
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index d1de300af1737..8887b5ed1fbca 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -878,6 +878,8 @@ static const struct cpu_dev intel_cpu_dev = {
cpu_dev_register(intel_cpu_dev);
#define X86_HYBRID_CPU_TYPE_ID_SHIFT 24
+#define TOPO_HW_CPU_TYPE_INTEL_ATOM 0x20
+#define TOPO_HW_CPU_TYPE_INTEL_CORE 0x40
/**
* get_this_hybrid_cpu_type() - Get the type of this hybrid CPU
@@ -907,3 +909,19 @@ u32 get_this_hybrid_cpu_native_id(void)
return cpuid_eax(0x0000001a) &
(BIT_ULL(X86_HYBRID_CPU_TYPE_ID_SHIFT) - 1);
}
+
+u32 intel_native_model_id(struct cpuinfo_x86 *c)
+{
+ return c->topo.intel_native_model_id;
+}
+
+enum x86_topology_cpu_type intel_cpu_type(struct cpuinfo_x86 *c)
+{
+ switch (c->topo.intel_type) {
+ case TOPO_HW_CPU_TYPE_INTEL_ATOM:
+ return TOPO_CPU_TYPE_EFFICIENCY;
+ case TOPO_HW_CPU_TYPE_INTEL_CORE:
+ return TOPO_CPU_TYPE_PERFORMANCE;
+ }
+ return TOPO_CPU_TYPE_UNKNOWN;
+}
diff --git a/arch/x86/kernel/cpu/topology_amd.c b/arch/x86/kernel/cpu/topology_amd.c
index 7d476fa697ca5..03b3c9c3a45e2 100644
--- a/arch/x86/kernel/cpu/topology_amd.c
+++ b/arch/x86/kernel/cpu/topology_amd.c
@@ -182,6 +182,9 @@ static void parse_topology_amd(struct topo_scan *tscan)
if (cpu_feature_enabled(X86_FEATURE_TOPOEXT))
has_topoext = cpu_parse_topology_ext(tscan);
+ if (cpu_feature_enabled(X86_FEATURE_AMD_HETEROGENEOUS_CORES))
+ tscan->c->topo.cpu_type = cpuid_ebx(0x80000026);
+
if (!has_topoext && !parse_8000_0008(tscan))
return;
diff --git a/arch/x86/kernel/cpu/topology_common.c b/arch/x86/kernel/cpu/topology_common.c
index 9a6069e7133c9..04b012dffa473 100644
--- a/arch/x86/kernel/cpu/topology_common.c
+++ b/arch/x86/kernel/cpu/topology_common.c
@@ -27,6 +27,16 @@ void topology_set_dom(struct topo_scan *tscan, enum x86_topology_domains dom,
}
}
+enum x86_topology_cpu_type topology_cpu_type(struct cpuinfo_x86 *c)
+{
+ if (c->x86_vendor == X86_VENDOR_INTEL)
+ return intel_cpu_type(c);
+ if (c->x86_vendor == X86_VENDOR_AMD)
+ return amd_cpu_type(c);
+
+ return TOPO_CPU_TYPE_UNKNOWN;
+}
+
static unsigned int __maybe_unused parse_num_cores_legacy(struct cpuinfo_x86 *c)
{
struct {
@@ -87,6 +97,7 @@ static void parse_topology(struct topo_scan *tscan, bool early)
.cu_id = 0xff,
.llc_id = BAD_APICID,
.l2c_id = BAD_APICID,
+ .cpu_type = TOPO_CPU_TYPE_UNKNOWN,
};
struct cpuinfo_x86 *c = tscan->c;
struct {
@@ -132,6 +143,8 @@ static void parse_topology(struct topo_scan *tscan, bool early)
case X86_VENDOR_INTEL:
if (!IS_ENABLED(CONFIG_CPU_SUP_INTEL) || !cpu_parse_topology_ext(tscan))
parse_legacy(tscan);
+ if (c->cpuid_level >= 0x1a)
+ c->topo.cpu_type = cpuid_eax(0x1a);
break;
case X86_VENDOR_HYGON:
if (IS_ENABLED(CONFIG_CPU_SUP_HYGON))
--
2.43.0
next prev parent reply other threads:[~2024-10-22 3:47 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-22 3:46 [PATCH v2 0/5] x86 Heterogeneous design identification Mario Limonciello
2024-10-22 3:46 ` [PATCH v2 1/5] x86/cpufeatures: Rename X86_FEATURE_FAST_CPPC to have AMD prefix Mario Limonciello
2024-10-22 3:46 ` [PATCH v2 2/5] x86/cpufeatures: Add feature bits for AMD heterogeneous processor Mario Limonciello
2024-10-22 3:46 ` [PATCH v2 3/5] x86/cpu: Enable SD_ASYM_PACKING for PKG Domain on AMD Processors Mario Limonciello
2024-10-22 9:20 ` Gautham R. Shenoy
2024-10-22 3:46 ` Mario Limonciello [this message]
2024-10-22 11:57 ` [PATCH v2 4/5] x86/cpu: Add CPU type to struct cpuinfo_topology Borislav Petkov
2024-10-22 12:03 ` Borislav Petkov
2024-10-22 15:41 ` Mario Limonciello
2024-10-22 16:03 ` Dave Hansen
2024-10-22 16:13 ` Mario Limonciello
2024-10-22 17:09 ` Dave Hansen
2024-10-23 3:58 ` Pawan Gupta
2024-10-23 4:40 ` Pawan Gupta
2024-10-23 15:59 ` Borislav Petkov
2024-10-22 3:46 ` [PATCH v2 5/5] x86/amd: Use heterogeneous core topology for identifying boost numerator Mario Limonciello
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241022034608.32396-5-mario.limonciello@amd.com \
--to=mario.limonciello@amd.com \
--cc=bp@alien8.de \
--cc=brijesh.singh@amd.com \
--cc=dave.hansen@linux.intel.com \
--cc=gautham.shenoy@amd.com \
--cc=hpa@zytor.com \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=lirongqing@baidu.com \
--cc=mingo@redhat.com \
--cc=pawan.kumar.gupta@linux.intel.com \
--cc=perry.yuan@amd.com \
--cc=peterz@infradead.org \
--cc=rafael@kernel.org \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.