Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'perf-urgent-2025-12-12' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf event fixes from Ingo Molnar:

- Fix NULL pointer dereference crash in the Intel PMU driver

- Fix missing read event generation on task exit

- Fix AMD uncore driver init error handling

- Fix whitespace noise

* tag 'perf-urgent-2025-12-12' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf/x86/intel: Fix NULL event dereference crash in handle_pmi_common()
perf/core: Fix missing read event generation on task exit
perf/x86/amd/uncore: Fix the return value of amd_uncore_df_event_init() on error
perf/uprobes: Remove <space><Tab> whitespace noise

+20 -18
+1 -4
arch/x86/events/amd/uncore.c
··· 656 656 struct hw_perf_event *hwc = &event->hw; 657 657 int ret = amd_uncore_event_init(event); 658 658 659 - if (ret || pmu_version < 2) 660 - return ret; 661 - 662 659 hwc->config = event->attr.config & 663 660 (pmu_version >= 2 ? AMD64_PERFMON_V2_RAW_EVENT_MASK_NB : 664 661 AMD64_RAW_EVENT_MASK_NB); 665 662 666 - return 0; 663 + return ret; 667 664 } 668 665 669 666 static int amd_uncore_df_add(struct perf_event *event, int flags)
+3
arch/x86/events/intel/core.c
··· 3378 3378 3379 3379 if (!test_bit(bit, cpuc->active_mask)) 3380 3380 continue; 3381 + /* Event may have already been cleared: */ 3382 + if (!event) 3383 + continue; 3381 3384 3382 3385 /* 3383 3386 * There may be unprocessed PEBS records in the PEBS buffer,
+12 -10
kernel/events/core.c
··· 2317 2317 perf_event__header_size(leader); 2318 2318 } 2319 2319 2320 - static void sync_child_event(struct perf_event *child_event); 2321 - 2322 2320 static void perf_child_detach(struct perf_event *event) 2323 2321 { 2324 2322 struct perf_event *parent_event = event->parent; ··· 2335 2337 lockdep_assert_held(&parent_event->child_mutex); 2336 2338 */ 2337 2339 2338 - sync_child_event(event); 2339 2340 list_del_init(&event->child_list); 2340 2341 } 2341 2342 ··· 4585 4588 static void perf_remove_from_owner(struct perf_event *event); 4586 4589 static void perf_event_exit_event(struct perf_event *event, 4587 4590 struct perf_event_context *ctx, 4591 + struct task_struct *task, 4588 4592 bool revoke); 4589 4593 4590 4594 /* ··· 4613 4615 4614 4616 modified = true; 4615 4617 4616 - perf_event_exit_event(event, ctx, false); 4618 + perf_event_exit_event(event, ctx, ctx->task, false); 4617 4619 } 4618 4620 4619 4621 raw_spin_lock_irqsave(&ctx->lock, flags); ··· 12516 12518 /* 12517 12519 * De-schedule the event and mark it REVOKED. 12518 12520 */ 12519 - perf_event_exit_event(event, ctx, true); 12521 + perf_event_exit_event(event, ctx, ctx->task, true); 12520 12522 12521 12523 /* 12522 12524 * All _free_event() bits that rely on event->pmu: ··· 14073 14075 } 14074 14076 EXPORT_SYMBOL_GPL(perf_pmu_migrate_context); 14075 14077 14076 - static void sync_child_event(struct perf_event *child_event) 14078 + static void sync_child_event(struct perf_event *child_event, 14079 + struct task_struct *task) 14077 14080 { 14078 14081 struct perf_event *parent_event = child_event->parent; 14079 14082 u64 child_val; 14080 14083 14081 14084 if (child_event->attr.inherit_stat) { 14082 - struct task_struct *task = child_event->ctx->task; 14083 - 14084 14085 if (task && task != TASK_TOMBSTONE) 14085 14086 perf_event_read_event(child_event, task); 14086 14087 } ··· 14098 14101 14099 14102 static void 14100 14103 perf_event_exit_event(struct perf_event *event, 14101 - struct perf_event_context *ctx, bool revoke) 14104 + struct perf_event_context *ctx, 14105 + struct task_struct *task, 14106 + bool revoke) 14102 14107 { 14103 14108 struct perf_event *parent_event = event->parent; 14104 14109 unsigned long detach_flags = DETACH_EXIT; ··· 14123 14124 mutex_lock(&parent_event->child_mutex); 14124 14125 /* PERF_ATTACH_ITRACE might be set concurrently */ 14125 14126 attach_state = READ_ONCE(event->attach_state); 14127 + 14128 + if (attach_state & PERF_ATTACH_CHILD) 14129 + sync_child_event(event, task); 14126 14130 } 14127 14131 14128 14132 if (revoke) ··· 14217 14215 perf_event_task(task, ctx, 0); 14218 14216 14219 14217 list_for_each_entry_safe(child_event, next, &ctx->event_list, event_entry) 14220 - perf_event_exit_event(child_event, ctx, false); 14218 + perf_event_exit_event(child_event, ctx, exit ? task : NULL, false); 14221 14219 14222 14220 mutex_unlock(&ctx->mutex); 14223 14221
+4 -4
kernel/events/uprobes.c
··· 79 79 * The generic code assumes that it has two members of unknown type 80 80 * owned by the arch-specific code: 81 81 * 82 - * insn - copy_insn() saves the original instruction here for 82 + * insn - copy_insn() saves the original instruction here for 83 83 * arch_uprobe_analyze_insn(). 84 84 * 85 85 * ixol - potentially modified instruction to execute out of ··· 107 107 * allocated. 108 108 */ 109 109 struct xol_area { 110 - wait_queue_head_t wq; /* if all slots are busy */ 111 - unsigned long *bitmap; /* 0 = free slot */ 110 + wait_queue_head_t wq; /* if all slots are busy */ 111 + unsigned long *bitmap; /* 0 = free slot */ 112 112 113 113 struct page *page; 114 114 /* ··· 116 116 * itself. The probed process or a naughty kernel module could make 117 117 * the vma go away, and we must handle that reasonably gracefully. 118 118 */ 119 - unsigned long vaddr; /* Page(s) of instruction slots */ 119 + unsigned long vaddr; /* Page(s) of instruction slots */ 120 120 }; 121 121 122 122 static void uprobe_warn(struct task_struct *t, const char *msg)