[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <20251110-arm_spe_fix_truncated_flag-v2-1-a629740985cc@arm.com>
Date: Mon, 10 Nov 2025 16:28:31 +0000
From: Leo Yan <leo.yan@....com>
To: Will Deacon <will@...nel.org>, Mark Rutland <mark.rutland@....com>,
Alexandru Elisei <alexandru.elisei@....com>,
James Clark <james.clark@...aro.org>
Cc: linux-arm-kernel@...ts.infradead.org, linux-perf-users@...r.kernel.org,
linux-kernel@...r.kernel.org, Leo Yan <leo.yan@....com>
Subject: [PATCH v2 1/2] perf: arm_spe: Correct setting the PERF_HES_STOPPED
flag
In arm_spe_perf_aux_output_begin(), if the calculation of limit fails
and arm_spe_pmu_next_off() returns zero, the driver misses to set the
PERF_HES_STOPPED flag for the event. As a result, hwc->state does not
reflect the latest state, which can mislead subsequent operations.
Validate the limit when exiting the function: if the limit is 0,
that tracing is disabled, set the PERF_HES_STOPPED flag accordingly.
Fixes: d5d9696b0380 ("drivers/perf: Add support for ARMv8.2 Statistical Profiling Extension")
Signed-off-by: Leo Yan <leo.yan@....com>
---
drivers/perf/arm_spe_pmu.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c
index fa50645feddadbea5dc1e404f80f62cf5aa96fd4..fc8f908c2c3a270f2d1ae574c2badb1fbcf51484 100644
--- a/drivers/perf/arm_spe_pmu.c
+++ b/drivers/perf/arm_spe_pmu.c
@@ -597,7 +597,6 @@ static void arm_spe_perf_aux_output_begin(struct perf_output_handle *handle,
/* Start a new aux session */
buf = perf_aux_output_begin(handle, event);
if (!buf) {
- event->hw.state |= PERF_HES_STOPPED;
/*
* We still need to clear the limit pointer, since the
* profiler might only be disabled by virtue of a fault.
@@ -608,15 +607,19 @@ static void arm_spe_perf_aux_output_begin(struct perf_output_handle *handle,
limit = buf->snapshot ? arm_spe_pmu_next_snapshot_off(handle)
: arm_spe_pmu_next_off(handle);
- if (limit)
- limit |= PMBLIMITR_EL1_E;
+ if (!limit)
+ goto out_write_limit;
limit += (u64)buf->base;
+ limit |= PMBLIMITR_EL1_E;
base = (u64)buf->base + PERF_IDX2OFF(handle->head, buf);
write_sysreg_s(base, SYS_PMBPTR_EL1);
out_write_limit:
write_sysreg_s(limit, SYS_PMBLIMITR_EL1);
+
+ if (!limit)
+ event->hw.state |= PERF_HES_STOPPED;
}
static void arm_spe_perf_aux_output_end(struct perf_output_handle *handle)
--
2.34.1
Powered by blists - more mailing lists