In the Linux kernel, the following vulnerability has been resolved: perf/x86: Move event pointer setup earlier in x86pmuenable() A production AMD EPYC system crashed with a NULL pointer dereference in the PMU NMI handler: BUG: kernel NULL pointer dereference, address: 0000000000000198 RIP: x86perfeventupdate+0xc/0xa0 Call Trace: <NMI> amdpmuv2handleirq+0x1a6/0x390 perfeventnmihandler+0x24/0x40 The faulting instruction is cmpq $0x0, 0x198(%rdi) with RDI=0, corresponding to the if (unlikely(!hwc->event_base)) check in x86perfeventupdate() where hwc = &event->hw and event is NULL. drgn inspection of the vmcore on CPU 106 showed a mismatch between cpuc->activemask and cpuc->events[]: activemask: 0x1e (bits 1, 2, 3, 4) events[1]: 0xff1100136cbd4f38 (valid) events[2]: 0x0 (NULL, but activemask bit 2 set) events[3]: 0xff1100076fd2cf38 (valid) events[4]: 0xff1100079e990a90 (valid) The event that should occupy events[2] was found in eventlist[2] with hw.idx=2 and hw.state=0x0, confirming x86pmustart() had run (which clears hw.state and sets activemask) but events[2] was never populated. Another event (eventlist[0]) had hw.state=0x7 (STOPPED|UPTODATE|ARCH), showing it was stopped when the PMU rescheduled events, confirming the throttle-then-reschedule sequence occurred. The root cause is commit 7e772a93eb61 ("perf/x86: Fix NULL event access and potential PEBS record loss") which moved the cpuc->events[idx] assignment out of x86pmustart() and into step 2 of x86pmuenable(), after the PERFHESARCH check. This broke any path that calls pmu->start() without going through x86pmuenable() -- specifically the unthrottle path: perfadjustfrequnthrevents() -> perfeventunthrottlegroup() -> perfeventunthrottle() -> event->pmu->start(event, 0) -> x86pmustart() // sets activemask but not events[] The race sequence is: 1. A group of perf events overflows, triggering group throttle via perfeventthrottlegroup(). All events are stopped: activemask bits cleared, events[] preserved (x86pmustop no longer clears events[] after commit 7e772a93eb61). 2. While still throttled (PERFHESSTOPPED), x86pmuenable() runs due to other scheduling activity. Stopped events that need to move counters get PERFHESARCH set and events[oldidx] cleared. In step 2 of x86pmuenable(), PERFHESARCH causes these events to be skipped -- events[newidx] is never set. 3. The timer tick unthrottles the group via pmu->start(). Since commit 7e772a93eb61 removed the events[] assignment from x86pmustart(), activemask[newidx] is set but events[newidx] remains NULL. 4. A PMC overflow NMI fires. The handler iterates active counters, finds activemask[2] set, reads events[2] which is NULL, and crashes dereferencing it. Move the cpuc->events[hwc->idx] assignment in x86pmuenable() to before the PERFHES_ARCH check, so that events[] is populated even for events that are not immediately started. This ensures the unthrottle path via pmu->start() always finds a valid event pointer.