mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-17 03:14:12 +08:00
coresight: tmc: Explicit type conversions to prevent integer overflow
[ Upstream commitfd380097cd
] Perf cs_etm session executed unexpectedly when AUX buffer > 1G. perf record -C 0 -m ,2G -e cs_etm// -- <workload> [ perf record: Captured and wrote 2.615 MB perf.data ] Perf only collect about 2M perf data rather than 2G. This is becasuse the operation, "nr_pages << PAGE_SHIFT", in coresight tmc driver, will overflow when nr_pages >= 0x80000(correspond to 1G AUX buffer). The overflow cause buffer allocation to fail, and TMC driver will alloc minimal buffer size(1M). You can just get about 2M perf data(1M AUX buffer + perf data header) at least. Explicit convert nr_pages to 64 bit to avoid overflow. Fixes:22f429f19c
("coresight: etm-perf: Add support for ETR backend") Fixes:99443ea19e
("coresight: Add generic TMC sg table framework") Fixes:2e499bbc1a
("coresight: tmc: implementing TMC-ETF AUX space API") Signed-off-by: Ruidong Tian <tianruidong@linux.alibaba.com> Reviewed-by: James Clark <james.clark@arm.com> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20230804081514.120171-2-tianruidong@linux.alibaba.com Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
93a5b461a4
commit
d3256d8040
@ -428,7 +428,7 @@ static int tmc_set_etf_buffer(struct coresight_device *csdev,
|
||||
return -EINVAL;
|
||||
|
||||
/* wrap head around to the amount of space we have */
|
||||
head = handle->head & ((buf->nr_pages << PAGE_SHIFT) - 1);
|
||||
head = handle->head & (((unsigned long)buf->nr_pages << PAGE_SHIFT) - 1);
|
||||
|
||||
/* find the page to write to */
|
||||
buf->cur = head / PAGE_SIZE;
|
||||
|
@ -47,7 +47,8 @@ struct etr_perf_buffer {
|
||||
};
|
||||
|
||||
/* Convert the perf index to an offset within the ETR buffer */
|
||||
#define PERF_IDX2OFF(idx, buf) ((idx) % ((buf)->nr_pages << PAGE_SHIFT))
|
||||
#define PERF_IDX2OFF(idx, buf) \
|
||||
((idx) % ((unsigned long)(buf)->nr_pages << PAGE_SHIFT))
|
||||
|
||||
/* Lower limit for ETR hardware buffer */
|
||||
#define TMC_ETR_PERF_MIN_BUF_SIZE SZ_1M
|
||||
@ -1232,7 +1233,7 @@ alloc_etr_buf(struct tmc_drvdata *drvdata, struct perf_event *event,
|
||||
* than the size requested via sysfs.
|
||||
*/
|
||||
if ((nr_pages << PAGE_SHIFT) > drvdata->size) {
|
||||
etr_buf = tmc_alloc_etr_buf(drvdata, (nr_pages << PAGE_SHIFT),
|
||||
etr_buf = tmc_alloc_etr_buf(drvdata, ((ssize_t)nr_pages << PAGE_SHIFT),
|
||||
0, node, NULL);
|
||||
if (!IS_ERR(etr_buf))
|
||||
goto done;
|
||||
|
@ -321,7 +321,7 @@ ssize_t tmc_sg_table_get_data(struct tmc_sg_table *sg_table,
|
||||
static inline unsigned long
|
||||
tmc_sg_table_buf_size(struct tmc_sg_table *sg_table)
|
||||
{
|
||||
return sg_table->data_pages.nr_pages << PAGE_SHIFT;
|
||||
return (unsigned long)sg_table->data_pages.nr_pages << PAGE_SHIFT;
|
||||
}
|
||||
|
||||
struct coresight_device *tmc_etr_get_catu_device(struct tmc_drvdata *drvdata);
|
||||
|
Loading…
Reference in New Issue
Block a user