[PATCH v2 00/14] perf cs-etm: Fix bogus branch samples on exceptions
From: Leo Yan <leo.yan@arm.com>
Date: 2026-09-23 15:22:10
Also in:
linux-perf-users, lkml
CoreSight currently models exception entry by changing the preceding instruction range into a taken branch. This can give an IRQ the source PC of an instruction that already retired and overwrite a real branch immediately before the exception. For an untaken B.LS followed by an IRQ, perf script currently reports: hw int 4000f8 => ffff800080010c80 b.ls #0x400118 ... iret ffff800080012284 => 4000fc eret The hardware trace supplies 0x4000fc as the preferred return address. For an IRQ, this is the architectural resume PC (Arm ARM, R_VBQMV). B.LS has retired, and the saved PC identifies the boundary before the following MOV. Using this PC as the IRQ source reflects the architectural state at exception entry: hw int 4000fc => ffff800080010c80 movz x2, #0x1796 ... iret ffff800080012284 => 4000fc eret The IRQ sample represents the transfer from this architectural execution position to the handler. The series synthesizes exception entries from exception packets, preserving the preceding branch and its outcome. The supporting changes: - Let decoders supply sample.ret_addr so later instruction fetching cannot change thread-stack return addresses. Apply this to Intel PT asynchronous samples as well. - Prepare packet ISA and instruction-size handling and share sample synthesis helpers. Mark untaken branches and break history when instruction memory is unavailable. - Add a thread-stack regression test and four AArch64 CoreSight tests. IRQs and page faults must resume at the entry PC; SVC and emulated MRS must resume four bytes later. Based on the AI search and test on my x86 machine, this matches perf's Intel PT handling of IRQs. Intel PT records the next instruction's IP in the FUP packet, and Perf uses that IP as the interrupt sample's source. This series is verified on Orion6 board with "perf test coresight". Signed-off-by: Leo Yan <leo.yan@arm.com> --- Changes in v2: - Rework the fix around exception packets to preserve both exception entries and preceding branches. - Add explicit return addresses and the Intel PT asynchronous-branch fix. - Split out packet/synthesis preparation, record not-taken branches and handle unreadable instruction memory. - Add thread-stack regression coverage and four CoreSight tests. - Link to v1: https://lore.kernel.org/r/20260713-perf_cs_etm_fix_non_taken-v1-0-4561607fc69f@arm.com (local) --- Leo Yan (14): perf sample: Allow decoders to supply branch return addresses perf intel-pt: Preserve return addresses for asynchronous branches perf cs-etm: Break branch history when instruction memory is unavailable perf cs-etm: Centralize packet ISA initialization perf cs-etm: Use the recorded instruction size for A32 and A64 perf cs-etm: Mark branches that were not taken perf cs-etm: Factor out final instruction sample synthesis perf cs-etm: Centralize branch sample synthesis checks perf cs-etm: Classify exception calls using the exception packet perf cs-etm: Synthesize exception entries separately from branches perf tests: Check CoreSight IRQ entry and exit perf tests: Check CoreSight syscall entry and exit perf tests: Check CoreSight abort entry and exit perf tests: Check CoreSight emulated instruction entry and exit tools/perf/tests/Build | 1 + tools/perf/tests/builtin-test.c | 3 + .../perf/tests/shell/coresight/abort_entry_exit.sh | 21 ++ tools/perf/tests/shell/coresight/irq_entry_exit.sh | 37 ++++ .../tests/shell/coresight/syscall_entry_exit.sh | 21 ++ .../perf/tests/shell/coresight/trap_entry_exit.sh | 24 +++ tools/perf/tests/shell/lib/coresight_exception.sh | 165 +++++++++++++++ tools/perf/tests/tests.h | 3 + tools/perf/tests/thread-stack.c | 106 ++++++++++ tools/perf/tests/workloads/Build | 4 + tools/perf/tests/workloads/branch_not_taken_loop.c | 33 +++ tools/perf/tests/workloads/page_fault_loop.c | 37 ++++ tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 106 +++++++--- tools/perf/util/cs-etm.c | 222 ++++++++++----------- tools/perf/util/cs-etm.h | 2 + tools/perf/util/intel-pt.c | 7 + tools/perf/util/sample.c | 1 + tools/perf/util/sample.h | 5 + tools/perf/util/thread-stack.c | 5 +- 19 files changed, 656 insertions(+), 147 deletions(-) --- base-commit: edd8a9fe2eca009599e013a29c421c7a6b5ad1b9 change-id: 20260713-perf_cs_etm_fix_non_taken-5b4d7f73f41e Best regards, -- Leo Yan [off-list ref]