* [PATCH 0/3] perf cs-etm: Fix GCC 15 build failure
@ 2026-11-13 10:54 Leo Yan
2026-11-13 10:54 ` [PATCH 1/3] perf cs-etm: Initialize the Thumb instruction buffer Leo Yan
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Leo Yan @ 2026-11-13 10:54 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo, Namhyung Kim, James Clark, Mike Leach,
Suzuki K Poulose, Ian Rogers, Adrian Hunter, Robert Walker
Cc: Arnaldo Carvalho de Melo, coresight, linux-arm-kernel,
linux-perf-users, linux-kernel, Leo Yan
This series fixes the GCC 15 build failure reported by Ian Rogers [1]
(thanks, Ian!).
Two follow-up refactoring patches use the packet’s recorded instruction
size for stack events and centralize error checking for frontend
instruction reads.
[1] https://lore.kernel.org/linux-perf-users/20261030-perf_cs_etm_fix_non_taken-v3-0-7629b52ab047@arm.com/T/#m64fb81c665214b79883d9be815b40ac5f6669628
Signed-off-by: Leo Yan <leo.yan@arm.com>
---
Leo Yan (3):
perf cs-etm: Initialize the Thumb instruction buffer
perf cs-etm: Use the packet instruction size for stack events
perf cs-etm: Check frontend instruction reads
tools/perf/util/cs-etm.c | 83 +++++++++++++++++++++++++++++-------------------
1 file changed, 51 insertions(+), 32 deletions(-)
---
base-commit: 4af65363b11fc4fe65fcb497f68bbe4f3e3a4d2c
change-id: 20261113-perf_fix_gcc15_failure-1e31233be802
Best regards,
--
Leo Yan <leo.yan@arm.com>
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH 1/3] perf cs-etm: Initialize the Thumb instruction buffer 2026-11-13 10:54 [PATCH 0/3] perf cs-etm: Fix GCC 15 build failure Leo Yan @ 2026-11-13 10:54 ` Leo Yan 2026-11-13 10:58 ` sashiko-bot 2026-11-13 10:54 ` [PATCH 2/3] perf cs-etm: Use the packet instruction size for stack events Leo Yan 2026-11-13 10:54 ` [PATCH 3/3] perf cs-etm: Check frontend instruction reads Leo Yan 2 siblings, 1 reply; 7+ messages in thread From: Leo Yan @ 2026-11-13 10:54 UTC (permalink / raw) To: Arnaldo Carvalho de Melo, Namhyung Kim, James Clark, Mike Leach, Suzuki K Poulose, Ian Rogers, Adrian Hunter, Robert Walker Cc: Arnaldo Carvalho de Melo, coresight, linux-arm-kernel, linux-perf-users, linux-kernel, Leo Yan cs_etm__frontend_mem_access() can return zero or a short read without fully initializing instrBytes. cs_etm__t32_instr_size() nevertheless inspects its second byte. With CORESIGHT=1 and -O3, GCC 15.2.0 reports: error: 'instrBytes' may be used uninitialized Zero-initialize the buffer to avoid reading uninitialized stack data when instruction memory is unavailable and fix the build failure. Reported-by: Ian Rogers <irogers@google.com> Closes: https://lore.kernel.org/linux-perf-users/20261030-perf_cs_etm_fix_non_taken-v3-0-7629b52ab047@arm.com/T/#m64fb81c665214b79883d9be815b40ac5f6669628 Fixes: a7ee4d625ede ("perf cs-etm: Support for ARM A32/T32 instruction sets in CoreSight trace") Signed-off-by: Leo Yan <leo.yan@arm.com> --- tools/perf/util/cs-etm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 3e01b401ca6f3a08f44bb69204317efaf2fa18d0..25f12bd110934a204d79244f45317085b7a81666 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -1369,7 +1369,7 @@ static inline int cs_etm__t32_instr_size(struct cs_etm_queue *etmq, struct cs_etm_traceid_queue *tidq, struct cs_etm_packet *packet, u64 addr) { - u8 instrBytes[2]; + u8 instrBytes[2] = { 0 }; cs_etm__frontend_mem_access(etmq, tidq, packet, addr, ARRAY_SIZE(instrBytes), instrBytes); -- 2.34.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/3] perf cs-etm: Initialize the Thumb instruction buffer 2026-11-13 10:54 ` [PATCH 1/3] perf cs-etm: Initialize the Thumb instruction buffer Leo Yan @ 2026-11-13 10:58 ` sashiko-bot 0 siblings, 0 replies; 7+ messages in thread From: sashiko-bot @ 2026-11-13 10:58 UTC (permalink / raw) To: Leo Yan; +Cc: linux-perf-users > cs_etm__frontend_mem_access() can return zero or a short read without > fully initializing instrBytes. cs_etm__t32_instr_size() nevertheless > inspects its second byte. With CORESIGHT=1 and -O3, GCC 15.2.0 reports: > > error: 'instrBytes' may be used uninitialized > > Zero-initialize the buffer to avoid reading uninitialized stack data > when instruction memory is unavailable and fix the build failure. > > Reported-by: Ian Rogers <irogers@google.com> > Closes: https://lore.kernel.org/linux-perf-users/20261030-perf_cs_etm_fix_non_taken-v3-0-7629b52ab047@arm.com/T/#m64fb81c665214b79883d9be815b40ac5f6669628 > Fixes: a7ee4d625ede ("perf cs-etm: Support for ARM A32/T32 instruction sets in CoreSight trace") > Signed-off-by: Leo Yan <leo.yan@arm.com> Sashiko has reviewed this patch and found no issues. -- Sashiko AI review · https://sashiko.dev/#/patchset/20261113-perf_fix_gcc15_failure-v1-0-eae592c5ff64@arm.com?part=1 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/3] perf cs-etm: Use the packet instruction size for stack events 2026-11-13 10:54 [PATCH 0/3] perf cs-etm: Fix GCC 15 build failure Leo Yan 2026-11-13 10:54 ` [PATCH 1/3] perf cs-etm: Initialize the Thumb instruction buffer Leo Yan @ 2026-11-13 10:54 ` Leo Yan 2026-11-13 11:01 ` sashiko-bot 2026-11-13 10:54 ` [PATCH 3/3] perf cs-etm: Check frontend instruction reads Leo Yan 2 siblings, 1 reply; 7+ messages in thread From: Leo Yan @ 2026-11-13 10:54 UTC (permalink / raw) To: Arnaldo Carvalho de Melo, Namhyung Kim, James Clark, Mike Leach, Suzuki K Poulose, Ian Rogers, Adrian Hunter, Robert Walker Cc: Arnaldo Carvalho de Melo, coresight, linux-arm-kernel, linux-perf-users, linux-kernel, Leo Yan cs_etm__add_stack_event() uses the last executed instruction of the previous packet as the branch source. The decoder already records this instruction's size in last_instr_size, including for T32 instructions. Use the recorded size directly instead of reading instruction memory again. This removes an unnecessary read and the dependency on DSO data when updating the thread stack. Signed-off-by: Leo Yan <leo.yan@arm.com> --- tools/perf/util/cs-etm.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 25f12bd110934a204d79244f45317085b7a81666..312d4a734e84faa0d24c4ac1fee16f4dae4c2398 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -1626,7 +1626,6 @@ static void cs_etm__add_stack_event(struct cs_etm_queue *etmq, { struct cs_etm_auxtrace *etm = etmq->etm; u64 from, to; - int size; if (!etm->synth_opts.branches && !etm->synth_opts.instructions) return; @@ -1638,11 +1637,10 @@ static void cs_etm__add_stack_event(struct cs_etm_queue *etmq, from = cs_etm__last_executed_instr(tidq->prev_packet); to = cs_etm__first_executed_instr(tidq->packet); - size = cs_etm__instr_size(etmq, tidq, tidq->prev_packet, from); - /* Enable callchain so thread stack entry can be allocated */ thread_stack__event(tidq->frontend_thread, tidq->prev_packet->cpu, - tidq->prev_packet->flags, from, to, size, + tidq->prev_packet->flags, from, to, + tidq->prev_packet->last_instr_size, etmq->buffer->buffer_nr + 1, etmq->etm->use_callchain, tidq->br_stack_sz, 0); -- 2.34.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 2/3] perf cs-etm: Use the packet instruction size for stack events 2026-11-13 10:54 ` [PATCH 2/3] perf cs-etm: Use the packet instruction size for stack events Leo Yan @ 2026-11-13 11:01 ` sashiko-bot 0 siblings, 0 replies; 7+ messages in thread From: sashiko-bot @ 2026-11-13 11:01 UTC (permalink / raw) To: Leo Yan; +Cc: linux-perf-users > cs_etm__add_stack_event() uses the last executed instruction of the > previous packet as the branch source. The decoder already records this > instruction's size in last_instr_size, including for T32 instructions. > > Use the recorded size directly instead of reading instruction memory > again. This removes an unnecessary read and the dependency on DSO data > when updating the thread stack. > > Signed-off-by: Leo Yan <leo.yan@arm.com> Sashiko has reviewed this patch and found no issues. -- Sashiko AI review · https://sashiko.dev/#/patchset/20261113-perf_fix_gcc15_failure-v1-0-eae592c5ff64@arm.com?part=2 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 3/3] perf cs-etm: Check frontend instruction reads 2026-11-13 10:54 [PATCH 0/3] perf cs-etm: Fix GCC 15 build failure Leo Yan 2026-11-13 10:54 ` [PATCH 1/3] perf cs-etm: Initialize the Thumb instruction buffer Leo Yan 2026-11-13 10:54 ` [PATCH 2/3] perf cs-etm: Use the packet instruction size for stack events Leo Yan @ 2026-11-13 10:54 ` Leo Yan 2026-11-13 11:03 ` sashiko-bot 2 siblings, 1 reply; 7+ messages in thread From: Leo Yan @ 2026-11-13 10:54 UTC (permalink / raw) To: Arnaldo Carvalho de Melo, Namhyung Kim, James Clark, Mike Leach, Suzuki K Poulose, Ian Rogers, Adrian Hunter, Robert Walker Cc: Arnaldo Carvalho de Melo, coresight, linux-arm-kernel, linux-perf-users, linux-kernel, Leo Yan Frontend instruction decoding needs a complete memory read rather than a byte count. Refactor cs_etm__frontend_mem_access() to return zero for a complete read and -EIO otherwise, while retaining the decoder memory callback's byte-count interface. Propagate read errors through Thumb instruction size and address calculation. Skip samples whose addresses cannot be determined while preserving instruction period accounting, branch synthesis and packet processing. Initialize the copied instruction length to zero, validate the size, and set the length only after reading all instruction bytes. Also check read errors before recognizing SVC instructions. Signed-off-by: Leo Yan <leo.yan@arm.com> --- tools/perf/util/cs-etm.c | 75 +++++++++++++++++++++++++++++++----------------- 1 file changed, 48 insertions(+), 27 deletions(-) diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 312d4a734e84faa0d24c4ac1fee16f4dae4c2398..303e16a54445bc62ce1c7d0e4ffeb1819211fd40 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -1218,13 +1218,16 @@ static u32 __cs_etm__mem_access(struct cs_etm_queue *etmq, return ret; } -static u32 cs_etm__frontend_mem_access(struct cs_etm_queue *etmq, +static int cs_etm__frontend_mem_access(struct cs_etm_queue *etmq, struct cs_etm_traceid_queue *tidq, struct cs_etm_packet *packet, u64 address, size_t size, u8 *buffer) { - return __cs_etm__mem_access(etmq, address, size, buffer, 0, packet->el, - tidq->frontend_thread); + if (__cs_etm__mem_access(etmq, address, size, buffer, 0, packet->el, + tidq->frontend_thread) != size) + return -EIO; + + return 0; } static u32 cs_etm__decoder_mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id, @@ -1370,9 +1373,12 @@ static inline int cs_etm__t32_instr_size(struct cs_etm_queue *etmq, struct cs_etm_packet *packet, u64 addr) { u8 instrBytes[2] = { 0 }; + int ret; - cs_etm__frontend_mem_access(etmq, tidq, packet, addr, - ARRAY_SIZE(instrBytes), instrBytes); + ret = cs_etm__frontend_mem_access(etmq, tidq, packet, addr, + ARRAY_SIZE(instrBytes), instrBytes); + if (ret) + return ret; /* * T32 instruction size is indicated by bits[15:11] of the first * 16-bit word of the instruction: 0b11101, 0b11110 and 0b11111 @@ -1429,7 +1435,11 @@ static inline u64 cs_etm__instr_addr(struct cs_etm_queue *etmq, return addr + offset * 4; while (offset) { - addr += cs_etm__instr_size(etmq, tidq, packet, addr); + int size = cs_etm__instr_size(etmq, tidq, packet, addr); + + if (size < 0) + return CS_ETM_INVAL_ADDR; + addr += size; offset--; } return addr; @@ -1560,31 +1570,31 @@ static void cs_etm__copy_insn(struct cs_etm_queue *etmq, struct cs_etm_packet *packet, struct perf_sample *sample) { + int size; + + sample->insn_len = 0; + /* * It's pointless to read instructions for the CS_ETM_DISCONTINUITY * packet, so directly bail out with 'insn_len' = 0. */ - if (packet->sample_type == CS_ETM_DISCONTINUITY) { - sample->insn_len = 0; + if (packet->sample_type == CS_ETM_DISCONTINUITY) return; - } - sample->insn_len = cs_etm__instr_size(etmq, tidq, packet, sample->ip); + size = cs_etm__instr_size(etmq, tidq, packet, sample->ip); /* * The instruction length should always fit within sample->insn, * but check it to prevent an out-of-bounds write. */ - if (sample->insn_len > sizeof(sample->insn)) { - sample->insn_len = 0; + if (size <= 0 || (size_t)size > sizeof(sample->insn)) return; - } - if (packet->sample_type == CS_ETM_EXCEPTION && !sample->insn_len) + if (cs_etm__frontend_mem_access(etmq, tidq, packet, sample->ip, + size, (void *)sample->insn)) return; - cs_etm__frontend_mem_access(etmq, tidq, packet, sample->ip, - sample->insn_len, (void *)sample->insn); + sample->insn_len = size; } u64 cs_etm__convert_sample_time(struct cs_etm_queue *etmq, u64 cs_timestamp) @@ -2011,11 +2021,13 @@ static int cs_etm__sample(struct cs_etm_queue *etmq, */ addr = cs_etm__instr_addr(etmq, tidq, tidq->packet, offset - 1); - ret = cs_etm__synth_instruction_sample( - etmq, tidq, tidq->packet, addr, - etm->instructions_sample_period); - if (ret) - return ret; + if (addr != CS_ETM_INVAL_ADDR) { + ret = cs_etm__synth_instruction_sample( + etmq, tidq, tidq->packet, addr, + etm->instructions_sample_period); + if (ret) + return ret; + } offset += etm->instructions_sample_period; tidq->period_instructions -= @@ -2227,8 +2239,11 @@ static bool cs_etm__is_svc_instr(struct cs_etm_queue *etmq, * so below only read 2 bytes as instruction size for T32. */ addr = ret_addr - 2; - cs_etm__frontend_mem_access(etmq, tidq, packet, addr, - sizeof(instr16), (u8 *)&instr16); + + if (cs_etm__frontend_mem_access(etmq, tidq, packet, addr, + sizeof(instr16), (u8 *)&instr16)) + return false; + if ((instr16 & 0xFF00) == 0xDF00) return true; @@ -2243,8 +2258,11 @@ static bool cs_etm__is_svc_instr(struct cs_etm_queue *etmq, * +---------+---------+-------------------------+ */ addr = ret_addr - 4; - cs_etm__frontend_mem_access(etmq, tidq, packet, addr, - sizeof(instr32), (u8 *)&instr32); + + if (cs_etm__frontend_mem_access(etmq, tidq, packet, addr, + sizeof(instr32), (u8 *)&instr32)) + return false; + if ((instr32 & 0x0F000000) == 0x0F000000 && (instr32 & 0xF0000000) != 0xF0000000) return true; @@ -2260,8 +2278,11 @@ static bool cs_etm__is_svc_instr(struct cs_etm_queue *etmq, * +-----------------------+---------+-----------+ */ addr = ret_addr - 4; - cs_etm__frontend_mem_access(etmq, tidq, packet, addr, - sizeof(instr32), (u8 *)&instr32); + + if (cs_etm__frontend_mem_access(etmq, tidq, packet, addr, + sizeof(instr32), (u8 *)&instr32)) + return false; + if ((instr32 & 0xFFE0001F) == 0xd4000001) return true; -- 2.34.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 3/3] perf cs-etm: Check frontend instruction reads 2026-11-13 10:54 ` [PATCH 3/3] perf cs-etm: Check frontend instruction reads Leo Yan @ 2026-11-13 11:03 ` sashiko-bot 0 siblings, 0 replies; 7+ messages in thread From: sashiko-bot @ 2026-11-13 11:03 UTC (permalink / raw) To: Leo Yan; +Cc: linux-perf-users Thank you for your contribution! Sashiko AI review found no new issues in this patch, but noticed 2 related pre-existing issues it does not introduce: - [Medium] perf cs-etm: missing perf_sample__exit() in sample synthesis error paths [1] - [Medium] perf cs-etm: infinite loop in cs_etm__sample() when period is 0 [2] -- commit 1c4da6763b4506cd44f0609ef42fba0e4bd574ea Author: Leo Yan <leo.yan@arm.com> perf cs-etm: Check frontend instruction reads This commit updates cs_etm__frontend_mem_access() to return 0 on a complete read and -EIO otherwise, propagating read errors through instruction size, address calculation, instruction copying, and SVC detection. > diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c > index 312d4a734e84f..303e16a54445b 100644 > --- a/tools/perf/util/cs-etm.c > +++ b/tools/perf/util/cs-etm.c [ ... ] > @@ -2011,11 +2021,13 @@ static int cs_etm__sample(struct cs_etm_queue *etmq, > */ > addr = cs_etm__instr_addr(etmq, tidq, tidq->packet, > offset - 1); > - ret = cs_etm__synth_instruction_sample( > - etmq, tidq, tidq->packet, addr, > - etm->instructions_sample_period); > - if (ret) > - return ret; > + if (addr != CS_ETM_INVAL_ADDR) { > + ret = cs_etm__synth_instruction_sample( > + etmq, tidq, tidq->packet, addr, > + etm->instructions_sample_period); > + if (ret) > + return ret; > + } [Severity: Medium] This problem wasn't introduced by this patch, but can cs_etm__synth_instruction_sample() and cs_etm__synth_branch_sample() leak sample resources when event injection fails [1]? Both functions initialize sample with perf_sample__init(&sample, true), which allocates sub-structures, and then return early before perf_sample__exit(&sample) if cs_etm__inject_event() returns an error: tools/perf/util/cs-etm.c:cs_etm__synth_instruction_sample() { ... perf_sample__init(&sample, /*all=*/true); ... if (etm->synth_opts.inject) { ret = cs_etm__inject_event(etm, event, &sample, etm->instructions_sample_type); if (ret) return ret; } ... perf_sample__exit(&sample); return ret; } > > offset += etm->instructions_sample_period; > tidq->period_instructions -= [Severity: Medium] This problem wasn't introduced by this patch, but can cs_etm__sample() spin forever when the user specifies an instruction sample period of 0 (for example, --itrace=i0i) [2]? The loop condition is: tools/perf/util/cs-etm.c:cs_etm__sample() { ... while (tidq->period_instructions >= etm->instructions_sample_period) { ... offset += etm->instructions_sample_period; tidq->period_instructions -= etm->instructions_sample_period; } } Because both operands are unsigned, tidq->period_instructions >= 0 is always true and subtracting 0 never reduces tidq->period_instructions. [1] https://sashiko.dev/#/bug/linux-313ce3d0-12d6-4671-8007-6e3925af60fc [2] https://sashiko.dev/#/bug/linux-88c200a9-e322-487b-904a-28d581ccee8b -- Sashiko AI review · https://sashiko.dev/#/patchset/20261113-perf_fix_gcc15_failure-v1-0-eae592c5ff64@arm.com?part=3 ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-11-13 11:03 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-11-13 10:54 [PATCH 0/3] perf cs-etm: Fix GCC 15 build failure Leo Yan 2026-11-13 10:54 ` [PATCH 1/3] perf cs-etm: Initialize the Thumb instruction buffer Leo Yan 2026-11-13 10:58 ` sashiko-bot 2026-11-13 10:54 ` [PATCH 2/3] perf cs-etm: Use the packet instruction size for stack events Leo Yan 2026-11-13 11:01 ` sashiko-bot 2026-11-13 10:54 ` [PATCH 3/3] perf cs-etm: Check frontend instruction reads Leo Yan 2026-11-13 11:03 ` sashiko-bot
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.