- 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 -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEzv7L6UO9uDPlPSfHEsHwGGHeVUoFAmextCMACgkQEsHwGGHe VUr7ag/+PjtbKevbeqjQ0RtkA4TF0gpbYMQdE/h5myY4YnxjmsvuiZoNZztgKU6f 48/NJ2Fjf7cjMnTf+vYSxoTh4FmBcnhz16GyRYeF+JczR3LLf0yN/UmUz6V05kti 4pWdbgqa7pPOIVS2NQUcC+rlHNO0kvlpat42e+TGVAGiZAUOtS4jHGE1RqfXp13G lDdiLKVpReuHpVVtvgTuMSvJzLRV/6zJ/+XExzgZI9b2IIwgt7YVS5pPzYCykm2h YMuC7v4e+0epKxuwbGApzPbCquBJvoBq+aTqU4ZMltpENkEHKlm+9gotNeMBaWA9 xMETydcWCjEIqjDHdC1yWrGTlIHSE92KAM7pHASoCuddPmhaHIh/BuTDxfeJBrNn xUuukR1IVzgXZItiQ/Oz/QMNLI+EBpyBZyfb9LM3wiw0jf10+XyLE9zbMZhIc2Y2 hwuBQ1is/dkdBcWLhaSsjHQIpKwY3iYXXjQ/AToXZV4OS8MlTNL49eSlugEisObD AamLQa2JAvw1wzUDe/vj15hbV2dW5bg43qVcTRJpAtg45FnPHynyJo34z7vqYNcb M1ljZtv+LRQeM3d4EHosrDKhhxlcOiUmUxl9E7dFlmutsusz/zW1/kbNebSj0WJt Ssb3lDO4JTNCI1RLb5I6Soe29FukeKmq/RYwlT49ZmRWxhpU6mE= =ThZf -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
ff1848d81c
5 changed files with 54 additions and 32 deletions
|
@ -4905,20 +4905,22 @@ static inline bool intel_pmu_broken_perf_cap(void)
|
|||
|
||||
static void update_pmu_cap(struct x86_hybrid_pmu *pmu)
|
||||
{
|
||||
unsigned int sub_bitmaps, eax, ebx, ecx, edx;
|
||||
unsigned int cntr, fixed_cntr, ecx, edx;
|
||||
union cpuid35_eax eax;
|
||||
union cpuid35_ebx ebx;
|
||||
|
||||
cpuid(ARCH_PERFMON_EXT_LEAF, &sub_bitmaps, &ebx, &ecx, &edx);
|
||||
cpuid(ARCH_PERFMON_EXT_LEAF, &eax.full, &ebx.full, &ecx, &edx);
|
||||
|
||||
if (ebx & ARCH_PERFMON_EXT_UMASK2)
|
||||
if (ebx.split.umask2)
|
||||
pmu->config_mask |= ARCH_PERFMON_EVENTSEL_UMASK2;
|
||||
if (ebx & ARCH_PERFMON_EXT_EQ)
|
||||
if (ebx.split.eq)
|
||||
pmu->config_mask |= ARCH_PERFMON_EVENTSEL_EQ;
|
||||
|
||||
if (sub_bitmaps & ARCH_PERFMON_NUM_COUNTER_LEAF_BIT) {
|
||||
if (eax.split.cntr_subleaf) {
|
||||
cpuid_count(ARCH_PERFMON_EXT_LEAF, ARCH_PERFMON_NUM_COUNTER_LEAF,
|
||||
&eax, &ebx, &ecx, &edx);
|
||||
pmu->cntr_mask64 = eax;
|
||||
pmu->fixed_cntr_mask64 = ebx;
|
||||
&cntr, &fixed_cntr, &ecx, &edx);
|
||||
pmu->cntr_mask64 = cntr;
|
||||
pmu->fixed_cntr_mask64 = fixed_cntr;
|
||||
}
|
||||
|
||||
if (!intel_pmu_broken_perf_cap()) {
|
||||
|
@ -4941,11 +4943,6 @@ static void intel_pmu_check_hybrid_pmus(struct x86_hybrid_pmu *pmu)
|
|||
else
|
||||
pmu->intel_ctrl &= ~(1ULL << GLOBAL_CTRL_EN_PERF_METRICS);
|
||||
|
||||
if (pmu->intel_cap.pebs_output_pt_available)
|
||||
pmu->pmu.capabilities |= PERF_PMU_CAP_AUX_OUTPUT;
|
||||
else
|
||||
pmu->pmu.capabilities &= ~PERF_PMU_CAP_AUX_OUTPUT;
|
||||
|
||||
intel_pmu_check_event_constraints(pmu->event_constraints,
|
||||
pmu->cntr_mask64,
|
||||
pmu->fixed_cntr_mask64,
|
||||
|
@ -5023,9 +5020,6 @@ static bool init_hybrid_pmu(int cpu)
|
|||
|
||||
pr_info("%s PMU driver: ", pmu->name);
|
||||
|
||||
if (pmu->intel_cap.pebs_output_pt_available)
|
||||
pr_cont("PEBS-via-PT ");
|
||||
|
||||
pr_cont("\n");
|
||||
|
||||
x86_pmu_show_pmu_cap(&pmu->pmu);
|
||||
|
@ -5048,8 +5042,11 @@ static void intel_pmu_cpu_starting(int cpu)
|
|||
|
||||
init_debug_store_on_cpu(cpu);
|
||||
/*
|
||||
* Deal with CPUs that don't clear their LBRs on power-up.
|
||||
* Deal with CPUs that don't clear their LBRs on power-up, and that may
|
||||
* even boot with LBRs enabled.
|
||||
*/
|
||||
if (!static_cpu_has(X86_FEATURE_ARCH_LBR) && x86_pmu.lbr_nr)
|
||||
msr_clear_bit(MSR_IA32_DEBUGCTLMSR, DEBUGCTLMSR_LBR_BIT);
|
||||
intel_pmu_lbr_reset();
|
||||
|
||||
cpuc->lbr_sel = NULL;
|
||||
|
@ -6370,11 +6367,9 @@ static __always_inline int intel_pmu_init_hybrid(enum hybrid_pmu_type pmus)
|
|||
pmu->intel_cap.capabilities = x86_pmu.intel_cap.capabilities;
|
||||
if (pmu->pmu_type & hybrid_small_tiny) {
|
||||
pmu->intel_cap.perf_metrics = 0;
|
||||
pmu->intel_cap.pebs_output_pt_available = 1;
|
||||
pmu->mid_ack = true;
|
||||
} else if (pmu->pmu_type & hybrid_big) {
|
||||
pmu->intel_cap.perf_metrics = 1;
|
||||
pmu->intel_cap.pebs_output_pt_available = 0;
|
||||
pmu->late_ack = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2578,7 +2578,15 @@ void __init intel_ds_init(void)
|
|||
}
|
||||
pr_cont("PEBS fmt4%c%s, ", pebs_type, pebs_qual);
|
||||
|
||||
if (!is_hybrid() && x86_pmu.intel_cap.pebs_output_pt_available) {
|
||||
/*
|
||||
* The PEBS-via-PT is not supported on hybrid platforms,
|
||||
* because not all CPUs of a hybrid machine support it.
|
||||
* The global x86_pmu.intel_cap, which only contains the
|
||||
* common capabilities, is used to check the availability
|
||||
* of the feature. The per-PMU pebs_output_pt_available
|
||||
* in a hybrid machine should be ignored.
|
||||
*/
|
||||
if (x86_pmu.intel_cap.pebs_output_pt_available) {
|
||||
pr_cont("PEBS-via-PT, ");
|
||||
x86_get_pmu(smp_processor_id())->capabilities |= PERF_PMU_CAP_AUX_OUTPUT;
|
||||
}
|
||||
|
|
|
@ -370,6 +370,10 @@ static int rapl_pmu_event_init(struct perf_event *event)
|
|||
unsigned int rapl_pmu_idx;
|
||||
struct rapl_pmus *rapl_pmus;
|
||||
|
||||
/* only look at RAPL events */
|
||||
if (event->attr.type != event->pmu->type)
|
||||
return -ENOENT;
|
||||
|
||||
/* unsupported modes and filters */
|
||||
if (event->attr.sample_period) /* no sampling */
|
||||
return -EINVAL;
|
||||
|
@ -387,10 +391,6 @@ static int rapl_pmu_event_init(struct perf_event *event)
|
|||
rapl_pmus_scope = rapl_pmus->pmu.scope;
|
||||
|
||||
if (rapl_pmus_scope == PERF_PMU_SCOPE_PKG || rapl_pmus_scope == PERF_PMU_SCOPE_DIE) {
|
||||
/* only look at RAPL package events */
|
||||
if (event->attr.type != rapl_pmus_pkg->pmu.type)
|
||||
return -ENOENT;
|
||||
|
||||
cfg = array_index_nospec((long)cfg, NR_RAPL_PKG_DOMAINS + 1);
|
||||
if (!cfg || cfg >= NR_RAPL_PKG_DOMAINS + 1)
|
||||
return -EINVAL;
|
||||
|
@ -398,10 +398,6 @@ static int rapl_pmu_event_init(struct perf_event *event)
|
|||
bit = cfg - 1;
|
||||
event->hw.event_base = rapl_model->rapl_pkg_msrs[bit].msr;
|
||||
} else if (rapl_pmus_scope == PERF_PMU_SCOPE_CORE) {
|
||||
/* only look at RAPL core events */
|
||||
if (event->attr.type != rapl_pmus_core->pmu.type)
|
||||
return -ENOENT;
|
||||
|
||||
cfg = array_index_nospec((long)cfg, NR_RAPL_CORE_DOMAINS + 1);
|
||||
if (!cfg || cfg >= NR_RAPL_PKG_DOMAINS + 1)
|
||||
return -EINVAL;
|
||||
|
|
|
@ -395,7 +395,8 @@
|
|||
#define MSR_IA32_PASID_VALID BIT_ULL(31)
|
||||
|
||||
/* DEBUGCTLMSR bits (others vary by model): */
|
||||
#define DEBUGCTLMSR_LBR (1UL << 0) /* last branch recording */
|
||||
#define DEBUGCTLMSR_LBR_BIT 0 /* last branch recording */
|
||||
#define DEBUGCTLMSR_LBR (1UL << DEBUGCTLMSR_LBR_BIT)
|
||||
#define DEBUGCTLMSR_BTF_SHIFT 1
|
||||
#define DEBUGCTLMSR_BTF (1UL << 1) /* single-step on branches */
|
||||
#define DEBUGCTLMSR_BUS_LOCK_DETECT (1UL << 2)
|
||||
|
|
|
@ -188,11 +188,33 @@ union cpuid10_edx {
|
|||
* detection/enumeration details:
|
||||
*/
|
||||
#define ARCH_PERFMON_EXT_LEAF 0x00000023
|
||||
#define ARCH_PERFMON_EXT_UMASK2 0x1
|
||||
#define ARCH_PERFMON_EXT_EQ 0x2
|
||||
#define ARCH_PERFMON_NUM_COUNTER_LEAF_BIT 0x1
|
||||
#define ARCH_PERFMON_NUM_COUNTER_LEAF 0x1
|
||||
|
||||
union cpuid35_eax {
|
||||
struct {
|
||||
unsigned int leaf0:1;
|
||||
/* Counters Sub-Leaf */
|
||||
unsigned int cntr_subleaf:1;
|
||||
/* Auto Counter Reload Sub-Leaf */
|
||||
unsigned int acr_subleaf:1;
|
||||
/* Events Sub-Leaf */
|
||||
unsigned int events_subleaf:1;
|
||||
unsigned int reserved:28;
|
||||
} split;
|
||||
unsigned int full;
|
||||
};
|
||||
|
||||
union cpuid35_ebx {
|
||||
struct {
|
||||
/* UnitMask2 Supported */
|
||||
unsigned int umask2:1;
|
||||
/* EQ-bit Supported */
|
||||
unsigned int eq:1;
|
||||
unsigned int reserved:30;
|
||||
} split;
|
||||
unsigned int full;
|
||||
};
|
||||
|
||||
/*
|
||||
* Intel Architectural LBR CPUID detection/enumeration details:
|
||||
*/
|
||||
|
|
Loading…
Add table
Reference in a new issue