History

Merge tag 'perf-urgent-2026-03-01' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf events fixes from Ingo Molnar: - Fix lock ordering bug found by lockdep in perf_event_wakeup() - Fix uncore counter enumeration on Granite Rapids and Sierra Forest - Fix perf_mmap() refcount bug found by Syzkaller - Fix __perf_event_overflow() vs perf_remove_from_context() race * tag 'perf-urgent-2026-03-01' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: perf: Fix __perf_event_overflow() vs perf_remove_from_context() race perf/core: Fix refcount bug and potential UAF in perf_mmap perf/x86/intel/uncore: Add per-scheduler IMC CAS count events perf/core: Fix invalid wait context in ctx_sched_in()

Linus Torvalds committed 8 months ago

Commit cb36eab2 parents b410220 c9bc1752 files · +89 −22Browse files

Unified · Split

2 files
  1. arch/x86/events/intel/uncore_snbep.c +27 −1
  2. kernel/events/core.c +62 −21
arch/x86/events/intel/uncore_snbep.c+27−1
@@ -6497,6 +6497,32 @@ static struct intel_uncore_type gnr_uncore_ubox = { · 6496 unmodified lines
6497 .attr_update = uncore_alias_groups,6497 .attr_update = uncore_alias_groups,
6498};6498};
6499 6499
6500static struct uncore_event_desc gnr_uncore_imc_events[] = {
6501 INTEL_UNCORE_EVENT_DESC(clockticks, "event=0x01,umask=0x00"),
6502 INTEL_UNCORE_EVENT_DESC(cas_count_read_sch0, "event=0x05,umask=0xcf"),
6503 INTEL_UNCORE_EVENT_DESC(cas_count_read_sch0.scale, "6.103515625e-5"),
6504 INTEL_UNCORE_EVENT_DESC(cas_count_read_sch0.unit, "MiB"),
6505 INTEL_UNCORE_EVENT_DESC(cas_count_read_sch1, "event=0x06,umask=0xcf"),
6506 INTEL_UNCORE_EVENT_DESC(cas_count_read_sch1.scale, "6.103515625e-5"),
6507 INTEL_UNCORE_EVENT_DESC(cas_count_read_sch1.unit, "MiB"),
6508 INTEL_UNCORE_EVENT_DESC(cas_count_write_sch0, "event=0x05,umask=0xf0"),
6509 INTEL_UNCORE_EVENT_DESC(cas_count_write_sch0.scale, "6.103515625e-5"),
6510 INTEL_UNCORE_EVENT_DESC(cas_count_write_sch0.unit, "MiB"),
6511 INTEL_UNCORE_EVENT_DESC(cas_count_write_sch1, "event=0x06,umask=0xf0"),
6512 INTEL_UNCORE_EVENT_DESC(cas_count_write_sch1.scale, "6.103515625e-5"),
6513 INTEL_UNCORE_EVENT_DESC(cas_count_write_sch1.unit, "MiB"),
6514 { /* end: all zeroes */ },
6515};
6516
6517static struct intel_uncore_type gnr_uncore_imc = {
6518 SPR_UNCORE_MMIO_COMMON_FORMAT(),
6519 .name = "imc",
6520 .fixed_ctr_bits = 48,
6521 .fixed_ctr = SNR_IMC_MMIO_PMON_FIXED_CTR,
6522 .fixed_ctl = SNR_IMC_MMIO_PMON_FIXED_CTL,
6523 .event_descs = gnr_uncore_imc_events,
6524};
6525
6500static struct intel_uncore_type gnr_uncore_pciex8 = {6526static struct intel_uncore_type gnr_uncore_pciex8 = {
6501 SPR_UNCORE_PCI_COMMON_FORMAT(),6527 SPR_UNCORE_PCI_COMMON_FORMAT(),
6502 .name = "pciex8",6528 .name = "pciex8",
@@ -6544,7 +6570,7 @@ static struct intel_uncore_type *gnr_uncores[UNCORE_GNR_NUM_UNCORE_TYPES] = { · 41 unmodified lines
6544 NULL,6570 NULL,
6545 &spr_uncore_pcu,6571 &spr_uncore_pcu,
6546 &gnr_uncore_ubox,6572 &gnr_uncore_ubox,
6547 &spr_uncore_imc,6573 &gnr_uncore_imc,
6548 NULL,6574 NULL,
6549 &gnr_uncore_upi,6575 &gnr_uncore_upi,
6550 NULL,6576 NULL,
kernel/events/core.c+62−21
@@ -4138,7 +4138,8 @@ static int merge_sched_in(struct perf_event *event, void *data) · 4137 unmodified lines
4138 if (*perf_event_fasync(event))4138 if (*perf_event_fasync(event))
4139 event->pending_kill = POLL_ERR;4139 event->pending_kill = POLL_ERR;
4140 4140
4141 perf_event_wakeup(event);4141 event->pending_wakeup = 1;
4142 irq_work_queue(&event->pending_irq);
4142 } else {4143 } else {
4143 struct perf_cpu_pmu_context *cpc = this_cpc(event->pmu_ctx->pmu);4144 struct perf_cpu_pmu_context *cpc = this_cpc(event->pmu_ctx->pmu);
4144 4145
@@ -7464,28 +7465,28 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma) · 3319 unmodified lines
7464 ret = perf_mmap_aux(vma, event, nr_pages);7465 ret = perf_mmap_aux(vma, event, nr_pages);
7465 if (ret)7466 if (ret)
7466 return ret;7467 return ret;
7467 }
7468 7468
7469 /*7469 /*
7470 * Since pinned accounting is per vm we cannot allow fork() to copy our7470 * Since pinned accounting is per vm we cannot allow fork() to copy our
7471 * vma.7471 * vma.
7472 */7472 */
7473 vm_flags_set(vma, VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP);7473 vm_flags_set(vma, VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP);
7474 vma->vm_ops = &perf_mmap_vmops;7474 vma->vm_ops = &perf_mmap_vmops;
7475 7475
7476 mapped = get_mapped(event, event_mapped);7476 mapped = get_mapped(event, event_mapped);
7477 if (mapped)7477 if (mapped)
7478 mapped(event, vma->vm_mm);7478 mapped(event, vma->vm_mm);
7479 7479
7480 /*7480 /*
7481 * Try to map it into the page table. On fail, invoke7481 * Try to map it into the page table. On fail, invoke
7482 * perf_mmap_close() to undo the above, as the callsite expects7482 * perf_mmap_close() to undo the above, as the callsite expects
7483 * full cleanup in this case and therefore does not invoke7483 * full cleanup in this case and therefore does not invoke
7484 * vmops::close().7484 * vmops::close().
7485 */7485 */
7486 ret = map_range(event->rb, vma);7486 ret = map_range(event->rb, vma);
7487 if (ret)7487 if (ret)
7488 perf_mmap_close(vma);7488 perf_mmap_close(vma);
7489 }
7489 7490
7490 return ret;7491 return ret;
7491}7492}
@@ -10776,6 +10777,13 @@ int perf_event_overflow(struct perf_event *event, · 3284 unmodified lines
10776 struct perf_sample_data *data,10777 struct perf_sample_data *data,
10777 struct pt_regs *regs)10778 struct pt_regs *regs)
10778{10779{
10780 /*
10781 * Entry point from hardware PMI, interrupts should be disabled here.
10782 * This serializes us against perf_event_remove_from_context() in
10783 * things like perf_event_release_kernel().
10784 */
10785 lockdep_assert_irqs_disabled();
10786
10779 return __perf_event_overflow(event, 1, data, regs);10787 return __perf_event_overflow(event, 1, data, regs);
10780}10788}
10781 10789
@@ -10852,6 +10860,19 @@ static void perf_swevent_event(struct perf_event *event, u64 nr, · 70 unmodified lines
10852{10860{
10853 struct hw_perf_event *hwc = &event->hw;10861 struct hw_perf_event *hwc = &event->hw;
10854 10862
10863 /*
10864 * This is:
10865 * - software preempt
10866 * - tracepoint preempt
10867 * - tp_target_task irq (ctx->lock)
10868 * - uprobes preempt/irq
10869 * - kprobes preempt/irq
10870 * - hw_breakpoint irq
10871 *
10872 * Any of these are sufficient to hold off RCU and thus ensure @event
10873 * exists.
10874 */
10875 lockdep_assert_preemption_disabled();
10855 local64_add(nr, &event->count);10876 local64_add(nr, &event->count);
10856 10877
10857 if (!regs)10878 if (!regs)
@@ -10860,6 +10881,16 @@ static void perf_swevent_event(struct perf_event *event, u64 nr, · 2 unmodified lines
10860 if (!is_sampling_event(event))10881 if (!is_sampling_event(event))
10861 return;10882 return;
10862 10883
10884 /*
10885 * Serialize against event_function_call() IPIs like normal overflow
10886 * event handling. Specifically, must not allow
10887 * perf_event_release_kernel() -> perf_remove_from_context() to make
10888 * progress and 'release' the event from under us.
10889 */
10890 guard(irqsave)();
10891 if (event->state != PERF_EVENT_STATE_ACTIVE)
10892 return;
10893
10863 if ((event->attr.sample_type & PERF_SAMPLE_PERIOD) && !event->attr.freq) {10894 if ((event->attr.sample_type & PERF_SAMPLE_PERIOD) && !event->attr.freq) {
10864 data->period = nr;10895 data->period = nr;
10865 return perf_swevent_overflow(event, 1, data, regs);10896 return perf_swevent_overflow(event, 1, data, regs);
@@ -11358,6 +11389,11 @@ void perf_tp_event(u16 event_type, u64 count, void *record, int entry_size, · 492 unmodified lines
11358 struct perf_sample_data data;11389 struct perf_sample_data data;
11359 struct perf_event *event;11390 struct perf_event *event;
11360 11391
11392 /*
11393 * Per being a tracepoint, this runs with preemption disabled.
11394 */
11395 lockdep_assert_preemption_disabled();
11396
11361 struct perf_raw_record raw = {11397 struct perf_raw_record raw = {
11362 .frag = {11398 .frag = {
11363 .size = entry_size,11399 .size = entry_size,
@@ -11690,6 +11726,11 @@ void perf_bp_event(struct perf_event *bp, void *data) · 326 unmodified lines
11690 struct perf_sample_data sample;11726 struct perf_sample_data sample;
11691 struct pt_regs *regs = data;11727 struct pt_regs *regs = data;
11692 11728
11729 /*
11730 * Exception context, will have interrupts disabled.
11731 */
11732 lockdep_assert_irqs_disabled();
11733
11693 perf_sample_data_init(&sample, bp->attr.bp_addr, 0);11734 perf_sample_data_init(&sample, bp->attr.bp_addr, 0);
11694 11735
11695 if (!bp->hw.state && !perf_exclude_event(bp, regs))11736 if (!bp->hw.state && !perf_exclude_event(bp, regs))
@@ -12154,7 +12195,7 @@ static enum hrtimer_restart perf_swevent_hrtimer(struct hrtimer *hrtimer) · 458 unmodified lines
12154 12195
12155 if (regs && !perf_exclude_event(event, regs)) {12196 if (regs && !perf_exclude_event(event, regs)) {
12156 if (!(event->attr.exclude_idle && is_idle_task(current)))12197 if (!(event->attr.exclude_idle && is_idle_task(current)))
12157 if (__perf_event_overflow(event, 1, &data, regs))12198 if (perf_event_overflow(event, &data, regs))
12158 ret = HRTIMER_NORESTART;12199 ret = HRTIMER_NORESTART;
12159 }12200 }
12160 12201