[PATCH] perf cs-etm: Avoid truncating AUX buffer sizes to int
James Clark
james.clark at linaro.org
Tue Jul 21 07:23:31 PDT 2026
On 20/07/2026 11:01 am, Leo Yan wrote:
> cs_etm__get_trace() returns an int, but it used to return etmq->buf_len
> on success. That value comes from auxtrace_buffer::size, which is a
> size_t. For a large AUX trace block, returning the byte count through an
> int can overflow and make a valid buffer look like a negative error.
>
> The callers do not need the actual byte count from cs_etm__get_trace().
> The buffer length is already stored in the etmq->buf_len. The callers
> only need to distinguish three states:
>
> < 0: error
> = 0: no more AUX buffers
> > 0: data is available
>
> Make cs_etm__get_trace() return 0 for all non-error cases and use
> etmq->buf_len to indicate whether a new buffer was found. Then make
> cs_etm__get_data_block() return 1 whenever data is available, instead of
> returning the buffer length.
>
> Also refactor cs_etm__get_data_block() to make its return value
> semantics clearer.
>
> Reported-by: Suyash Mahar <smahar at meta.com>
> Fixes: 8224531cf5a1 ("perf cs-etm: Modularize auxtrace_buffer fetch function")
> Signed-off-by: Leo Yan <leo.yan at arm.com>
Reviewed-by: James Clark <james.clark at linaro.org>
> ---
> tools/perf/util/cs-etm.c | 46 ++++++++++++++++++++++++++--------------------
> 1 file changed, 26 insertions(+), 20 deletions(-)
>
> diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
> index 95e3ec1171acc8442d8539a72a26a1a5a53a2f37..114b3cd2da495e54e78df8fbd707898312f95079 100644
> --- a/tools/perf/util/cs-etm.c
> +++ b/tools/perf/util/cs-etm.c
> @@ -1467,8 +1467,7 @@ cs_etm__get_trace(struct cs_etm_queue *etmq)
> etmq->buf_used = 0;
> etmq->buf_len = aux_buffer->size;
> etmq->buf = aux_buffer->data;
> -
> - return etmq->buf_len;
> + return 0;
> }
>
> /*
> @@ -2151,26 +2150,33 @@ static int cs_etm__get_data_block(struct cs_etm_queue *etmq)
> {
> int ret;
>
> - if (!etmq->buf_len) {
> - ret = cs_etm__get_trace(etmq);
> - if (ret <= 0)
> - return ret;
> - /*
> - * We cannot assume consecutive blocks in the data file
> - * are contiguous, reset the decoder to force re-sync.
> - */
> - ret = cs_etm_decoder__reset(etmq->decoder);
> - if (ret)
> - return ret;
> + /* The current block is not finished */
> + if (etmq->buf_len)
> + return 1;
>
> - /*
> - * Since the decoder is reset, this causes a global trace
> - * discontinuity. Flush all thread stacks.
> - */
> - cs_etm__flush_all_stack(etmq);
> - }
> + ret = cs_etm__get_trace(etmq);
> + if (ret < 0)
> + return ret;
> +
> + /* No more buffer to read */
> + if (!etmq->buf_len)
> + return 0;
> +
> + /*
> + * We cannot assume consecutive blocks in the data file
> + * are contiguous, reset the decoder to force re-sync.
> + */
> + ret = cs_etm_decoder__reset(etmq->decoder);
> + if (ret)
> + return ret;
> +
> + /*
> + * Since the decoder is reset, this causes a global trace
> + * discontinuity. Flush all thread stacks.
> + */
> + cs_etm__flush_all_stack(etmq);
>
> - return etmq->buf_len;
> + return 1;
> }
>
> static bool cs_etm__is_svc_instr(struct cs_etm_queue *etmq,
>
> ---
> base-commit: e01c7bd5b1eece254bcbf282db066b12c4815d21
> change-id: 20260720-perf_cs_etm_fix_big_size-ec5608f767df
>
> Best regards,
More information about the linux-arm-kernel
mailing list