Skip to content

Commit ff1848d

Browse files
committed
Merge tag 'perf_urgent_for_v6.14_rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 perf fixes from Borislav Petkov: - Explicitly clear DEBUGCTL.LBR to prevent LBRs continuing being enabled after handoff to the OS - Check CPUID(0x23) leaf and subleafs presence properly - Remove the PEBS-via-PT feature from being supported on hybrid systems - Fix perf record/top default commands on systems without a raw PMU registered * tag 'perf_urgent_for_v6.14_rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: perf/x86/intel: Ensure LBRs are disabled when a CPU is starting perf/x86/intel: Fix ARCH_PERFMON_NUM_COUNTER_LEAF perf/x86/intel: Clean up PEBS-via-PT on hybrid perf/x86/rapl: Fix the error checking order
2 parents ff3b373 + c631a2d commit ff1848d

File tree

5 files changed

+54
-32
lines changed

5 files changed

+54
-32
lines changed

arch/x86/events/intel/core.c

Lines changed: 14 additions & 19 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()) {
@@ -4941,11 +4943,6 @@ static void intel_pmu_check_hybrid_pmus(struct x86_hybrid_pmu *pmu)
49414943
else
49424944
pmu->intel_ctrl &= ~(1ULL << GLOBAL_CTRL_EN_PERF_METRICS);
49434945

4944-
if (pmu->intel_cap.pebs_output_pt_available)
4945-
pmu->pmu.capabilities |= PERF_PMU_CAP_AUX_OUTPUT;
4946-
else
4947-
pmu->pmu.capabilities &= ~PERF_PMU_CAP_AUX_OUTPUT;
4948-
49494946
intel_pmu_check_event_constraints(pmu->event_constraints,
49504947
pmu->cntr_mask64,
49514948
pmu->fixed_cntr_mask64,
@@ -5023,9 +5020,6 @@ static bool init_hybrid_pmu(int cpu)
50235020

50245021
pr_info("%s PMU driver: ", pmu->name);
50255022

5026-
if (pmu->intel_cap.pebs_output_pt_available)
5027-
pr_cont("PEBS-via-PT ");
5028-
50295023
pr_cont("\n");
50305024

50315025
x86_pmu_show_pmu_cap(&pmu->pmu);
@@ -5048,8 +5042,11 @@ static void intel_pmu_cpu_starting(int cpu)
50485042

50495043
init_debug_store_on_cpu(cpu);
50505044
/*
5051-
* Deal with CPUs that don't clear their LBRs on power-up.
5045+
* Deal with CPUs that don't clear their LBRs on power-up, and that may
5046+
* even boot with LBRs enabled.
50525047
*/
5048+
if (!static_cpu_has(X86_FEATURE_ARCH_LBR) && x86_pmu.lbr_nr)
5049+
msr_clear_bit(MSR_IA32_DEBUGCTLMSR, DEBUGCTLMSR_LBR_BIT);
50535050
intel_pmu_lbr_reset();
50545051

50555052
cpuc->lbr_sel = NULL;
@@ -6370,11 +6367,9 @@ static __always_inline int intel_pmu_init_hybrid(enum hybrid_pmu_type pmus)
63706367
pmu->intel_cap.capabilities = x86_pmu.intel_cap.capabilities;
63716368
if (pmu->pmu_type & hybrid_small_tiny) {
63726369
pmu->intel_cap.perf_metrics = 0;
6373-
pmu->intel_cap.pebs_output_pt_available = 1;
63746370
pmu->mid_ack = true;
63756371
} else if (pmu->pmu_type & hybrid_big) {
63766372
pmu->intel_cap.perf_metrics = 1;
6377-
pmu->intel_cap.pebs_output_pt_available = 0;
63786373
pmu->late_ack = true;
63796374
}
63806375
}

arch/x86/events/intel/ds.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2578,7 +2578,15 @@ void __init intel_ds_init(void)
25782578
}
25792579
pr_cont("PEBS fmt4%c%s, ", pebs_type, pebs_qual);
25802580

2581-
if (!is_hybrid() && x86_pmu.intel_cap.pebs_output_pt_available) {
2581+
/*
2582+
* The PEBS-via-PT is not supported on hybrid platforms,
2583+
* because not all CPUs of a hybrid machine support it.
2584+
* The global x86_pmu.intel_cap, which only contains the
2585+
* common capabilities, is used to check the availability
2586+
* of the feature. The per-PMU pebs_output_pt_available
2587+
* in a hybrid machine should be ignored.
2588+
*/
2589+
if (x86_pmu.intel_cap.pebs_output_pt_available) {
25822590
pr_cont("PEBS-via-PT, ");
25832591
x86_get_pmu(smp_processor_id())->capabilities |= PERF_PMU_CAP_AUX_OUTPUT;
25842592
}

arch/x86/events/rapl.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,10 @@ static int rapl_pmu_event_init(struct perf_event *event)
370370
unsigned int rapl_pmu_idx;
371371
struct rapl_pmus *rapl_pmus;
372372

373+
/* only look at RAPL events */
374+
if (event->attr.type != event->pmu->type)
375+
return -ENOENT;
376+
373377
/* unsupported modes and filters */
374378
if (event->attr.sample_period) /* no sampling */
375379
return -EINVAL;
@@ -387,21 +391,13 @@ static int rapl_pmu_event_init(struct perf_event *event)
387391
rapl_pmus_scope = rapl_pmus->pmu.scope;
388392

389393
if (rapl_pmus_scope == PERF_PMU_SCOPE_PKG || rapl_pmus_scope == PERF_PMU_SCOPE_DIE) {
390-
/* only look at RAPL package events */
391-
if (event->attr.type != rapl_pmus_pkg->pmu.type)
392-
return -ENOENT;
393-
394394
cfg = array_index_nospec((long)cfg, NR_RAPL_PKG_DOMAINS + 1);
395395
if (!cfg || cfg >= NR_RAPL_PKG_DOMAINS + 1)
396396
return -EINVAL;
397397

398398
bit = cfg - 1;
399399
event->hw.event_base = rapl_model->rapl_pkg_msrs[bit].msr;
400400
} else if (rapl_pmus_scope == PERF_PMU_SCOPE_CORE) {
401-
/* only look at RAPL core events */
402-
if (event->attr.type != rapl_pmus_core->pmu.type)
403-
return -ENOENT;
404-
405401
cfg = array_index_nospec((long)cfg, NR_RAPL_CORE_DOMAINS + 1);
406402
if (!cfg || cfg >= NR_RAPL_PKG_DOMAINS + 1)
407403
return -EINVAL;

arch/x86/include/asm/msr-index.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,8 @@
395395
#define MSR_IA32_PASID_VALID BIT_ULL(31)
396396

397397
/* DEBUGCTLMSR bits (others vary by model): */
398-
#define DEBUGCTLMSR_LBR (1UL << 0) /* last branch recording */
398+
#define DEBUGCTLMSR_LBR_BIT 0 /* last branch recording */
399+
#define DEBUGCTLMSR_LBR (1UL << DEBUGCTLMSR_LBR_BIT)
399400
#define DEBUGCTLMSR_BTF_SHIFT 1
400401
#define DEBUGCTLMSR_BTF (1UL << 1) /* single-step on branches */
401402
#define DEBUGCTLMSR_BUS_LOCK_DETECT (1UL << 2)

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)