mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
perf cs-etm: Avoid truncating AUX buffer sizes to int
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@meta.com>
Fixes: 8224531cf5 ("perf cs-etm: Modularize auxtrace_buffer fetch function")
Signed-off-by: Leo Yan <leo.yan@arm.com>
Reviewed-by: James Clark <james.clark@linaro.org>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
This commit is contained in:
+26
-20
@@ -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;
|
||||
|
||||
return etmq->buf_len;
|
||||
/* 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 1;
|
||||
}
|
||||
|
||||
static bool cs_etm__is_svc_instr(struct cs_etm_queue *etmq,
|
||||
|
||||
Reference in New Issue
Block a user