Skip to content

Commit 47a973f

Browse files
Kan LiangPeter Zijlstra
authored andcommitted
perf/x86/intel: Fix ARCH_PERFMON_NUM_COUNTER_LEAF
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 <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Cc: [email protected] Link: https://lkml.kernel.org/r/[email protected]
1 parent 0a55615 commit 47a973f

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
@@ -4905,20 +4905,22 @@ static inline bool intel_pmu_broken_perf_cap(void)
49054905

49064906
static void update_pmu_cap(struct x86_hybrid_pmu *pmu)
49074907
{
4908-
unsigned int sub_bitmaps, eax, ebx, ecx, edx;
4908+
unsigned int cntr, fixed_cntr, ecx, edx;
4909+
union cpuid35_eax eax;
4910+
union cpuid35_ebx ebx;
49094911

4910-
cpuid(ARCH_PERFMON_EXT_LEAF, &sub_bitmaps, &ebx, &ecx, &edx);
4912+
cpuid(ARCH_PERFMON_EXT_LEAF, &eax.full, &ebx.full, &ecx, &edx);
49114913

4912-
if (ebx & ARCH_PERFMON_EXT_UMASK2)
4914+
if (ebx.split.umask2)
49134915
pmu->config_mask |= ARCH_PERFMON_EVENTSEL_UMASK2;
4914-
if (ebx & ARCH_PERFMON_EXT_EQ)
4916+
if (ebx.split.eq)
49154917
pmu->config_mask |= ARCH_PERFMON_EVENTSEL_EQ;
49164918

4917-
if (sub_bitmaps & ARCH_PERFMON_NUM_COUNTER_LEAF_BIT) {
4919+
if (eax.split.cntr_subleaf) {
49184920
cpuid_count(ARCH_PERFMON_EXT_LEAF, ARCH_PERFMON_NUM_COUNTER_LEAF,
4919-
&eax, &ebx, &ecx, &edx);
4920-
pmu->cntr_mask64 = eax;
4921-
pmu->fixed_cntr_mask64 = ebx;
4921+
&cntr, &fixed_cntr, &ecx, &edx);
4922+
pmu->cntr_mask64 = cntr;
4923+
pmu->fixed_cntr_mask64 = fixed_cntr;
49224924
}
49234925

49244926
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
@@ -188,11 +188,33 @@ union cpuid10_edx {
188188
* detection/enumeration details:
189189
*/
190190
#define ARCH_PERFMON_EXT_LEAF 0x00000023
191-
#define ARCH_PERFMON_EXT_UMASK2 0x1
192-
#define ARCH_PERFMON_EXT_EQ 0x2
193-
#define ARCH_PERFMON_NUM_COUNTER_LEAF_BIT 0x1
194191
#define ARCH_PERFMON_NUM_COUNTER_LEAF 0x1
195192

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

0 commit comments

Comments
 (0)