Skip to content

Commit 6248ee8

Browse files
Kan Liangmehmetb0
authored andcommitted
perf/x86/intel: Fix ARCH_PERFMON_NUM_COUNTER_LEAF
BugLink: https://bugs.launchpad.net/bugs/2104873 commit 47a973f upstream. The EAX of the CPUID Leaf 023H enumerates the mask of valid sub-leaves. To tell the availability of the sub-leaf 1 (enumerate the counter mask), perf should check the bit 1 (0x2) of EAS, rather than bit 0 (0x1). The error is not user-visible on bare metal. Because the sub-leaf 0 and the sub-leaf 1 are always available. However, it may bring issues in a virtualization environment when a VMM only enumerates the sub-leaf 0. Introduce the cpuid35_e?x to replace the macros, which makes the implementation style consistent. Fixes: eb467aa ("perf/x86/intel: Support Architectural PerfMon Extension leaf") Signed-off-by: Kan Liang <kan.liang@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/20250129154820.3755948-3-kan.liang@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Noah Wager <noah.wager@canonical.com>
1 parent 0ca41de commit 6248ee8

File tree

2 files changed

+35
-11
lines changed

2 files changed

+35
-11
lines changed

arch/x86/events/intel/core.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4865,20 +4865,22 @@ static inline bool intel_pmu_broken_perf_cap(void)
48654865

48664866
static void update_pmu_cap(struct x86_hybrid_pmu *pmu)
48674867
{
4868-
unsigned int sub_bitmaps, eax, ebx, ecx, edx;
4868+
unsigned int cntr, fixed_cntr, ecx, edx;
4869+
union cpuid35_eax eax;
4870+
union cpuid35_ebx ebx;
48694871

4870-
cpuid(ARCH_PERFMON_EXT_LEAF, &sub_bitmaps, &ebx, &ecx, &edx);
4872+
cpuid(ARCH_PERFMON_EXT_LEAF, &eax.full, &ebx.full, &ecx, &edx);
48714873

4872-
if (ebx & ARCH_PERFMON_EXT_UMASK2)
4874+
if (ebx.split.umask2)
48734875
pmu->config_mask |= ARCH_PERFMON_EVENTSEL_UMASK2;
4874-
if (ebx & ARCH_PERFMON_EXT_EQ)
4876+
if (ebx.split.eq)
48754877
pmu->config_mask |= ARCH_PERFMON_EVENTSEL_EQ;
48764878

4877-
if (sub_bitmaps & ARCH_PERFMON_NUM_COUNTER_LEAF_BIT) {
4879+
if (eax.split.cntr_subleaf) {
48784880
cpuid_count(ARCH_PERFMON_EXT_LEAF, ARCH_PERFMON_NUM_COUNTER_LEAF,
4879-
&eax, &ebx, &ecx, &edx);
4880-
pmu->cntr_mask64 = eax;
4881-
pmu->fixed_cntr_mask64 = ebx;
4881+
&cntr, &fixed_cntr, &ecx, &edx);
4882+
pmu->cntr_mask64 = cntr;
4883+
pmu->fixed_cntr_mask64 = fixed_cntr;
48824884
}
48834885

48844886
if (!intel_pmu_broken_perf_cap()) {

arch/x86/include/asm/perf_event.h

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -187,11 +187,33 @@ union cpuid10_edx {
187187
* detection/enumeration details:
188188
*/
189189
#define ARCH_PERFMON_EXT_LEAF 0x00000023
190-
#define ARCH_PERFMON_EXT_UMASK2 0x1
191-
#define ARCH_PERFMON_EXT_EQ 0x2
192-
#define ARCH_PERFMON_NUM_COUNTER_LEAF_BIT 0x1
193190
#define ARCH_PERFMON_NUM_COUNTER_LEAF 0x1
194191

192+
union cpuid35_eax {
193+
struct {
194+
unsigned int leaf0:1;
195+
/* Counters Sub-Leaf */
196+
unsigned int cntr_subleaf:1;
197+
/* Auto Counter Reload Sub-Leaf */
198+
unsigned int acr_subleaf:1;
199+
/* Events Sub-Leaf */
200+
unsigned int events_subleaf:1;
201+
unsigned int reserved:28;
202+
} split;
203+
unsigned int full;
204+
};
205+
206+
union cpuid35_ebx {
207+
struct {
208+
/* UnitMask2 Supported */
209+
unsigned int umask2:1;
210+
/* EQ-bit Supported */
211+
unsigned int eq:1;
212+
unsigned int reserved:30;
213+
} split;
214+
unsigned int full;
215+
};
216+
195217
/*
196218
* Intel Architectural LBR CPUID detection/enumeration details:
197219
*/

0 commit comments

Comments
 (0)