If the AUX buffer size is specified as 2 GiB or larger, the expression "(buf)->nr_pages << PAGE_SHIFT" may exceed 0x8000_0000. Since (buf)->nr_pages is a signed integer, the shift can overflow and produce a negative value. As a result, PERF_IDX2OFF() fails to work correctly.
Fix this by casting (buf)->nr_pages to unsigned long before the shift, which allows PERF_IDX2OFF() to handle large buffers properly.
Signed-off-by: Leo Yan leo.yan@arm.com --- Leo Yan (2): coresight: trbe: Prevent overflow in PERF_IDX2OFF() perf: arm_spe: Prevent overflow in PERF_IDX2OFF()
drivers/hwtracing/coresight/coresight-trbe.c | 3 ++- drivers/perf/arm_spe_pmu.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) --- base-commit: 5aca7966d2a7255ba92fd5e63268dd767b223aa5 change-id: 20250917-fix_aux_trace_index-9745674f5061
Best regards,
Cast nr_pages to unsigned long to avoid overflow when handling large AUX buffer sizes (>= 2 GiB).
Fixes: 3fbf7f011f24 ("coresight: sink: Add TRBE driver") Signed-off-by: Leo Yan leo.yan@arm.com --- drivers/hwtracing/coresight/coresight-trbe.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c index 8267dd1a2130d37d9507791620ea7bc8cbcd675c..8f426f94e32a15fd26e6c4e42385a5d93a7b7c1a 100644 --- a/drivers/hwtracing/coresight/coresight-trbe.c +++ b/drivers/hwtracing/coresight/coresight-trbe.c @@ -23,7 +23,8 @@ #include "coresight-self-hosted-trace.h" #include "coresight-trbe.h"
-#define PERF_IDX2OFF(idx, buf) ((idx) % ((buf)->nr_pages << PAGE_SHIFT)) +#define PERF_IDX2OFF(idx, buf) \ + ((idx) % ((unsigned long)(buf)->nr_pages << PAGE_SHIFT))
/* * A padding packet that will help the user space tools
Cast nr_pages to unsigned long to avoid overflow when handling large AUX buffer sizes (>= 2 GiB).
Fixes: d5d9696b0380 ("drivers/perf: Add support for ARMv8.2 Statistical Profiling Extension") Signed-off-by: Leo Yan leo.yan@arm.com --- drivers/perf/arm_spe_pmu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c index 369e77ad5f13ffb490bf8f128fee5180d1254bc6..8f14cb324e018349fbe19c5c20d92a9cdcfd2e73 100644 --- a/drivers/perf/arm_spe_pmu.c +++ b/drivers/perf/arm_spe_pmu.c @@ -97,7 +97,8 @@ struct arm_spe_pmu { #define to_spe_pmu(p) (container_of(p, struct arm_spe_pmu, pmu))
/* Convert a free-running index from perf into an SPE buffer offset */ -#define PERF_IDX2OFF(idx, buf) ((idx) % ((buf)->nr_pages << PAGE_SHIFT)) +#define PERF_IDX2OFF(idx, buf) \ + ((idx) % ((unsigned long)(buf)->nr_pages << PAGE_SHIFT))
/* Keep track of our dynamic hotplug state */ static enum cpuhp_state arm_spe_pmu_online;