Commit ff1848d8 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
parents ff3b373e c631a2de
Loading
Loading
Loading
Loading
+14 −19
Original line number Diff line number Diff line
@@ -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;
		}
	}
+9 −1
Original line number Diff line number Diff line
@@ -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;
			}
+4 −8
Original line number Diff line number Diff line
@@ -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;
+2 −1
Original line number Diff line number Diff line
@@ -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)
+25 −3
Original line number Diff line number Diff line
@@ -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:
 */