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

Merge tag 'perf_urgent_for_v6.1_rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf fixes from Borislav Petkov:

 - Fix an intel PT erratum where CPUs do not support single range output
   for more than 4K

 - Fix a NULL ptr dereference which can happen after an NMI interferes
   with the event enabling dance in amd_pmu_enable_all()

 - Free the events array too when freeing uncore contexts on CPU online,
   thereby fixing a memory leak

 - Improve the pending SIGTRAP check

* tag 'perf_urgent_for_v6.1_rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  perf/x86/intel/pt: Fix sampling using single range output
  perf/x86/amd: Fix crash due to race between amd_pmu_enable_all, perf NMI and throttling
  perf/x86/amd/uncore: Fix memory leak for events array
  perf: Improve missing SIGTRAP checking
parents 6a211a75 ce0d998b
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -861,8 +861,7 @@ static int amd_pmu_handle_irq(struct pt_regs *regs)
	pmu_enabled = cpuc->enabled;
	cpuc->enabled = 0;

	/* stop everything (includes BRS) */
	amd_pmu_disable_all();
	amd_brs_disable_all();

	/* Drain BRS is in use (could be inactive) */
	if (cpuc->lbr_users)
@@ -873,7 +872,7 @@ static int amd_pmu_handle_irq(struct pt_regs *regs)

	cpuc->enabled = pmu_enabled;
	if (pmu_enabled)
		amd_pmu_enable_all(0);
		amd_brs_enable_all();

	return amd_pmu_adjust_nmi_window(handled);
}
+1 −0
Original line number Diff line number Diff line
@@ -553,6 +553,7 @@ static void uncore_clean_online(void)

	hlist_for_each_entry_safe(uncore, n, &uncore_unused_list, node) {
		hlist_del(&uncore->node);
		kfree(uncore->events);
		kfree(uncore);
	}
}
+9 −0
Original line number Diff line number Diff line
@@ -1263,6 +1263,15 @@ static int pt_buffer_try_single(struct pt_buffer *buf, int nr_pages)
	if (1 << order != nr_pages)
		goto out;

	/*
	 * Some processors cannot always support single range for more than
	 * 4KB - refer errata TGL052, ADL037 and RPL017. Future processors might
	 * also be affected, so for now rather than trying to keep track of
	 * which ones, just disable it for all.
	 */
	if (nr_pages > 1)
		goto out;

	buf->single = true;
	buf->nr_pages = nr_pages;
	ret = 0;
+19 −6
Original line number Diff line number Diff line
@@ -9306,14 +9306,27 @@ static int __perf_event_overflow(struct perf_event *event,
	}

	if (event->attr.sigtrap) {
		/*
		 * Should not be able to return to user space without processing
		 * pending_sigtrap (kernel events can overflow multiple times).
		 */
		WARN_ON_ONCE(event->pending_sigtrap && event->attr.exclude_kernel);
		unsigned int pending_id = 1;

		if (regs)
			pending_id = hash32_ptr((void *)instruction_pointer(regs)) ?: 1;
		if (!event->pending_sigtrap) {
			event->pending_sigtrap = 1;
			event->pending_sigtrap = pending_id;
			local_inc(&event->ctx->nr_pending);
		} else if (event->attr.exclude_kernel) {
			/*
			 * Should not be able to return to user space without
			 * consuming pending_sigtrap; with exceptions:
			 *
			 *  1. Where !exclude_kernel, events can overflow again
			 *     in the kernel without returning to user space.
			 *
			 *  2. Events that can overflow again before the IRQ-
			 *     work without user space progress (e.g. hrtimer).
			 *     To approximate progress (with false negatives),
			 *     check 32-bit hash of the current IP.
			 */
			WARN_ON_ONCE(event->pending_sigtrap != pending_id);
		}
		event->pending_addr = data->addr;
		irq_work_queue(&event->pending_irq);