arch/x86/events/amd/brs.c | 9 +++-- arch/x86/events/amd/lbr.c | 16 ++++----- arch/x86/events/intel/lbr.c | 65 ++++++++++++++++++++----------------- drivers/perf/arm_brbe.c | 2 +- include/linux/perf_event.h | 17 ---------- kernel/events/core.c | 15 ++++++--- 6 files changed, 58 insertions(+), 66 deletions(-)
These three fixes were found while adding BRBE support for bpf_get_branch_snapshot() on arm64 and were carried in that series until v6 [1]. They do not depend on it, so they go on their own; the version number continues from that series to avoid two numbering schemes for the same patches. Patch 1 stops __perf_pmu_sched_task() passing a NULL pmu_ctx to pmu->sched_task(). armv8pmu_sched_task() is the only implementation that dereferences the argument, so the oops needs BRBE. Patch 2 makes perf_pmu_sched_task() visit PMUs whose events are all CPU-wide. They are skipped today on every switch to a task that has a perf context but no event on that PMU, so branch records leak across the task boundary with perf record -b -a. intel_pmu_lbr_add() calls perf_sched_cb_inc() unconditionally, so x86 LBR is affected the same way. Patch 3 has each caller fill struct perf_branch_entry in one assignment rather than clearing the bitfields first, and drops perf_clear_branch_entry_bitfields(). The helper had drifted from the struct: new_type and priv were never cleared, and arm_pmuv3.c allocates the per-CPU branch stack with kmalloc(). Tested on a 128 CPU arm64 machine with BRBE. A WARN_ON_ONCE() at the gate patch 2 adds to perf_ctx_sched_task_cb() fires within seconds of running perf record -b -a alongside a task-bound event pinned to a different CPU. Also built for x86, which patch 3 touches. Changes in v7: - Patch 1: pass &cpc->epc unconditionally. cpc->task_epc is NULL there both before and after patch 2, so the conditional was dead. - Patch 2: gate perf_pmu_sched_task() on cpc->task_epc alone. It is never set without a task context scheduled in, so the cpuctx->task_ctx test was redundant and the two gates are now inverses. - Patch 3: fill the entry at each site instead of renaming the helper, as suggested by Peter. - Dropped the v6 review tags, all three patches changed. Changes in v6: - Split the sched_task() fix into patches 1 and 2; the NULL dereference and the missed dispatch are separate bugs with different reachability. - Gate perf_ctx_sched_task_cb() on cpc->task_epc. v5 removed the early return in perf_pmu_sched_task() without it, so both paths ran for a task whose event for that PMU is pinned to another CPU. Caught by the WARN_ON_ONCE() described above. - Tag patches 1 and 2 for stable. - Send separately from the BRBE series, rebased onto tip perf/core. [1] https://lore.kernel.org/all/20260616155716.2631508-1-puranjay@kernel.org/ v6: https://lore.kernel.org/bpf/20260806135224.3267890-1-puranjay@kernel.org/ Puranjay Mohan (3): perf/core: Fix NULL pmu_ctx passed to pmu->sched_task() perf/core: Run sched_task() for PMUs with only CPU-wide events perf/core: Fill branch entries with a single assignment arch/x86/events/amd/brs.c | 9 +++-- arch/x86/events/amd/lbr.c | 16 ++++----- arch/x86/events/intel/lbr.c | 65 ++++++++++++++++++++----------------- drivers/perf/arm_brbe.c | 2 +- include/linux/perf_event.h | 17 ---------- kernel/events/core.c | 15 ++++++--- 6 files changed, 58 insertions(+), 66 deletions(-) -- 2.53.0-Meta
On Mon, Aug 10, 2026 at 06:35:33AM -0700, Puranjay Mohan wrote: > Puranjay Mohan (3): > perf/core: Fix NULL pmu_ctx passed to pmu->sched_task() > perf/core: Run sched_task() for PMUs with only CPU-wide events > perf/core: Fill branch entries with a single assignment > > arch/x86/events/amd/brs.c | 9 +++-- > arch/x86/events/amd/lbr.c | 16 ++++----- > arch/x86/events/intel/lbr.c | 65 ++++++++++++++++++++----------------- > drivers/perf/arm_brbe.c | 2 +- > include/linux/perf_event.h | 17 ---------- > kernel/events/core.c | 15 ++++++--- > 6 files changed, 58 insertions(+), 66 deletions(-) > Found this series ... I'll feed it to the robots and barring them screaming I'll push it out to -tip.
Hi Puranjay,
On 8/10/2026 9:35 PM, Puranjay Mohan wrote:
> These three fixes were found while adding BRBE support for
> bpf_get_branch_snapshot() on arm64 and were carried in that series until
> v6 [1]. They do not depend on it, so they go on their own; the version
> number continues from that series to avoid two numbering schemes for the
> same patches.
perf record -C <cpu> -b [<command>] triggers a NULL pointer dereference
in armv8pmu_sched_task().
Commit fa9d27773873 ("perf: arm_pmu: Kill last use of per-CPU cpu_armpmu
pointer") changed armv8pmu_sched_task() from reading the per-CPU
cpu_armpmu variable to dereferencing pmu_ctx->pmu via
to_arm_pmu(pmu_ctx->pmu). Meanwhile, commit bd2756811766 ("perf:
Rewrite core context handling") made __perf_pmu_sched_task() pass
cpc->task_epc to pmu->sched_task(). cpc->task_epc is only non-NULL
while a task context is scheduled in; CPU-bound events do not schedule a
task context, so cpc->task_epc stays NULL. The NULL argument is dereferenced
and crashes.
With the patches applied, perf record -C <cpu> -b no longer crashes,
and system-wide perf record -b -e <event> -a alongside a task-bound event
on a different CPU runs without any WARN_ON.
Tested-by: Yifan Wu <wuyifan50@huawei.com>
On Thu, Sep 3, 2026 at 7:45 PM wuyifan <wuyifan50@huawei.com> wrote:
>
> Hi Puranjay,
>
> On 8/10/2026 9:35 PM, Puranjay Mohan wrote:
> > These three fixes were found while adding BRBE support for
> > bpf_get_branch_snapshot() on arm64 and were carried in that series until
> > v6 [1]. They do not depend on it, so they go on their own; the version
> > number continues from that series to avoid two numbering schemes for the
> > same patches.
> perf record -C <cpu> -b [<command>] triggers a NULL pointer dereference
> in armv8pmu_sched_task().
>
> Commit fa9d27773873 ("perf: arm_pmu: Kill last use of per-CPU cpu_armpmu
> pointer") changed armv8pmu_sched_task() from reading the per-CPU
> cpu_armpmu variable to dereferencing pmu_ctx->pmu via
> to_arm_pmu(pmu_ctx->pmu). Meanwhile, commit bd2756811766 ("perf:
> Rewrite core context handling") made __perf_pmu_sched_task() pass
> cpc->task_epc to pmu->sched_task(). cpc->task_epc is only non-NULL
> while a task context is scheduled in; CPU-bound events do not schedule a
> task context, so cpc->task_epc stays NULL. The NULL argument is dereferenced
> and crashes.
>
> With the patches applied, perf record -C <cpu> -b no longer crashes,
> and system-wide perf record -b -e <event> -a alongside a task-bound event
> on a different CPU runs without any WARN_ON.
>
> Tested-by: Yifan Wu <wuyifan50@huawei.com>
Hi,
Is there anything that needs doing to land this series? Avoiding a
perf crash seems worthwhile. I believe Peter and Ingo are best placed
to review the changes to kernel/events/core.c.
Thanks,
Ian
On Tue, Sep 15, 2026 at 3:47 PM Ian Rogers <irogers@google.com> wrote:
>
> On Thu, Sep 3, 2026 at 7:45 PM wuyifan <wuyifan50@huawei.com> wrote:
> >
> > Hi Puranjay,
> >
> > On 8/10/2026 9:35 PM, Puranjay Mohan wrote:
> > > These three fixes were found while adding BRBE support for
> > > bpf_get_branch_snapshot() on arm64 and were carried in that series until
> > > v6 [1]. They do not depend on it, so they go on their own; the version
> > > number continues from that series to avoid two numbering schemes for the
> > > same patches.
> > perf record -C <cpu> -b [<command>] triggers a NULL pointer dereference
> > in armv8pmu_sched_task().
> >
> > Commit fa9d27773873 ("perf: arm_pmu: Kill last use of per-CPU cpu_armpmu
> > pointer") changed armv8pmu_sched_task() from reading the per-CPU
> > cpu_armpmu variable to dereferencing pmu_ctx->pmu via
> > to_arm_pmu(pmu_ctx->pmu). Meanwhile, commit bd2756811766 ("perf:
> > Rewrite core context handling") made __perf_pmu_sched_task() pass
> > cpc->task_epc to pmu->sched_task(). cpc->task_epc is only non-NULL
> > while a task context is scheduled in; CPU-bound events do not schedule a
> > task context, so cpc->task_epc stays NULL. The NULL argument is dereferenced
> > and crashes.
> >
> > With the patches applied, perf record -C <cpu> -b no longer crashes,
> > and system-wide perf record -b -e <event> -a alongside a task-bound event
> > on a different CPU runs without any WARN_ON.
> >
> > Tested-by: Yifan Wu <wuyifan50@huawei.com>
>
> Hi,
>
> Is there anything that needs doing to land this series? Avoiding a
> perf crash seems worthwhile. I believe Peter and Ingo are best placed
> to review the changes to kernel/events/core.c.
>
another ping... seems like worthwhile problems to fix
> Thanks,
> Ian
>
© 2016 - 2026 Red Hat, Inc.