[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