driver inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I8EC9K CVE: NA
--------------------------------
Function armpmu_add will call armv8pmu_branch_reset() to reset BRBE. The BRBE feature depend on ARMV8 PMU hardware support for branch stack sampling. On older platforms the kernel panics.
Internal error: Oops - Undefined instruction: 0000000002000000 [#1] SMP Call trace: armv8pmu_branch_reset+0xc/0x20 event_sched_in+0xc8/0x1a0 merge_sched_in+0x16c/0x41c
Fixes: 2690e65ac9f9 ("drivers: perf: arm_pmuv3: Enable branch stack sampling via FEAT_BRBE") Signed-off-by: Junhao He hejunhao3@huawei.com --- drivers/perf/arm_pmu.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-)
diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c index d02a85c0bedc..4ef8aee84eea 100644 --- a/drivers/perf/arm_pmu.c +++ b/drivers/perf/arm_pmu.c @@ -313,10 +313,12 @@ armpmu_del(struct perf_event *event, int flags) struct hw_perf_event *hwc = &event->hw; int idx = hwc->idx;
- WARN_ON_ONCE(!hw_events->brbe_users); - hw_events->brbe_users--; - if (!hw_events->brbe_users) - hw_events->brbe_context = NULL; + if (has_branch_stack(event)) { + WARN_ON_ONCE(!hw_events->brbe_users); + hw_events->brbe_users--; + if (!hw_events->brbe_users) + hw_events->brbe_context = NULL; + }
armpmu_stop(event, PERF_EF_UPDATE); hw_events->events[idx] = NULL; @@ -334,18 +336,20 @@ armpmu_add(struct perf_event *event, int flags) struct hw_perf_event *hwc = &event->hw; int idx;
- /* - * Reset branch records buffer if a new task event gets - * scheduled on a PMU which might have existing records. - * Otherwise older branch records present in the buffer - * might leak into the new task event. - */ - if (event->ctx->task && hw_events->brbe_context != event->ctx) { - hw_events->brbe_context = event->ctx; - if (armpmu->branch_reset) - armpmu->branch_reset(); + if (has_branch_stack(event)) { + /* + * Reset branch records buffer if a new task event gets + * scheduled on a PMU which might have existing records. + * Otherwise older branch records present in the buffer + * might leak into the new task event. + */ + if (event->ctx->task && hw_events->brbe_context != event->ctx) { + hw_events->brbe_context = event->ctx; + if (armpmu->branch_reset) + armpmu->branch_reset(); + } + hw_events->brbe_users++; } - hw_events->brbe_users++;
/* An event following a process won't be stopped earlier */ if (!cpumask_test_cpu(smp_processor_id(), &armpmu->supported_cpus))