[PATCH v3 1/4] perf/core: Fix NULL pmu_ctx passed to PMU sched_task callback

From: Puranjay Mohan

Date: Mon Apr 13 2026 - 14:58:59 EST


__perf_pmu_sched_task() passes cpc->task_epc to pmu->sched_task(),
which is NULL when no per-task events exist for this PMU. With CPU-wide
branch-stack events, PMU callbacks that dereference pmu_ctx crash.

On ARM64 this is easily triggered with:

perf record -b -e cycles -a -- ls

which crashes on the first context switch:

Unable to handle kernel NULL pointer dereference at virtual address 00[.]
PC is at armv8pmu_sched_task+0x14/0x50
Call trace:
armv8pmu_sched_task+0x14/0x50 (P)
perf_pmu_sched_task+0xac/0x108
__perf_event_task_sched_out+0x6c/0xe0

Fall back to &cpc->epc when cpc->task_epc is NULL so the callback
always receives a valid pmu_ctx.

Fixes: bd2756811766 ("perf: Rewrite core context handling")
Signed-off-by: Puranjay Mohan <puranjay@xxxxxxxxxx>
---
kernel/events/core.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/kernel/events/core.c b/kernel/events/core.c
index 1f5699b339ec..2a8fb78e1347 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -3906,7 +3906,8 @@ static void __perf_pmu_sched_task(struct perf_cpu_pmu_context *cpc,
perf_ctx_lock(cpuctx, cpuctx->task_ctx);
perf_pmu_disable(pmu);

- pmu->sched_task(cpc->task_epc, task, sched_in);
+ pmu->sched_task(cpc->task_epc ? cpc->task_epc : &cpc->epc,
+ task, sched_in);

perf_pmu_enable(pmu);
perf_ctx_unlock(cpuctx, cpuctx->task_ctx);
--
2.52.0