From nobody Thu Sep 24 13:43:08 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id D4F6255D86D; Wed, 23 Sep 2026 15:21:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790176920; cv=none; b=pq1BgkCvwdMyTnD6TFxft9HE4Ag3UOJp9WgRHa5BPvUENZ0jDyC6qdsTqFxFYO3GXAH8COIPXbaBmgojVdrlzi17S4S0q+LPkWzzOiZsunEcm8Xsv9HkAqhFv1AhyQxMo0rIpfkFu6K873rGZiKlGriWWGbbaFaF9h6DgwJOxPY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790176920; c=relaxed/simple; bh=XRNWbpk0QOOsA2aYa6yH6hal8elpLwnaUnNIt+qhB34=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=lwwF5wy5Z4oi9EXKX7AwRYIYx+D3ZOWQNEdsUxM/86WKi/vhBVrwHVScQXEx/0vBZK+8HToYsG5kulGVjHlJYSAjQ5FvftSYTwWJov5M9ormWCssTq2852THTSC3UCIyCOkY5E+ybaKvgUssJo29dpB3xFWckikRilHA3RQIREE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=dzbcJJ2G; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="dzbcJJ2G" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id BC0B21576; Wed, 23 Sep 2026 08:21:54 -0700 (PDT) Received: from e132581.arm.com (unknown [10.2.196.114]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 0BA603F86F; Wed, 23 Sep 2026 08:21:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1790176918; bh=XRNWbpk0QOOsA2aYa6yH6hal8elpLwnaUnNIt+qhB34=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=dzbcJJ2GegtV42YfoU4VmSBZCeD3RUeaypFiErM97ILHM+NAxZGFghi0Aq8jtgsXX 69Rg6b9xPZ6htruioABbpF/6c373L72NJkHwdc9fdcmn2FQ/jHsrDiFOydTdKpgMeK t9W7SqYcKXUGHVzfVqDKka7mU4xPoqW0B3V9Je58= From: Leo Yan Date: Wed, 23 Sep 2026 16:21:41 +0100 Subject: [PATCH v2 01/14] perf sample: Allow decoders to supply branch return addresses Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260923-perf_cs_etm_fix_non_taken-v2-1-6ab8c07a5455@arm.com> References: <20260923-perf_cs_etm_fix_non_taken-v2-0-6ab8c07a5455@arm.com> In-Reply-To: <20260923-perf_cs_etm_fix_non_taken-v2-0-6ab8c07a5455@arm.com> To: Arnaldo Carvalho de Melo , Namhyung Kim , Jiri Olsa , Ian Rogers , Adrian Hunter , James Clark , Mike Leach , Suzuki K Poulose , Suyash Mahar , Amir Ayupov Cc: Arnaldo Carvalho de Melo , coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Leo Yan X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1790176913; l=8195; i=leo.yan@arm.com; s=20250604; h=from:subject:message-id; bh=XRNWbpk0QOOsA2aYa6yH6hal8elpLwnaUnNIt+qhB34=; b=2732rz0LHJ47CsPp1Ve7ayP1SNvJvY30yLB8A6AEAHpNtmkETQFrujAYDLnKgC6qend9ThXSh bzG5i1sTnvUBNEV6oX9zIVdgB0/MZPT5+8V41p858HyAuxErDMlmFH+ X-Developer-Key: i=leo.yan@arm.com; a=ed25519; pk=k4BaDbvkCXzBFA7Nw184KHGP5thju8lKqJYIrOWxDhI= The thread stack derives return addresses from IP + insn_len. For an interrupt or fault, the return address can instead be the sample IP even when instruction bytes at that address are available. Add ret_addr to perf_sample and prefer it in thread_stack__trace_end() and thread_stack__process() when supplied. Initialize it to zero so other samples retain the IP + insn_len calculation. Add a regression test for explicit exception return addresses and the ordinary call fallback when the return address is zero. Assisted-by: Codex:gpt-6 Signed-off-by: Leo Yan Reviewed-by: Adrian Hunter --- tools/perf/tests/Build | 1 + tools/perf/tests/builtin-test.c | 1 + tools/perf/tests/tests.h | 1 + tools/perf/tests/thread-stack.c | 106 ++++++++++++++++++++++++++++++++++++= ++++ tools/perf/util/sample.c | 1 + tools/perf/util/sample.h | 5 ++ tools/perf/util/thread-stack.c | 5 +- 7 files changed, 118 insertions(+), 2 deletions(-) diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index 81c311b131b72715f11b6501511a18dce2af07df..d03ae938dd0ad92f78f8de6900c= e7161f39fc3bc 100644 --- a/tools/perf/tests/Build +++ b/tools/perf/tests/Build @@ -29,6 +29,7 @@ perf-test-y +=3D task-exit.o perf-test-y +=3D sw-clock.o perf-test-y +=3D mmap-thread-lookup.o perf-test-y +=3D thread-maps-share.o +perf-test-y +=3D thread-stack.o perf-test-$(CONFIG_LIBTRACEEVENT) +=3D switch-tracking.o perf-test-y +=3D keep-tracking.o perf-test-y +=3D code-reading.o diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-tes= t.c index d2f594921e25bda9fc662e7ba82464bfef1b752b..6259ed805c5f75799d52ac742b7= 7cf278f98bd9d 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -112,6 +112,7 @@ static struct test_suite *generic_tests[] =3D { &suite__hists_filter, &suite__mmap_thread_lookup, &suite__thread_maps_share, + &suite__thread_stack, &suite__hists_output, &suite__hists_cumulate, #ifdef HAVE_LIBTRACEEVENT diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 9c96f33483d1435644da6068c3802f7a914a9de0..b2520a564417b61718f1dcb23da= 1f8cc0f601906 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -138,6 +138,7 @@ DECLARE_SUITE(expr); DECLARE_SUITE(hists_filter); DECLARE_SUITE(mmap_thread_lookup); DECLARE_SUITE(thread_maps_share); +DECLARE_SUITE(thread_stack); DECLARE_SUITE(hists_output); DECLARE_SUITE(hists_cumulate); DECLARE_SUITE(switch_tracking); diff --git a/tools/perf/tests/thread-stack.c b/tools/perf/tests/thread-stac= k.c new file mode 100644 index 0000000000000000000000000000000000000000..0239e3bee34faf8fd4ddc7b723c= f479609760064 --- /dev/null +++ b/tools/perf/tests/thread-stack.c @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include "tests.h" +#include "util/addr_location.h" +#include "util/event.h" +#include "util/sample.h" +#include "util/thread.h" +#include "util/thread-stack.h" + +#define CALL_REF 1234UL +#define RET_REF 5678UL + +struct return_check { + unsigned int matched; + unsigned int unmatched; +}; + +static int check_call_return(struct call_return *cr, + u64 *parent_db_id __maybe_unused, void *data) +{ + struct return_check *check =3D data; + + if (cr->call_ref =3D=3D CALL_REF && cr->return_ref =3D=3D RET_REF && !cr-= >flags) + check->matched++; + else + check->unmatched++; + + return 0; +} + +/* A zero expected_ret_addr asks the stack to use ip + insn_len. */ +static int check_return_address(u64 expected_ret_addr, u64 actual_ret_addr, + u32 flags) +{ + struct call_return_processor *crp; + struct return_check check =3D { }; + struct thread *thread; + struct addr_location from =3D { }, to =3D { }; + struct perf_sample sample =3D { }; + int ret =3D TEST_FAIL; + + thread =3D thread__new(getpid(), getpid()); + if (!thread) + return TEST_FAIL; + + crp =3D call_return_processor__new(check_call_return, &check); + if (!crp) + goto out; + + sample.ip =3D 0x1000; /* Call or exception source addr */ + sample.addr =3D 0x2000; /* Callee or exception handler addr */ + sample.ret_addr =3D expected_ret_addr; + sample.flags =3D PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_CALL | flags; + sample.time =3D 1; + /* Model the opcode length after an instruction fetch. */ + sample.insn_len =3D 4; + if (thread_stack__process(thread, thread__comm(thread), &sample, + &from, &to, CALL_REF, crp)) + goto out; + + sample.ip =3D 0x2000; /* Return instruction addr */ + sample.addr =3D actual_ret_addr; /* Return branch target addr */ + sample.ret_addr =3D 0; + sample.flags =3D PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | + (flags & (PERF_IP_FLAG_INTERRUPT | PERF_IP_FLAG_SYSCALLRET)); + sample.time =3D 2; + if (thread_stack__process(thread, thread__comm(thread), &sample, + &to, &from, RET_REF, crp)) + goto out; + + if (check.matched =3D=3D 1 && !check.unmatched) + ret =3D TEST_OK; + +out: + thread__put(thread); + call_return_processor__free(crp); + return ret; +} + +static int test__thread_stack(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) +{ + static const struct { + const char *name; + u64 expected_ret_addr; + u64 actual_ret_addr; + u32 flags; + } cases[] =3D { + { "ordinary call", 0, 0x1004, 0 }, + { "interrupt", 0x1000, 0x1000, PERF_IP_FLAG_ASYNC | PERF_IP_FLAG_INTERRU= PT }, + { "fault or trap", 0x1000, 0x1000, PERF_IP_FLAG_INTERRUPT }, + { "SVC", 0x1004, 0x1004, PERF_IP_FLAG_SYSCALLRET }, + }; + + for (size_t i =3D 0; i < ARRAY_SIZE(cases); i++) { + if (check_return_address(cases[i].expected_ret_addr, + cases[i].actual_ret_addr, cases[i].flags)) { + pr_debug("Incorrect return address for %s\n", cases[i].name); + return TEST_FAIL; + } + } + return TEST_OK; +} + +DEFINE_SUITE("Thread stack return addresses after instruction fetching", t= hread_stack); diff --git a/tools/perf/util/sample.c b/tools/perf/util/sample.c index bccc19e2aaf25118a8ecde88473aa6cb16fa561a..4abb689132bc27d0f2318eeafca= 20f7e57621837 100644 --- a/tools/perf/util/sample.c +++ b/tools/perf/util/sample.c @@ -29,6 +29,7 @@ void perf_sample__init(struct perf_sample *sample, bool a= ll) sample->intr_regs =3D NULL; sample->merged_callchain =3D false; sample->callchain =3D NULL; + sample->ret_addr =3D 0; } } =20 diff --git a/tools/perf/util/sample.h b/tools/perf/util/sample.h index cb4b16654876e9a5c3bfd66be3e0235ac15795e0..865ed18200f1339f5949ef3f185= ed57a34aace72 100644 --- a/tools/perf/util/sample.h +++ b/tools/perf/util/sample.h @@ -131,6 +131,11 @@ struct perf_sample { u64 time; /** @addr: The sample event PERF_SAMPLE_ADDR value. */ u64 addr; + /** + * @ret_addr: Return address supplied by the decoder for a branch sample. + * Zero means use ip + insn_len. + */ + u64 ret_addr; /** @id: The sample event PERF_SAMPLE_ID or PERF_SAMPLE_IDENTIFIER value.= */ u64 id; /** @stream_id: The sample event PERF_SAMPLE_STREAM_ID value. */ diff --git a/tools/perf/util/thread-stack.c b/tools/perf/util/thread-stack.c index 1360f44421ef8bb80fe5cfdba59be7e6029b0240..d452d1a7eabb16f040ca3dada23= e6fdec8fb1088 100644 --- a/tools/perf/util/thread-stack.c +++ b/tools/perf/util/thread-stack.c @@ -1030,7 +1030,7 @@ static int thread_stack__trace_end(struct thread_stac= k *ts, cp =3D call_path__findnew(cpr, ts->stack[ts->cnt - 1].cp, NULL, 0, ts->kernel_start); =20 - ret_addr =3D sample->ip + sample->insn_len; + ret_addr =3D sample->ret_addr ? sample->ret_addr : sample->ip + sample->i= nsn_len; =20 return thread_stack__push_cp(ts, ret_addr, sample->time, ref, cp, false, true); @@ -1154,7 +1154,8 @@ int thread_stack__process(struct thread *thread, stru= ct comm *comm, if (!sample->ip || !sample->addr) return 0; =20 - ret_addr =3D sample->ip + sample->insn_len; + /* Opcode fetching must not change a decoder-supplied return address. */ + ret_addr =3D sample->ret_addr ? sample->ret_addr : sample->ip + sample->= insn_len; if (ret_addr =3D=3D sample->addr) return 0; /* Zero-length calls are excluded */ =20 --=20 2.34.1 From nobody Thu Sep 24 13:43:08 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 65B005326DD; Wed, 23 Sep 2026 15:22:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790176923; cv=none; b=NmjfdW+Ya3tPzkFJrICyZ/YSYAqTsfwpoR20VL1fjDHVdAq8WB7xWlivvwdKTACrMtJHvmkHpjv4ddJuQp+mkXXsdi+5fA5zK8zKBWysdL9Uhg01TgUU/1xWI0/qZnRJ0wMEzJ0E0uQnamc/1BD4AqDk31AEywZ0Enko6Ktk9mQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790176923; c=relaxed/simple; bh=jr6rgp9BDzG3S84HnXLYb8kzpUHgSQc0QYp/oTK+hI0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=sBL4VIkGfB9Yj94twvGuB6GAVn4aD56Lz7Cg9DTNROlQBGN4h8HosGysakMZ+0bxILG31H3ciCp5S0QyQuS6fmYAsZKxz2f+ba1jhLgDUWqCRqepTs6r12sLwIqYsTguR2iRNGKlYT/UhTCeKdAnqWuy3i76Ms30GAloikzAMq0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=Y76lsS2v; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="Y76lsS2v" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 53DC31713; Wed, 23 Sep 2026 08:21:57 -0700 (PDT) Received: from e132581.arm.com (unknown [10.2.196.114]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 963D53F86F; Wed, 23 Sep 2026 08:21:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1790176920; bh=jr6rgp9BDzG3S84HnXLYb8kzpUHgSQc0QYp/oTK+hI0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Y76lsS2vlpiBJlvAoy5NTL2bfGWEGaYAxPfGCjNUiJqHltYPezc4IUYV6cMnMKldR 3toCC+toUqR/IFZMOYmr5glCSL3pR03ujsmlMgEc2AqlVmu7Wm+6SfUxapUIMI+E6S pcqepA1hyb2mJ54Eqy3tj4jFVGMabBrMHlmIEroM= From: Leo Yan Date: Wed, 23 Sep 2026 16:21:42 +0100 Subject: [PATCH v2 02/14] perf intel-pt: Preserve return addresses for asynchronous branches Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260923-perf_cs_etm_fix_non_taken-v2-2-6ab8c07a5455@arm.com> References: <20260923-perf_cs_etm_fix_non_taken-v2-0-6ab8c07a5455@arm.com> In-Reply-To: <20260923-perf_cs_etm_fix_non_taken-v2-0-6ab8c07a5455@arm.com> To: Arnaldo Carvalho de Melo , Namhyung Kim , Jiri Olsa , Ian Rogers , Adrian Hunter , James Clark , Mike Leach , Suzuki K Poulose , Suyash Mahar , Amir Ayupov Cc: Arnaldo Carvalho de Melo , coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Leo Yan X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1790176913; l=1356; i=leo.yan@arm.com; s=20250604; h=from:subject:message-id; bh=jr6rgp9BDzG3S84HnXLYb8kzpUHgSQc0QYp/oTK+hI0=; b=/FYgfBXt1MezJNB+vTU67BSfL2iiVIcoKpoywwZv6tbuqnER+TXCPg1oaMMchEoJMPlpF9ioj hEmsnyAO5GoCUvJHIgQ1hjqZG660JLE1f9a85rEwIY45hyAPYpCQsvh X-Developer-Key: i=leo.yan@arm.com; a=ed25519; pk=k4BaDbvkCXzBFA7Nw184KHGP5thju8lKqJYIrOWxDhI= Intel PT uses a zero instruction length for asynchronous branches so the thread stack resumes at the source IP. A dlfilter can fetch the instruction before call/return processing and replace that zero with its opcode length, advancing the saved return address. Set sample.ret_addr to sample.ip for asynchronous branch samples so instruction fetching cannot change the return address. This also covers asynchronous trace-end samples and VM exits. Assisted-by: Codex:gpt-6 Signed-off-by: Leo Yan Reviewed-by: Adrian Hunter --- tools/perf/util/intel-pt.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index 8c21c9f52d572d2dd4e15b3b5c341b253ccea1b5..e8b9c8a67b0a0635e0110eda4b6= ccb2511132fc7 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -1803,6 +1803,13 @@ static int intel_pt_synth_branch_sample(struct intel= _pt_queue *ptq) perf_sample__init(&sample, /*all=3D*/true); intel_pt_prep_b_sample(pt, ptq, event, &sample); =20 + /* + * For asynchronous branches, use the sample IP as the return address + * instead of advancing it during instruction decoding. + */ + if (sample.flags & PERF_IP_FLAG_ASYNC) + sample.ret_addr =3D sample.ip; + sample.id =3D ptq->pt->branches_id; sample.stream_id =3D ptq->pt->branches_id; =20 --=20 2.34.1 From nobody Thu Sep 24 13:43:08 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 0E5DA55D881; Wed, 23 Sep 2026 15:22:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790176925; cv=none; b=nErKhWHhpDcc8hGj7xzNz26ITdy9F6QIV4/XfuBJG3a6byuxXYQImXXEmOLLFoCzQBX12iE0SIWERkN5X34+uOwBX0b6ZIdDIrxrCUAwUwRSTmHS0XurbSZRbtI5I9T693iooObk9Jajn3rYXXHEIu6t8aV9gUbMUVmQ8p8blPE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790176925; c=relaxed/simple; bh=wi+zn9O1qBn5yWetnOxpHDcJ44qEdmWTjDLDoafQLSY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=lknCnj5qdT2AbYSm0uXnvvVXGoHPt/srBk0El1rR1EmdHPM7NOxczbOnswgRfCPUtZu0iJKL+tonBXFjeKDrluUio6JCNFeR3CoSoEHay+PxKDtWgBuWBnfJWCW5ZHF0uc7k3VvmoIavOlz36dBRLPPNpSILzPDwhv4chuN+BgM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=I9GAUcip; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="I9GAUcip" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id E15831A32; Wed, 23 Sep 2026 08:21:59 -0700 (PDT) Received: from e132581.arm.com (unknown [10.2.196.114]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 2C1B43F86F; Wed, 23 Sep 2026 08:22:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1790176923; bh=wi+zn9O1qBn5yWetnOxpHDcJ44qEdmWTjDLDoafQLSY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=I9GAUcipFtMhldJOdMoWYOAtPTFQPIy5oEZXM0Xv2Jdx4GHnIf6pff4+m0nN9OiiC EUirc5EwgHte2IV0BGDpcmfcbHfliUwqiZ+moVez3ogYH/rfBpOT1gR3RvTl36WmR+ 8MWkrpJ4LMSEzomqa8gUIUqA1HZMDFF6+PpTAYA4= From: Leo Yan Date: Wed, 23 Sep 2026 16:21:43 +0100 Subject: [PATCH v2 03/14] perf cs-etm: Break branch history when instruction memory is unavailable Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260923-perf_cs_etm_fix_non_taken-v2-3-6ab8c07a5455@arm.com> References: <20260923-perf_cs_etm_fix_non_taken-v2-0-6ab8c07a5455@arm.com> In-Reply-To: <20260923-perf_cs_etm_fix_non_taken-v2-0-6ab8c07a5455@arm.com> To: Arnaldo Carvalho de Melo , Namhyung Kim , Jiri Olsa , Ian Rogers , Adrian Hunter , James Clark , Mike Leach , Suzuki K Poulose , Suyash Mahar , Amir Ayupov Cc: Arnaldo Carvalho de Melo , coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Leo Yan X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1790176913; l=1293; i=leo.yan@arm.com; s=20250604; h=from:subject:message-id; bh=wi+zn9O1qBn5yWetnOxpHDcJ44qEdmWTjDLDoafQLSY=; b=k24/0ahZeLiRNnrB33kUsNhRAUML1zwRXvPDR6Jf8jGLim1vV4DejcevwOpoXQuEN5zMaWQYr eSUZ3XQ6GzrCMLhBEg77kMmYgfB3GBrb+FUe20xOHYt1jswDMKo+2Zr X-Developer-Key: i=leo.yan@arm.com; a=ed25519; pk=k4BaDbvkCXzBFA7Nw184KHGP5thju8lKqJYIrOWxDhI= The decoder currently ignores OCSD_GEN_TRC_ELEM_ADDR_NACC, allowing a subsequent range to be paired with stale branch history from before the unreadable code. Treat an inaccessible instruction address as a discontinuity and flush the pending range and branch history before processing subsequent elements. Assisted-by: Codex:gpt-6 Signed-off-by: Leo Yan --- tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/u= til/cs-etm-decoder/cs-etm-decoder.c index 26940f1f1b0bf44c8671d80020597c672c361c1a..35ca1a23e12735416d0d412a949= 595efc5bfe50a 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c @@ -594,7 +594,8 @@ static ocsd_datapath_resp_t cs_etm_decoder__gen_trace_e= lem_printer( =20 if (type =3D=3D OCSD_GEN_TRC_ELEM_EO_TRACE || type =3D=3D OCSD_GEN_TRC_ELEM_NO_SYNC || - type =3D=3D OCSD_GEN_TRC_ELEM_TRACE_ON) + type =3D=3D OCSD_GEN_TRC_ELEM_TRACE_ON || + type =3D=3D OCSD_GEN_TRC_ELEM_ADDR_NACC) resp =3D cs_etm_decoder__buffer_discontinuity(etmq, packet_queue, trace_chan_id); else if (type =3D=3D OCSD_GEN_TRC_ELEM_INSTR_RANGE) --=20 2.34.1 From nobody Thu Sep 24 13:43:08 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 8DAC4563FC3; Wed, 23 Sep 2026 15:22:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790176928; cv=none; b=dlNyWjKVLaKELuAFsGw4QFB3esZBxXa8Ob08nAaB7HXMkHgrhZ5Z3DczkspaXEV1P8Y1W839CfkG5cVmDF5A/bvLdsKz0qMLeE9ooR7hY4a9Rxgxy742Yvmr5yqlzIEXEJo3CrH3pxVeoNGSLtyJW9bJQe0D1NM2XnrIw1O2lms= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790176928; c=relaxed/simple; bh=BkxK+LtxfryXBC5WzXodJ262cTbTi9UYj0rhj6FzdUU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=N8LmBVPtKqQH6TJAf2HcvBFHqdMBSv8K7tVQ0tFuZyvcAoiZVMqcqIMPGzFUhakz6h8Wgcf+v1qSN4X8azt/iPupr2S8Nf/jHIaBLa4z2gQSfU5nn1YruUcaLwb3TEHTamnIVRgrWhfLjJwm9veCXufPIPrMxru6PX4ID7zIH+k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=TCgyLxOs; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="TCgyLxOs" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 72CCB1CDD; Wed, 23 Sep 2026 08:22:02 -0700 (PDT) Received: from e132581.arm.com (unknown [10.2.196.114]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id B979F3F86F; Wed, 23 Sep 2026 08:22:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1790176926; bh=BkxK+LtxfryXBC5WzXodJ262cTbTi9UYj0rhj6FzdUU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=TCgyLxOsWuFBYBSFK0MPm5WIDIBy5vHa3OJK2t+u8H+hg7cx4l6ZlVkp/T9Tr6W10 gTYn42IUTwy7HeB4iTou1epwV94ScUN6eOmvrX/l26EwYKFPFqI7wHZKaGJKWKC73A DJmIUZmkyZoyYpoNNsozAzdw3qTDafdd09WQ4pnI= From: Leo Yan Date: Wed, 23 Sep 2026 16:21:44 +0100 Subject: [PATCH v2 04/14] perf cs-etm: Centralize packet ISA initialization Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260923-perf_cs_etm_fix_non_taken-v2-4-6ab8c07a5455@arm.com> References: <20260923-perf_cs_etm_fix_non_taken-v2-0-6ab8c07a5455@arm.com> In-Reply-To: <20260923-perf_cs_etm_fix_non_taken-v2-0-6ab8c07a5455@arm.com> To: Arnaldo Carvalho de Melo , Namhyung Kim , Jiri Olsa , Ian Rogers , Adrian Hunter , James Clark , Mike Leach , Suzuki K Poulose , Suyash Mahar , Amir Ayupov Cc: Arnaldo Carvalho de Melo , coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Leo Yan X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1790176913; l=6497; i=leo.yan@arm.com; s=20250604; h=from:subject:message-id; bh=BkxK+LtxfryXBC5WzXodJ262cTbTi9UYj0rhj6FzdUU=; b=pv81NnNurnXrvgVqQnkkduobkB9PxVL6WeC1jErb5lURrX1NESRbLO47pQvkIflRvor5faD29 acKioMvidioDXaZ3ud2OsMJddcvHQ89UTLT2WqSqRldNyeRaTWjmEqV X-Developer-Key: i=leo.yan@arm.com; a=ed25519; pk=k4BaDbvkCXzBFA7Nw184KHGP5thju8lKqJYIrOWxDhI= Exception packets need their own ISA so the frontend can generate samples directly from them. Currently, ISA initialization is limited to instruction range packets. Move ISA initialization into cs_etm_decoder__buffer_packet() and use a common helper to obtain it from the OpenCSD element. Populate the ISA for instruction ranges, context updates and exceptions, leaving it unknown for other element types. Assisted-by: Codex:gpt-6 Signed-off-by: Leo Yan --- tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 69 +++++++++++++++------= ---- 1 file changed, 41 insertions(+), 28 deletions(-) diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/u= til/cs-etm-decoder/cs-etm-decoder.c index 35ca1a23e12735416d0d412a949595efc5bfe50a..469aba5e596a791289c5bcece13= 2aba7b0baf6c3 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c @@ -368,9 +368,38 @@ cs_etm_decoder__reset_timestamp(struct cs_etm_packet_q= ueue *packet_queue) packet_queue->instr_count =3D 0; } =20 +static enum cs_etm_isa +cs_etm_decoder__get_isa(const ocsd_generic_trace_elem *elem) +{ + /* + * OpenCSD preserves ISA and context between output elements, including + * exceptions after a context change with no intervening range. + */ + if (elem->elem_type !=3D OCSD_GEN_TRC_ELEM_PE_CONTEXT && + elem->elem_type !=3D OCSD_GEN_TRC_ELEM_INSTR_RANGE && + elem->elem_type !=3D OCSD_GEN_TRC_ELEM_EXCEPTION) + return CS_ETM_ISA_UNKNOWN; + + switch (elem->isa) { + case ocsd_isa_aarch64: + return CS_ETM_ISA_A64; + case ocsd_isa_arm: + return CS_ETM_ISA_A32; + case ocsd_isa_thumb2: + return CS_ETM_ISA_T32; + case ocsd_isa_tee: + case ocsd_isa_jazelle: + case ocsd_isa_custom: + case ocsd_isa_unknown: + default: + return CS_ETM_ISA_UNKNOWN; + } +} + static ocsd_datapath_resp_t cs_etm_decoder__buffer_packet(struct cs_etm_queue *etmq, struct cs_etm_packet_queue *packet_queue, + const ocsd_generic_trace_elem *elem, const u8 trace_chan_id, enum cs_etm_sample_type sample_type) { @@ -389,7 +418,7 @@ cs_etm_decoder__buffer_packet(struct cs_etm_queue *etmq, packet_queue->packet_count++; =20 packet_queue->packet_buffer[et].sample_type =3D sample_type; - packet_queue->packet_buffer[et].isa =3D CS_ETM_ISA_UNKNOWN; + packet_queue->packet_buffer[et].isa =3D cs_etm_decoder__get_isa(elem); packet_queue->packet_buffer[et].cpu =3D cpu; packet_queue->packet_buffer[et].start_addr =3D CS_ETM_INVAL_ADDR; packet_queue->packet_buffer[et].end_addr =3D CS_ETM_INVAL_ADDR; @@ -420,31 +449,13 @@ cs_etm_decoder__buffer_range(struct cs_etm_queue *etm= q, int ret =3D 0; struct cs_etm_packet *packet; =20 - ret =3D cs_etm_decoder__buffer_packet(etmq, packet_queue, trace_chan_id, - CS_ETM_RANGE); + ret =3D cs_etm_decoder__buffer_packet(etmq, packet_queue, elem, + trace_chan_id, CS_ETM_RANGE); if (ret !=3D OCSD_RESP_CONT && ret !=3D OCSD_RESP_WAIT) return ret; =20 packet =3D &packet_queue->packet_buffer[packet_queue->tail]; =20 - switch (elem->isa) { - case ocsd_isa_aarch64: - packet->isa =3D CS_ETM_ISA_A64; - break; - case ocsd_isa_arm: - packet->isa =3D CS_ETM_ISA_A32; - break; - case ocsd_isa_thumb2: - packet->isa =3D CS_ETM_ISA_T32; - break; - case ocsd_isa_tee: - case ocsd_isa_jazelle: - case ocsd_isa_custom: - case ocsd_isa_unknown: - default: - packet->isa =3D CS_ETM_ISA_UNKNOWN; - } - packet->start_addr =3D elem->st_addr; packet->end_addr =3D elem->en_addr; packet->instr_count =3D elem->num_instr_range; @@ -483,6 +494,7 @@ cs_etm_decoder__buffer_range(struct cs_etm_queue *etmq, static ocsd_datapath_resp_t cs_etm_decoder__buffer_discontinuity(struct cs_etm_queue *etmq, struct cs_etm_packet_queue *queue, + const ocsd_generic_trace_elem *elem, const uint8_t trace_chan_id) { /* @@ -490,7 +502,7 @@ cs_etm_decoder__buffer_discontinuity(struct cs_etm_queu= e *etmq, * reset time statistics. */ cs_etm_decoder__reset_timestamp(queue); - return cs_etm_decoder__buffer_packet(etmq, queue, trace_chan_id, + return cs_etm_decoder__buffer_packet(etmq, queue, elem, trace_chan_id, CS_ETM_DISCONTINUITY); } =20 @@ -502,7 +514,7 @@ cs_etm_decoder__buffer_exception(struct cs_etm_queue *e= tmq, { int ret =3D 0; struct cs_etm_packet *packet; =20 - ret =3D cs_etm_decoder__buffer_packet(etmq, queue, trace_chan_id, + ret =3D cs_etm_decoder__buffer_packet(etmq, queue, elem, trace_chan_id, CS_ETM_EXCEPTION); if (ret !=3D OCSD_RESP_CONT && ret !=3D OCSD_RESP_WAIT) return ret; @@ -516,9 +528,10 @@ cs_etm_decoder__buffer_exception(struct cs_etm_queue *= etmq, static ocsd_datapath_resp_t cs_etm_decoder__buffer_exception_ret(struct cs_etm_queue *etmq, struct cs_etm_packet_queue *queue, + const ocsd_generic_trace_elem *elem, const uint8_t trace_chan_id) { - return cs_etm_decoder__buffer_packet(etmq, queue, trace_chan_id, + return cs_etm_decoder__buffer_packet(etmq, queue, elem, trace_chan_id, CS_ETM_EXCEPTION_RET); } =20 @@ -555,8 +568,8 @@ cs_etm_decoder__set_tid(struct cs_etm_queue *etmq, elem->context.exception_level, tid)) return OCSD_RESP_FATAL_SYS_ERR; =20 - ret =3D cs_etm_decoder__buffer_packet(etmq, packet_queue, trace_chan_id, - CS_ETM_CONTEXT); + ret =3D cs_etm_decoder__buffer_packet(etmq, packet_queue, elem, + trace_chan_id, CS_ETM_CONTEXT); if (ret !=3D OCSD_RESP_CONT && ret !=3D OCSD_RESP_WAIT) return ret; =20 @@ -597,7 +610,7 @@ static ocsd_datapath_resp_t cs_etm_decoder__gen_trace_e= lem_printer( type =3D=3D OCSD_GEN_TRC_ELEM_TRACE_ON || type =3D=3D OCSD_GEN_TRC_ELEM_ADDR_NACC) resp =3D cs_etm_decoder__buffer_discontinuity(etmq, packet_queue, - trace_chan_id); + elem, trace_chan_id); else if (type =3D=3D OCSD_GEN_TRC_ELEM_INSTR_RANGE) resp =3D cs_etm_decoder__buffer_range(etmq, packet_queue, elem, trace_chan_id); @@ -606,7 +619,7 @@ static ocsd_datapath_resp_t cs_etm_decoder__gen_trace_e= lem_printer( trace_chan_id); else if (type =3D=3D OCSD_GEN_TRC_ELEM_EXCEPTION_RET) resp =3D cs_etm_decoder__buffer_exception_ret(etmq, packet_queue, - trace_chan_id); + elem, trace_chan_id); else if (type =3D=3D OCSD_GEN_TRC_ELEM_TIMESTAMP) resp =3D cs_etm_decoder__do_hard_timestamp(etmq, elem, trace_chan_id, --=20 2.34.1 From nobody Thu Sep 24 13:43:08 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 4298955198C; Wed, 23 Sep 2026 15:22:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790176930; cv=none; b=PuU29hW1TeCntY1ZWcWQtwxG+nO5C+JMBX60p85qvzZ41rm9COOSrpyOrXZ0PJQ7bZzqmb7Jbl6TO9JqkLN3H4SdwLCgU8bROO241fBxe6A6K2ktvza1mMDka9LuggW1WabMBzZ79eroCT1Qt1TXHTeOlA9mODCWMlceYGiLWZg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790176930; c=relaxed/simple; bh=sDZ3zCmdsg/NDDnz3ZYjdtSiVUMhALulqSJXMlTIm4k=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Eo5A1B2qmKQiNJDq5k9SeeGUrPa9Ytv1v4NP6JzhSoqKUfeqVNtJuczvVYnP+2SFtn1Am8a6kQyuDoyq9Z/bF4XF5EiYlsm/pzPaOne0Skqoi5u0TkuWKSdgeFfTmbSxuqaGCMPioiM8e/OmN600+dPF+mCJgclrNaZAqrAfD1k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=lo/9NyxK; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="lo/9NyxK" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 0B0FD1CE0; Wed, 23 Sep 2026 08:22:05 -0700 (PDT) Received: from e132581.arm.com (unknown [10.2.196.114]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 4FE953F86F; Wed, 23 Sep 2026 08:22:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1790176928; bh=sDZ3zCmdsg/NDDnz3ZYjdtSiVUMhALulqSJXMlTIm4k=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=lo/9NyxKyHnGlMV3zrAqgx2HIQcW8WAKeqNcS3QPYlRNALJ5SC7hfrg8NDvGn2sle mFYzLSScIAjANPdgcjaCSeTonMNB3NsFTDk2kSWHmCJng98fWbjesJOuy0jfFcfcdx 5aAe/3lPNnWQQlP4JksM1gK7iEutmDNF4DVKlZ/Y= From: Leo Yan Date: Wed, 23 Sep 2026 16:21:45 +0100 Subject: [PATCH v2 05/14] perf cs-etm: Use the recorded instruction size for A32 and A64 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260923-perf_cs_etm_fix_non_taken-v2-5-6ab8c07a5455@arm.com> References: <20260923-perf_cs_etm_fix_non_taken-v2-0-6ab8c07a5455@arm.com> In-Reply-To: <20260923-perf_cs_etm_fix_non_taken-v2-0-6ab8c07a5455@arm.com> To: Arnaldo Carvalho de Melo , Namhyung Kim , Jiri Olsa , Ian Rogers , Adrian Hunter , James Clark , Mike Leach , Suzuki K Poulose , Suyash Mahar , Amir Ayupov Cc: Arnaldo Carvalho de Melo , coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Leo Yan X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1790176913; l=1132; i=leo.yan@arm.com; s=20250604; h=from:subject:message-id; bh=sDZ3zCmdsg/NDDnz3ZYjdtSiVUMhALulqSJXMlTIm4k=; b=aXxBtmOiw7igZ8rNNHw3nOoekoZ794ac+lyLnnnKlVfrKJwvH3th/RqpxkBY1MLhOgPY3npEe pU6YBbVUmJ6Bb43A1u2myH1E8pUGLyJmTDmMyx6AHAprPbzTrYvpmX+ X-Developer-Key: i=leo.yan@arm.com; a=ed25519; pk=k4BaDbvkCXzBFA7Nw184KHGP5thju8lKqJYIrOWxDhI= Use packet->last_instr_size in cs_etm__instr_size() instead of a hard-coded value, allowing the decoder to supply the instruction size. Keep per-address decoding for T32. A range can mix 16-bit and 32-bit instructions, so last_instr_size describes only the final instruction and cannot determine the size at an arbitrary address in the range. Assisted-by: Codex:gpt-6 Signed-off-by: Leo Yan --- tools/perf/util/cs-etm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 2d1ab34f7b6b5a6331005c16c6a418d123c815eb..0163d93ac2d537a2190536e77d2= 4628b4d707751 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -1358,8 +1358,7 @@ static inline int cs_etm__instr_size(struct cs_etm_qu= eue *etmq, if (packet->isa =3D=3D CS_ETM_ISA_T32) return cs_etm__t32_instr_size(etmq, tidq, packet, addr); =20 - /* Otherwise, 4-byte instruction size for A32/A64 */ - return 4; + return packet->last_instr_size; } =20 static inline u64 cs_etm__first_executed_instr(struct cs_etm_packet *packe= t) --=20 2.34.1 From nobody Thu Sep 24 13:43:08 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id A20E4579834; Wed, 23 Sep 2026 15:22:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790176933; cv=none; b=G1tWPmsVpWir0eC01ahQa7fs8vyrx9CyJK2dzdI+7UUqDQsyNxWqHkMXN40Z2BIC0ohT2/NLfnUeaMRIFGYNfXbnw8Va97WnsfR3f26ZG1GyCy9dKw50oKG4bp34LBunhItb+G17aRnbzJwQnmeHSCvH5qiA4qBtssFUsN+Rdfs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790176933; c=relaxed/simple; bh=SnVKOKvRTdz5QhlRrwDJN/1IPX5DokfIgkiOL4pojQY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=J3qPEJgSMEQo/KyvVwa6enzpTo0n5CWD9ZJkzn9M/WbLzdb1nxsItXOTJ3TTBomUeaMxjLQ/SCfeDXJEI5k6KqPwfmQArAFRtySKzB8Pof5BpSYBzxuoIPZNkPesdAvE4zBVFQYzOj1mcGDeVld4LQXtycwHceOKTQn3REwbGmg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=H/vxQG0O; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="H/vxQG0O" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 9321B1CE2; Wed, 23 Sep 2026 08:22:07 -0700 (PDT) Received: from e132581.arm.com (unknown [10.2.196.114]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id D99793F86F; Wed, 23 Sep 2026 08:22:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1790176931; bh=SnVKOKvRTdz5QhlRrwDJN/1IPX5DokfIgkiOL4pojQY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=H/vxQG0ONNOz61LdE1YH0bQ8RYYezfLsQZhTuSf1Bdq5/MgX8LMyp6YxmZMMYzYo6 47g7jV1Tfb4fPu5bmH1lRiAYKz071imoljTCA1IZK5XcXMC19P19307zrko2phXdzn OHHYZhytjS5VNorhgiIgdv1f0hXkj1cBydqKofYk= From: Leo Yan Date: Wed, 23 Sep 2026 16:21:46 +0100 Subject: [PATCH v2 06/14] perf cs-etm: Mark branches that were not taken Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260923-perf_cs_etm_fix_non_taken-v2-6-6ab8c07a5455@arm.com> References: <20260923-perf_cs_etm_fix_non_taken-v2-0-6ab8c07a5455@arm.com> In-Reply-To: <20260923-perf_cs_etm_fix_non_taken-v2-0-6ab8c07a5455@arm.com> To: Arnaldo Carvalho de Melo , Namhyung Kim , Jiri Olsa , Ian Rogers , Adrian Hunter , James Clark , Mike Leach , Suzuki K Poulose , Suyash Mahar , Amir Ayupov Cc: Arnaldo Carvalho de Melo , coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Leo Yan X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1790176913; l=1907; i=leo.yan@arm.com; s=20250604; h=from:subject:message-id; bh=SnVKOKvRTdz5QhlRrwDJN/1IPX5DokfIgkiOL4pojQY=; b=1yzQkRkAzFWtYer8yI+mq4vpBJ3bRr3SIBqwniIx2H8n/EskoPkDm6Ytax33rd2/0T4faCcus O9+tsnsiezNCadzV71HTR0n5jpz3+c/iAYu9EnjDYCkpj9hlGBZivkA X-Developer-Key: i=leo.yan@arm.com; a=ed25519; pk=k4BaDbvkCXzBFA7Nw184KHGP5thju8lKqJYIrOWxDhI= An exception can transfer execution to the kernel after any instruction. When this creates a trace boundary, perf may attribute the trace-end sample to the last instruction in the range. If that instruction is an untaken branch, reporting only its branch type can make the transfer look like a taken branch. Set PERF_IP_FLAG_NOT_TAKEN for branch ranges when last_instr_taken_branch is false. This records the decoded branch outcome independently of exception entry. For a discontinuity without an exception element, perf script previously reported an untaken B.LS as: tr end jcc 4000f8 =3D> 0 b.ls #0x400118 tr strt jmp 0 =3D> 4000fc With the not-taken flag set: tr end jcc/not_taken/ 4000f8 =3D> 0 b.ls #0x400118 tr strt jmp 0 =3D> 4000fc Here, 4000f8 remains the last traced instruction and 4000fc is the trace restart address. These boundary samples do not establish an IRQ entry or an exception return; the not_taken flag records only the branch outcome. Assisted-by: Codex:gpt-6 Signed-off-by: Leo Yan --- tools/perf/util/cs-etm.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 0163d93ac2d537a2190536e77d24628b4d707751..c54218aeef53e8420447e9a2bee= 6e98d8225e335 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -2415,6 +2415,11 @@ static int cs_etm__set_sample_flags(struct cs_etm_qu= eue *etmq, packet->flags =3D PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN; =20 + /* Report branch that is not taken */ + if ((packet->flags & PERF_IP_FLAG_BRANCH) && + !packet->last_instr_taken_branch) + packet->flags |=3D PERF_IP_FLAG_NOT_TAKEN; + /* * Decoder might insert a discontinuity in the middle of * instruction packets, fixup prev_packet with flag --=20 2.34.1 From nobody Thu Sep 24 13:43:08 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id B0C9355D894; Wed, 23 Sep 2026 15:22:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790176937; cv=none; b=bEA4Mmy3RpX/V/6rPxbeRcGcw5/IpLJSkt+sgsMmaiCdLt0KooCrRKxfTgEHRxCTSd4hRn2S5+hBWqbsADcgKhZXisXuWkJQmShkMJKHgy7alX+ln89CNzXul/ZUhLPkDysqcZtJQPua/jbbw1by3fvZcdugHMIA5/zMcKpgF5Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790176937; c=relaxed/simple; bh=MElIxOjSVxPdBco/8DPDHK5NhvwHvte23jsz8G8f+rM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=KTpYHzU6JRZvHS39kQH8Yn0zRWkR0orVQ9PGnAG2yVtaG6U1bd+tcVlVVqiShencviFnYMEAz4hApSjg1ndMD6TG+ZV+EqO5CL1c8IMgXZUaH5P6ynpAteDTJ7YYJ/STOuCjeBn3F382APNzP6gHE3KxHOXp38axqLYmjozYY48= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=LH/LRUMK; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="LH/LRUMK" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 27F231D13; Wed, 23 Sep 2026 08:22:10 -0700 (PDT) Received: from e132581.arm.com (unknown [10.2.196.114]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 6F38D3F86F; Wed, 23 Sep 2026 08:22:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1790176933; bh=MElIxOjSVxPdBco/8DPDHK5NhvwHvte23jsz8G8f+rM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=LH/LRUMKRLOIPuKLKmk7PEsVpOo1X/VUd1L9nrIXZemJ7HFAnypchvd3nC+X43tFJ PWiWVbfzWj0dx3iVistehIvUtr+PQyMSL0DJgR7KVZ0ZVKEGYcu5bJ6YiUDzQrfvgg ryCAoYtOdw9cVHC9nWq2wIV8qKMAW+F2fV8Q9Tnw= From: Leo Yan Date: Wed, 23 Sep 2026 16:21:47 +0100 Subject: [PATCH v2 07/14] perf cs-etm: Factor out final instruction sample synthesis Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260923-perf_cs_etm_fix_non_taken-v2-7-6ab8c07a5455@arm.com> References: <20260923-perf_cs_etm_fix_non_taken-v2-0-6ab8c07a5455@arm.com> In-Reply-To: <20260923-perf_cs_etm_fix_non_taken-v2-0-6ab8c07a5455@arm.com> To: Arnaldo Carvalho de Melo , Namhyung Kim , Jiri Olsa , Ian Rogers , Adrian Hunter , James Clark , Mike Leach , Suzuki K Poulose , Suyash Mahar , Amir Ayupov Cc: Arnaldo Carvalho de Melo , coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Leo Yan X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1790176913; l=3714; i=leo.yan@arm.com; s=20250604; h=from:subject:message-id; bh=MElIxOjSVxPdBco/8DPDHK5NhvwHvte23jsz8G8f+rM=; b=PcwS9HINPU78ZZZPPE0+emH4fKk1SGGj3QzMUJEah63+DQBdZ7D49nPXZb5RqIEM39gBUfqIb rJMKpmWktBwCs/1vjH6XKhONX5ex0F+69wH+EKHhQgyIhOp32SdCfQu X-Developer-Key: i=leo.yan@arm.com; a=ed25519; pk=k4BaDbvkCXzBFA7Nw184KHGP5thju8lKqJYIrOWxDhI= cs_etm__flush() and cs_etm__end_block() duplicate the instruction sample used to report the remaining branch history at the end of a trace. Move this code into cs_etm__synth_last_instruction_sample(), preserving the sample generation and instruction period reset. Assisted-by: Codex:gpt-6 Signed-off-by: Leo Yan --- tools/perf/util/cs-etm.c | 71 ++++++++++++++++++--------------------------= ---- 1 file changed, 26 insertions(+), 45 deletions(-) diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index c54218aeef53e8420447e9a2bee6e98d8225e335..5b5ee52c0277f5ff8f03c2908e4= af1d7801845ff 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -1685,6 +1685,28 @@ static int cs_etm__synth_instruction_sample(struct c= s_etm_queue *etmq, return ret; } =20 +static int cs_etm__synth_last_instruction_sample(struct cs_etm_queue *etmq, + struct cs_etm_traceid_queue *tidq) +{ + struct cs_etm_packet *packet =3D tidq->prev_packet; + int ret; + + if (!etmq->etm->synth_opts.last_branch || + !etmq->etm->synth_opts.instructions) + return 0; + + if (packet->sample_type !=3D CS_ETM_RANGE) + return 0; + + ret =3D cs_etm__synth_instruction_sample(etmq, tidq, packet, + cs_etm__last_executed_instr(packet), + tidq->period_instructions); + if (!ret) + tidq->period_instructions =3D 0; + + return ret; +} + /* * The cs etm packet encodes an instruction range between a branch target * and the next taken branch. Generate sample accordingly. @@ -2023,28 +2045,9 @@ static int cs_etm__flush(struct cs_etm_queue *etmq, if (tidq->prev_packet->sample_type =3D=3D CS_ETM_EMPTY) goto swap_packet; =20 - if (etmq->etm->synth_opts.last_branch && - etmq->etm->synth_opts.instructions && - tidq->prev_packet->sample_type =3D=3D CS_ETM_RANGE) { - u64 addr; - /* - * Generate a last branch event for the branches left in the - * circular buffer at the end of the trace. - * - * Use the address of the end of the last reported execution - * range - */ - addr =3D cs_etm__last_executed_instr(tidq->prev_packet); - - err =3D cs_etm__synth_instruction_sample( - etmq, tidq, tidq->prev_packet, addr, - tidq->period_instructions); - if (err) - return err; - - tidq->period_instructions =3D 0; - - } + err =3D cs_etm__synth_last_instruction_sample(etmq, tidq); + if (err) + return err; =20 if (etm->synth_opts.branches && tidq->prev_packet->sample_type =3D=3D CS_ETM_RANGE) { @@ -2066,8 +2069,6 @@ static int cs_etm__flush(struct cs_etm_queue *etmq, static int cs_etm__end_block(struct cs_etm_queue *etmq, struct cs_etm_traceid_queue *tidq) { - int err; - /* * It has no new packet coming and 'etmq->packet' contains the stale * packet which was set at the previous time with packets swapping; @@ -2077,27 +2078,7 @@ static int cs_etm__end_block(struct cs_etm_queue *et= mq, * event for the branches left in the circular buffer at the end of * the trace. */ - if (etmq->etm->synth_opts.last_branch && - etmq->etm->synth_opts.instructions && - tidq->prev_packet->sample_type =3D=3D CS_ETM_RANGE) { - u64 addr; - - /* - * Use the address of the end of the last reported execution - * range. - */ - addr =3D cs_etm__last_executed_instr(tidq->prev_packet); - - err =3D cs_etm__synth_instruction_sample( - etmq, tidq, tidq->prev_packet, addr, - tidq->period_instructions); - if (err) - return err; - - tidq->period_instructions =3D 0; - } - - return 0; + return cs_etm__synth_last_instruction_sample(etmq, tidq); } =20 static int cs_etm__flush_stack_cb(struct thread *thread, --=20 2.34.1 From nobody Thu Sep 24 13:43:08 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id DF8BA57C72E; Wed, 23 Sep 2026 15:22:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790176939; cv=none; b=BaUg/FcR/R0wPr81o1fIwtFNhomrArhG0jyIgZ1nZYtOYLUMqG3ln3uDHXkYQumzutf7QYQEiLtF4FWRTbKB5heebL2ry1Xo9yjoCS6MqH276Xk3Eg4O6XpkZ+pf+qg/4nl38KHtnvuUC0lpaPXXikMkHIbYRYZasluWrmhjjUE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790176939; c=relaxed/simple; bh=7P52Iamvzkdn9OJUTBT7htFwBgcAKkrJTYDZdLDrnHU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZVWeXw8lBc6QzVdt/9cy9NA3hshLJErFLySrBhfVtsBXeaH0ejbHimvC1KTZiiz+xF4usONQcrrTdWHK0OOuFLNIwbHzie3CBURuZ6jESTWdJSsSRoZaCk6Wjo0UXOKmJhtow0B7si2PyY3GMqHFK3ZD7n/myGPnlcM0+ENEl5I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=d6PMTZjQ; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="d6PMTZjQ" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id B6E341D14; Wed, 23 Sep 2026 08:22:12 -0700 (PDT) Received: from e132581.arm.com (unknown [10.2.196.114]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 0574B3F86F; Wed, 23 Sep 2026 08:22:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1790176936; bh=7P52Iamvzkdn9OJUTBT7htFwBgcAKkrJTYDZdLDrnHU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=d6PMTZjQ7ZSxzrqFK/e2yI5C8+JzcOrD2Qt5cClF8mvJrqAShnmRPOj6My2rjA2cd 1ci29qzO5V6gHwW5lWsIxJerW/YKdpdLVD1+jzzUrFVbzJ4W/g241y0u1aby3faEWw dIqgUzTgMb+vIaeGNQqCSsiLOY9tI7MxfcoAjvj8= From: Leo Yan Date: Wed, 23 Sep 2026 16:21:48 +0100 Subject: [PATCH v2 08/14] perf cs-etm: Centralize branch sample synthesis checks Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260923-perf_cs_etm_fix_non_taken-v2-8-6ab8c07a5455@arm.com> References: <20260923-perf_cs_etm_fix_non_taken-v2-0-6ab8c07a5455@arm.com> In-Reply-To: <20260923-perf_cs_etm_fix_non_taken-v2-0-6ab8c07a5455@arm.com> To: Arnaldo Carvalho de Melo , Namhyung Kim , Jiri Olsa , Ian Rogers , Adrian Hunter , James Clark , Mike Leach , Suzuki K Poulose , Suyash Mahar , Amir Ayupov Cc: Arnaldo Carvalho de Melo , coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Leo Yan X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1790176913; l=2314; i=leo.yan@arm.com; s=20250604; h=from:subject:message-id; bh=7P52Iamvzkdn9OJUTBT7htFwBgcAKkrJTYDZdLDrnHU=; b=erlS3IJaBTyVBA7wVoMmrsa9kP3LBQ1uP7H7zeLDxlwD+GmLediFjMaSkpeyuHFLm+Sq3Q2Ot H6pTVJGzJV/Bf7j802YxLvf3vPZBvTZxpInkUwA1nbnhdfCI9jL8XBI X-Developer-Key: i=leo.yan@arm.com; a=ed25519; pk=k4BaDbvkCXzBFA7Nw184KHGP5thju8lKqJYIrOWxDhI= Move the branch-synthesis option and packet checks from cs_etm__sample() into cs_etm__synth_branch_sample(), alongside the existing branch filter. Call the helper directly from cs_etm__sample() and cs_etm__flush(). Accept trace-start and trace-end flags, this preserves boundary samples without a taken branch. Assisted-by: Codex:gpt-6 Signed-off-by: Leo Yan --- tools/perf/util/cs-etm.c | 37 ++++++++++++++----------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 5b5ee52c0277f5ff8f03c2908e4af1d7801845ff..c8a92b5dba6001329d68766d540= b9b7ead90e9e6 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -1726,6 +1726,14 @@ static int cs_etm__synth_branch_sample(struct cs_etm= _queue *etmq, } dummy_bs; u64 ip; =20 + if (!etm->synth_opts.branches) + return 0; + + if (!cs_etm__packet_has_taken_branch(tidq->prev_packet) && + !(tidq->prev_packet->flags & (PERF_IP_FLAG_TRACE_BEGIN | + PERF_IP_FLAG_TRACE_END))) + return 0; + if (etm->branches_filter && !(etm->branches_filter & tidq->prev_packet->flags)) return 0; @@ -1965,23 +1973,9 @@ static int cs_etm__sample(struct cs_etm_queue *etmq, } } =20 - if (etm->synth_opts.branches) { - bool generate_sample =3D false; - - /* Generate sample for tracing on packet */ - if (tidq->prev_packet->sample_type =3D=3D CS_ETM_DISCONTINUITY) - generate_sample =3D true; - - /* Generate sample for branch taken packet */ - if (cs_etm__packet_has_taken_branch(tidq->prev_packet)) - generate_sample =3D true; - - if (generate_sample) { - ret =3D cs_etm__synth_branch_sample(etmq, tidq); - if (ret) - return ret; - } - } + ret =3D cs_etm__synth_branch_sample(etmq, tidq); + if (ret) + return ret; =20 cs_etm__packet_swap(etm, tidq); =20 @@ -2049,12 +2043,9 @@ static int cs_etm__flush(struct cs_etm_queue *etmq, if (err) return err; =20 - if (etm->synth_opts.branches && - tidq->prev_packet->sample_type =3D=3D CS_ETM_RANGE) { - err =3D cs_etm__synth_branch_sample(etmq, tidq); - if (err) - return err; - } + err =3D cs_etm__synth_branch_sample(etmq, tidq); + if (err) + return err; =20 swap_packet: cs_etm__packet_swap(etm, tidq); --=20 2.34.1 From nobody Thu Sep 24 13:43:08 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 7E29157D22F; Wed, 23 Sep 2026 15:22:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790176941; cv=none; b=Jg2Tp4Zi5fwGI12fzktDNwtBX+qfWNuuJL43vWC95v1HFm1kUaEQlc1e31/Doduj0cjizgWNej+zhwXnBe+j6wZEvoexY9RVrRmAuye9pe5YuJjDzoeyh8iWbtEfkJpq16iRJpCTVQfPncqIESODWfnkd45AW/Z8/ekejH/+Ap0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790176941; c=relaxed/simple; bh=hPqdR80akvK7Nfqzy3k8MnAmzU+aKUYR/Uuzx/bHgb8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=f2wlvG/gMALZYvN+pjBerDZS1zUB/KfySJA+IbaCMe2hCMPCpGYvx70oX3ccuC4z8ZdT1wHFTD5epjciiuJLUH5K5ZUTnSn4NVr7chfeYam0IN1Rq3dIVaHB4OfR2Y4HyiIlrTaBFUgVN/XkStSQXW1KU2cQxCPGtrMUjbwqHps= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=rvnX2tfW; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="rvnX2tfW" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4979C1D6F; Wed, 23 Sep 2026 08:22:15 -0700 (PDT) Received: from e132581.arm.com (unknown [10.2.196.114]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 8F9663F86F; Wed, 23 Sep 2026 08:22:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1790176938; bh=hPqdR80akvK7Nfqzy3k8MnAmzU+aKUYR/Uuzx/bHgb8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=rvnX2tfWzMyqeIs2iJOYRIxwOhQO2Wh3jtiedIkrBrJ03RhUwDZUIBm8V3emR4JhR 3qiPoEcYo1An7jDY5YWWc203NLu1dXaHLF87T9XZdeThpJGcUDRbw0GH1eb3Im4NB/ fe9ETNTHLAq9CmEBVfE5kZjb8a9UmLF5TrrKzLGs= From: Leo Yan Date: Wed, 23 Sep 2026 16:21:49 +0100 Subject: [PATCH v2 09/14] perf cs-etm: Classify exception calls using the exception packet Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260923-perf_cs_etm_fix_non_taken-v2-9-6ab8c07a5455@arm.com> References: <20260923-perf_cs_etm_fix_non_taken-v2-0-6ab8c07a5455@arm.com> In-Reply-To: <20260923-perf_cs_etm_fix_non_taken-v2-0-6ab8c07a5455@arm.com> To: Arnaldo Carvalho de Melo , Namhyung Kim , Jiri Olsa , Ian Rogers , Adrian Hunter , James Clark , Mike Leach , Suzuki K Poulose , Suyash Mahar , Amir Ayupov Cc: Arnaldo Carvalho de Melo , coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Leo Yan X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1790176913; l=4462; i=leo.yan@arm.com; s=20250604; h=from:subject:message-id; bh=hPqdR80akvK7Nfqzy3k8MnAmzU+aKUYR/Uuzx/bHgb8=; b=PnSsJFS+2FvuZNBiU02dhEYbvGfqez75wpNzNNCgPt5Rai7e9KtxQ4OW7KFOy6bs34jHyuQ/7 dfiKaG22yKaBEglTDJ/AmusPDtSPnqe876q/+Fo/diFa8RLcGUoyuqY X-Developer-Key: i=leo.yan@arm.com; a=ed25519; pk=k4BaDbvkCXzBFA7Nw184KHGP5thju8lKqJYIrOWxDhI= ETMv4 and ETE use the same exception number for SVC, HVC and SMC. Identify SVC by inspecting the instruction before the preferred return address in the exception packet. Preserve the exception level and preferred return address from OpenCSD, and use them with the packet's ISA in cs_etm__is_syscall() and cs_etm__is_sync_exception(). This makes exception call classification independent of the preceding instruction range. Assisted-by: Codex:gpt-6 Signed-off-by: Leo Yan --- tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 7 ++++++- tools/perf/util/cs-etm.c | 10 +++------- tools/perf/util/cs-etm.h | 1 + 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/u= til/cs-etm-decoder/cs-etm-decoder.c index 469aba5e596a791289c5bcece132aba7b0baf6c3..48e8c355a3e495cc30dcb4056c0= 4a034d10ce860 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c @@ -511,7 +511,8 @@ cs_etm_decoder__buffer_exception(struct cs_etm_queue *e= tmq, struct cs_etm_packet_queue *queue, const ocsd_generic_trace_elem *elem, const uint8_t trace_chan_id) -{ int ret =3D 0; +{ + int ret =3D 0; struct cs_etm_packet *packet; =20 ret =3D cs_etm_decoder__buffer_packet(etmq, queue, elem, trace_chan_id, @@ -521,6 +522,10 @@ cs_etm_decoder__buffer_exception(struct cs_etm_queue *= etmq, =20 packet =3D &queue->packet_buffer[queue->tail]; packet->exception_number =3D elem->exception_number; + if (elem->context.el_valid) + packet->el =3D elem->context.exception_level; + if (elem->excep_ret_addr) + packet->end_addr =3D elem->en_addr; =20 return ret; } diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index c8a92b5dba6001329d68766d540b9b7ead90e9e6..a40b3b2fe2e6318154111d9b7eb= d05bee53934f1 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -2019,7 +2019,7 @@ static int cs_etm__exception(struct cs_etm_traceid_qu= eue *tidq) * to generate branch sample for the instruction range before the * exception is trapped to kernel or before the exception returning. * - * The exception packet includes the dummy address values, so don't + * The exception packet does not describe an instruction range, so don't * swap PACKET with PREV_PACKET. This keeps PREV_PACKET to be useful * for generating instruction and branch samples. */ @@ -2225,7 +2225,6 @@ static bool cs_etm__is_syscall(struct cs_etm_queue *e= tmq, struct cs_etm_traceid_queue *tidq, u64 magic) { struct cs_etm_packet *packet =3D tidq->packet; - struct cs_etm_packet *prev_packet =3D tidq->prev_packet; =20 if (magic =3D=3D __perf_cs_etmv3_magic) if (packet->exception_number =3D=3D CS_ETMV3_EXC_SVC) @@ -2238,8 +2237,7 @@ static bool cs_etm__is_syscall(struct cs_etm_queue *e= tmq, */ if (magic =3D=3D __perf_cs_etmv4_magic || magic =3D=3D __perf_cs_ete_magi= c) { if (packet->exception_number =3D=3D CS_ETMV4_EXC_CALL && - cs_etm__is_svc_instr(etmq, tidq, prev_packet, - prev_packet->end_addr)) + cs_etm__is_svc_instr(etmq, tidq, packet, packet->end_addr)) return true; } =20 @@ -2277,7 +2275,6 @@ static bool cs_etm__is_sync_exception(struct cs_etm_q= ueue *etmq, u64 magic) { struct cs_etm_packet *packet =3D tidq->packet; - struct cs_etm_packet *prev_packet =3D tidq->prev_packet; =20 if (magic =3D=3D __perf_cs_etmv3_magic) if (packet->exception_number =3D=3D CS_ETMV3_EXC_SMC || @@ -2301,8 +2298,7 @@ static bool cs_etm__is_sync_exception(struct cs_etm_q= ueue *etmq, * (SMC, HVC) are taken as sync exceptions. */ if (packet->exception_number =3D=3D CS_ETMV4_EXC_CALL && - !cs_etm__is_svc_instr(etmq, tidq, prev_packet, - prev_packet->end_addr)) + !cs_etm__is_svc_instr(etmq, tidq, packet, packet->end_addr)) return true; =20 /* diff --git a/tools/perf/util/cs-etm.h b/tools/perf/util/cs-etm.h index b81099c2b301c25f894cc9a50edfde87aceff49d..4d03f2a680b58aacd91c9f6c957= fb2d38e7ac2ad 100644 --- a/tools/perf/util/cs-etm.h +++ b/tools/perf/util/cs-etm.h @@ -174,6 +174,7 @@ struct cs_etm_packet { enum cs_etm_sample_type sample_type; enum cs_etm_isa isa; u64 start_addr; + /* For exceptions: preferred return address, or CS_ETM_INVAL_ADDR. */ u64 end_addr; u32 instr_count; u32 last_instr_type; --=20 2.34.1 From nobody Thu Sep 24 13:43:08 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 01E2357C72E; Wed, 23 Sep 2026 15:22:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790176944; cv=none; b=BNMS8Lprx6RoZu3H8lHSjtQ2YJsnqDLQwCu8J4Age3rH7/7eIuA1ouqv0YqRc6r0G84Dr3A6CRXDt0oHUCEFOnbXffBfPi5fV3G7iKND/Obg1BZl6TyplzU4L87j7hpam+RUkX4Vml6XFpSA0G2EbYhcKOtUQiPuaTl6OWexj2Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790176944; c=relaxed/simple; bh=GJmCbEJOW+JcbeKN6pUS0ubgm4N3ESLhcQNQ0oR73x0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=efG6dCNNCb0tCSHeH8aLAH6CXbHPGqIGYjLe4wttRQY6F2+DN+GIO9eEHLCzO3chm8h1lT0+3lLihp8fHWrKDCjQdf1EoFGw/0Lei6lN1HCYuB3oKVCfkFREaibzidQVP43oPO5MtSfHqsH9593bygL9GSPylYtpV4P/rlpCDlM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=UcYEkkRa; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="UcYEkkRa" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id D54561D70; Wed, 23 Sep 2026 08:22:17 -0700 (PDT) Received: from e132581.arm.com (unknown [10.2.196.114]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 2605A3F86F; Wed, 23 Sep 2026 08:22:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1790176941; bh=GJmCbEJOW+JcbeKN6pUS0ubgm4N3ESLhcQNQ0oR73x0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=UcYEkkRaFt2uwzw+Diy0c7/Cr2TF44L4vMLcFIB+xkedIjh/Mj8P2WPJCWUcfjXIG mWWc5+hIXvnRaOn8cOqikPrbuIwvqN16DvxdNctw2tzNCzwsZSsq8WaSFRSNHRch+5 to45PE8dCzqF0rlWaIsZ2z6LtL8Mmh15X7L8VNgM= From: Leo Yan Date: Wed, 23 Sep 2026 16:21:50 +0100 Subject: [PATCH v2 10/14] perf cs-etm: Synthesize exception entries separately from branches Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260923-perf_cs_etm_fix_non_taken-v2-10-6ab8c07a5455@arm.com> References: <20260923-perf_cs_etm_fix_non_taken-v2-0-6ab8c07a5455@arm.com> In-Reply-To: <20260923-perf_cs_etm_fix_non_taken-v2-0-6ab8c07a5455@arm.com> To: Arnaldo Carvalho de Melo , Namhyung Kim , Jiri Olsa , Ian Rogers , Adrian Hunter , James Clark , Mike Leach , Suzuki K Poulose , Suyash Mahar , Amir Ayupov Cc: Arnaldo Carvalho de Melo , coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Leo Yan X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1790176913; l=13665; i=leo.yan@arm.com; s=20250604; h=from:subject:message-id; bh=GJmCbEJOW+JcbeKN6pUS0ubgm4N3ESLhcQNQ0oR73x0=; b=afaGFn6Lhpa6LnMlWXrgh4n18hKYp8oF/D1MqRCdj9Spz417Lx28Qt28/6uC+h/ipYgP/xKBU TC5d7Kj0/UoBX1PL0OE/59XQGlFzLwXCxIRRzOUXTumMhZ90ie+/kC5 X-Developer-Key: i=leo.yan@arm.com; a=ed25519; pk=k4BaDbvkCXzBFA7Nw184KHGP5thju8lKqJYIrOWxDhI= Exception entry is currently represented by replacing the preceding range's flags and forcing its last_instr_taken_branch bit. This gives an interrupt the source address of the last executed instruction. When that instruction is a taken branch, its edge and original flags are lost. For example, consider an untaken B.LS followed by an IRQ: 4000f4: eb02003f cmp x1, x2 4000f8: 54000109 b.ls 400118 4000fc: d282f2c2 mov x2, #0x1796 If B.LS completes untaken and the IRQ is taken before MOV completes, the preferred exception return address is 4000fc. With kernel tracing disabled, perf script previously attributed the IRQ to the preceding range: tr end hw int 4000f8 =3D> 0 b.ls #0x400118 tr strt jmp 0 =3D> 4000fc When an IRQ element provides that return address, use it as the source of the synthesized exception sample: tr end hw int 4000fc =3D> 0 movz x2, #0x1796 tr strt jmp 0 =3D> 4000fc The source now identifies the architectural resume PC, rather than the last completed instruction. The IRQ signal could have arrived while B.LS was executing. The traced preferred exception return address of 4000fc confirms that B.LS had retired architecturally before the IRQ was taken. OpenCSD provides an exception's preferred return address in en_addr when excep_ret_addr is set. It does not define or initialize st_addr for an exception element. Derive A32 and A64 exception source PCs from the preferred return address. Exception calls (SVC/SMC/HVC) use the preceding four-byte instruction; interrupts, faults and traps use the return address with last_instr_size set to zero. Keep T32 exception samples on the existing fallback path, so determining the call size requires an instruction read. Retain end_addr for the frontend's SVC check. RESET and missing return addresses also use the fallback because their source PC is unknown. Resolve the preceding branch with its original flags without adding instructions. Then retain the exception in prev_packet until the next range, exception or discontinuity resolves its destination. This preserves both edges when an exception follows a taken branch and also handles consecutive exceptions. Supply the preferred return address in sample.ret_addr so later instruction fetching cannot change the return PC used by call/return export. Generate final instruction samples only from nonempty instruction ranges. CS_ETM_EXCEPTION_RET needs no further handling in the packet processing loop because ERET is already part of the preceding instruction range. cs_etm__set_sample_flags() now sets both that range's return flags and last_instr_taken_branch. Assisted-by: Codex:gpt-6 Signed-off-by: Leo Yan --- tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 31 ++++++- tools/perf/util/cs-etm.c | 102 ++++++++++++++------= ---- tools/perf/util/cs-etm.h | 1 + 3 files changed, 91 insertions(+), 43 deletions(-) diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/u= til/cs-etm-decoder/cs-etm-decoder.c index 48e8c355a3e495cc30dcb4056c04a034d10ce860..83a851bdd87bf0aa3fbc5653054= 51a68f42c69e6 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c @@ -514,6 +514,7 @@ cs_etm_decoder__buffer_exception(struct cs_etm_queue *e= tmq, { int ret =3D 0; struct cs_etm_packet *packet; + u8 last_instr_size =3D 0; =20 ret =3D cs_etm_decoder__buffer_packet(etmq, queue, elem, trace_chan_id, CS_ETM_EXCEPTION); @@ -524,8 +525,34 @@ cs_etm_decoder__buffer_exception(struct cs_etm_queue *= etmq, packet->exception_number =3D elem->exception_number; if (elem->context.el_valid) packet->el =3D elem->context.exception_level; - if (elem->excep_ret_addr) - packet->end_addr =3D elem->en_addr; + + /* RESET has no defined preferred return address. */ + if (!elem->excep_ret_addr || + packet->exception_number =3D=3D CS_ETMV4_EXC_RESET) + return ret; + + packet->end_addr =3D elem->en_addr; + + /* + * T32 calls can be two or four bytes, requiring an instruction read + * before end_addr to determine their size. Keep end_addr for the + * frontend's SVC check and leave start_addr unknown for its fallback. + */ + if (packet->isa !=3D CS_ETM_ISA_A32 && packet->isa !=3D CS_ETM_ISA_A64) + return ret; + + /* + * For A32 and A64, exception calls execute a four-byte SVC, HVC or + * SMC and save the following PC. Other exceptions use the interrupted + * or faulting PC, including traps on those instructions. + * + * With a shared branch target, no instruction has completed + * at the target, so last_instr_size remains zero. + */ + if (elem->exception_number =3D=3D CS_ETMV4_EXC_CALL) + last_instr_size =3D 4; + packet->start_addr =3D packet->end_addr - last_instr_size; + packet->last_instr_size =3D last_instr_size; =20 return ret; } diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index a40b3b2fe2e6318154111d9b7ebd05bee53934f1..6641e257e5f18f30a185a88db72= 0c1404cf2bd36 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -101,10 +101,8 @@ struct cs_etm_traceid_queue { ocsd_ex_level decode_el; =20 /* - * The frontend accesses the EL from '[prev_]packet' because it needs - * previous EL for branch and current EL for instruction samples. It's - * not possible to change thread in a single branch sample so no need to - * store or access the thread through the packet. + * Samples use the EL saved in their source packet. A branch sample + * cannot change thread, so the thread is kept in the frontend context. */ struct thread *frontend_thread; }; @@ -1364,11 +1362,10 @@ static inline int cs_etm__instr_size(struct cs_etm_= queue *etmq, static inline u64 cs_etm__first_executed_instr(struct cs_etm_packet *packe= t) { /* - * Return 0 for packets that have no addresses so that CS_ETM_INVAL_ADDR = doesn't - * appear in samples. + * Return 0 for discontinuities so that CS_ETM_INVAL_ADDR doesn't appear + * in samples. */ - if (packet->sample_type =3D=3D CS_ETM_DISCONTINUITY || - packet->sample_type =3D=3D CS_ETM_EXCEPTION) + if (packet->sample_type =3D=3D CS_ETM_DISCONTINUITY) return 0; =20 return packet->start_addr; @@ -1537,6 +1534,8 @@ static void cs_etm__copy_insn(struct cs_etm_queue *et= mq, } =20 sample->insn_len =3D cs_etm__instr_size(etmq, tidq, packet, sample->ip); + if (packet->sample_type =3D=3D CS_ETM_EXCEPTION && !sample->insn_len) + return; =20 cs_etm__frontend_mem_access(etmq, tidq, packet, sample->ip, sample->insn_len, (void *)sample->insn); @@ -1564,8 +1563,11 @@ static inline u64 cs_etm__resolve_sample_time(struct= cs_etm_queue *etmq, return etm->latest_kernel_timestamp; } =20 -static bool cs_etm__packet_has_taken_branch(struct cs_etm_packet *packet) +static bool cs_etm__packet_has_branch(struct cs_etm_packet *packet) { + if (packet->sample_type =3D=3D CS_ETM_EXCEPTION) + return true; + if (packet->sample_type =3D=3D CS_ETM_RANGE && packet->last_instr_taken_branch) return true; @@ -1583,7 +1585,7 @@ static void cs_etm__add_stack_event(struct cs_etm_que= ue *etmq, if (!etm->synth_opts.branches && !etm->synth_opts.instructions) return; =20 - if (!cs_etm__packet_has_taken_branch(tidq->prev_packet)) + if (!cs_etm__packet_has_branch(tidq->prev_packet)) return; =20 if (etmq->etm->use_thread_stack) { @@ -1695,7 +1697,8 @@ static int cs_etm__synth_last_instruction_sample(stru= ct cs_etm_queue *etmq, !etmq->etm->synth_opts.instructions) return 0; =20 - if (packet->sample_type !=3D CS_ETM_RANGE) + /* Only nonempty ranges provide a final instruction to sample. */ + if (packet->sample_type !=3D CS_ETM_RANGE || !packet->instr_count) return 0; =20 ret =3D cs_etm__synth_instruction_sample(etmq, tidq, packet, @@ -1729,7 +1732,7 @@ static int cs_etm__synth_branch_sample(struct cs_etm_= queue *etmq, if (!etm->synth_opts.branches) return 0; =20 - if (!cs_etm__packet_has_taken_branch(tidq->prev_packet) && + if (!cs_etm__packet_has_branch(tidq->prev_packet) && !(tidq->prev_packet->flags & (PERF_IP_FLAG_TRACE_BEGIN | PERF_IP_FLAG_TRACE_END))) return 0; @@ -1760,6 +1763,9 @@ static int cs_etm__synth_branch_sample(struct cs_etm_= queue *etmq, sample.flags =3D tidq->prev_packet->flags; sample.cpumode =3D event->sample.header.misc; =20 + if (tidq->prev_packet->sample_type =3D=3D CS_ETM_EXCEPTION) + sample.ret_addr =3D tidq->prev_packet->end_addr; + cs_etm__copy_insn(etmq, tidq, tidq->prev_packet, &sample); =20 /* @@ -2010,21 +2016,23 @@ static int cs_etm__context(struct cs_etm_queue *etm= q, return ret; } =20 -static int cs_etm__exception(struct cs_etm_traceid_queue *tidq) +static int cs_etm__exception(struct cs_etm_queue *etmq, + struct cs_etm_traceid_queue *tidq) { + struct cs_etm_packet *packet =3D tidq->packet; + /* - * When the exception packet is inserted, whether the last instruction - * in previous range packet is taken branch or not, we need to force - * to set 'prev_packet->last_instr_taken_branch' to true. This ensures - * to generate branch sample for the instruction range before the - * exception is trapped to kernel or before the exception returning. - * - * The exception packet does not describe an instruction range, so don't - * swap PACKET with PREV_PACKET. This keeps PREV_PACKET to be useful - * for generating instruction and branch samples. + * Resolve the preceding branch without adding instructions, then keep + * this exception as prev_packet until its destination is known. */ - if (tidq->prev_packet->sample_type =3D=3D CS_ETM_RANGE) + if (packet->start_addr !=3D CS_ETM_INVAL_ADDR) + return cs_etm__sample(etmq, tidq); + + /* Fall back to attributing the exception to the preceding range. */ + if (tidq->prev_packet->sample_type =3D=3D CS_ETM_RANGE) { + tidq->prev_packet->flags =3D packet->flags; tidq->prev_packet->last_instr_taken_branch =3D true; + } =20 return 0; } @@ -2418,7 +2426,8 @@ static int cs_etm__set_sample_flags(struct cs_etm_que= ue *etmq, * instruction packet, set flag PERF_IP_FLAG_TRACE_END * for previous packet. */ - if (prev_packet->sample_type =3D=3D CS_ETM_RANGE) + if (prev_packet->sample_type =3D=3D CS_ETM_RANGE || + prev_packet->sample_type =3D=3D CS_ETM_EXCEPTION) prev_packet->flags |=3D PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TRACE_END; break; @@ -2450,15 +2459,23 @@ static int cs_etm__set_sample_flags(struct cs_etm_q= ueue *etmq, PERF_IP_FLAG_CALL | PERF_IP_FLAG_INTERRUPT; =20 - /* - * When the exception packet is inserted, since exception - * packet is not used standalone for generating samples - * and it's affiliation to the previous instruction range - * packet; so set previous range packet flags to tell perf - * it is an exception taken branch. - */ - if (prev_packet->sample_type =3D=3D CS_ETM_RANGE) - prev_packet->flags =3D packet->flags; + if (packet->start_addr =3D=3D CS_ETM_INVAL_ADDR) + break; + + /* Resolve the preceding trace start or exception return. */ + if (prev_packet->sample_type =3D=3D CS_ETM_DISCONTINUITY) + prev_packet->flags |=3D PERF_IP_FLAG_BRANCH | + PERF_IP_FLAG_TRACE_BEGIN; + + if (prev_packet->flags =3D=3D (PERF_IP_FLAG_BRANCH | + PERF_IP_FLAG_RETURN | + PERF_IP_FLAG_INTERRUPT) && + cs_etm__is_svc_instr(etmq, tidq, packet, + packet->start_addr)) { + prev_packet->flags =3D PERF_IP_FLAG_BRANCH | + PERF_IP_FLAG_RETURN | + PERF_IP_FLAG_SYSCALLRET; + } break; case CS_ETM_EXCEPTION_RET: /* @@ -2486,10 +2503,12 @@ static int cs_etm__set_sample_flags(struct cs_etm_q= ueue *etmq, * system call instruction and then calibrate the sample flag * as needed. */ - if (prev_packet->sample_type =3D=3D CS_ETM_RANGE) + if (prev_packet->sample_type =3D=3D CS_ETM_RANGE) { prev_packet->flags =3D PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_RETURN | PERF_IP_FLAG_INTERRUPT; + prev_packet->last_instr_taken_branch =3D true; + } break; case CS_ETM_CONTEXT: case CS_ETM_EMPTY: @@ -2565,7 +2584,9 @@ static int cs_etm__process_traceid_queue(struct cs_et= m_queue *etmq, * range, generate instruction sequence * events. */ - cs_etm__sample(etmq, tidq); + ret =3D cs_etm__sample(etmq, tidq); + if (ret) + goto out; break; case CS_ETM_CONTEXT: /* @@ -2579,13 +2600,12 @@ static int cs_etm__process_traceid_queue(struct cs_= etm_queue *etmq, goto out; break; case CS_ETM_EXCEPTION: + ret =3D cs_etm__exception(etmq, tidq); + if (ret) + goto out; + break; case CS_ETM_EXCEPTION_RET: - /* - * If the exception packet is coming, - * make sure the previous instruction - * range packet to be handled properly. - */ - cs_etm__exception(tidq); + /* The return annotates the preceding instruction range. */ break; case CS_ETM_DISCONTINUITY: /* diff --git a/tools/perf/util/cs-etm.h b/tools/perf/util/cs-etm.h index 4d03f2a680b58aacd91c9f6c957fb2d38e7ac2ad..27201fea5af2764adf85a766925= c393ad93d40f8 100644 --- a/tools/perf/util/cs-etm.h +++ b/tools/perf/util/cs-etm.h @@ -173,6 +173,7 @@ struct cs_etm_queue; struct cs_etm_packet { enum cs_etm_sample_type sample_type; enum cs_etm_isa isa; + /* For exceptions: source PC, or CS_ETM_INVAL_ADDR. */ u64 start_addr; /* For exceptions: preferred return address, or CS_ETM_INVAL_ADDR. */ u64 end_addr; --=20 2.34.1 From nobody Thu Sep 24 13:43:08 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 82BF257EDB0; Wed, 23 Sep 2026 15:22:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790176946; cv=none; b=dJghhqRbUXV4cpxQf6Q0tdVcw7K5IwYyn8f20qBZygLArHBRwWEYgcH5dZ/uHmv5RZbJEbuTP4cCPPXinw1z41EfBJeLfGf+ZJIjnObNg9OTHJzs70Z9XxORhn6RnvFsg+/I6cQVqKapnZ38lOcEoYMEeZy4RyRbzfXiw7geox4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790176946; c=relaxed/simple; bh=eDjAKkJPh+OsL519J9LSkyD3AxjznW0hz63Al8+ihwI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=uqSHvsLnYptvTjdcDQ/R8HttjxyjlUnUoR2ujmqsBXfzvipN9VEOwNRQyU12wEL19wzR4EQHC5rH3oXvyZTnrJgKJZoFx38b9svSc0K7BoSYFgpJ9PLrC0pE+fOtRieMQet8qBpkjMdy5UFGmQulPPMVkpyCnOx+m8H7eLx1eIA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=PPbMuET/; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="PPbMuET/" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 7195B1DB5; Wed, 23 Sep 2026 08:22:20 -0700 (PDT) Received: from e132581.arm.com (unknown [10.2.196.114]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id B15963F86F; Wed, 23 Sep 2026 08:22:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1790176944; bh=eDjAKkJPh+OsL519J9LSkyD3AxjznW0hz63Al8+ihwI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=PPbMuET/X6m0Id59OT2grAI11IKaYNy9tq8C/S8i4IJSS7OxFyTlmZNrAKuqIb7Mo wQUKkCyleBqgAuTWCh83+Tzp8OiZrQ4kRx3y42UHOshXjOXePkOLV02sDOwEKPm9HW ruVpjluqoUWy3pezW+3oTWZRCSVtFHXKy5+mTBaI= From: Leo Yan Date: Wed, 23 Sep 2026 16:21:51 +0100 Subject: [PATCH v2 11/14] perf tests: Check CoreSight IRQ entry and exit Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260923-perf_cs_etm_fix_non_taken-v2-11-6ab8c07a5455@arm.com> References: <20260923-perf_cs_etm_fix_non_taken-v2-0-6ab8c07a5455@arm.com> In-Reply-To: <20260923-perf_cs_etm_fix_non_taken-v2-0-6ab8c07a5455@arm.com> To: Arnaldo Carvalho de Melo , Namhyung Kim , Jiri Olsa , Ian Rogers , Adrian Hunter , James Clark , Mike Leach , Suzuki K Poulose , Suyash Mahar , Amir Ayupov Cc: Arnaldo Carvalho de Melo , coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Leo Yan X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1790176913; l=10569; i=leo.yan@arm.com; s=20250604; h=from:subject:message-id; bh=eDjAKkJPh+OsL519J9LSkyD3AxjznW0hz63Al8+ihwI=; b=aqJ3khVSfORRxYef7Fnh7HBPJ16bGbVymgEpOacn71nfqQy+hHQyw3Js6dG9as5tpBbvlczns jhl9sZAXkG7AK1jEMKLSiTv2jCMP5lqSJ5fVkwSo5n1STPxFim9rV4M X-Developer-Key: i=leo.yan@arm.com; a=ed25519; pk=k4BaDbvkCXzBFA7Nw184KHGP5thju8lKqJYIrOWxDhI= Add an AArch64 branch_not_taken_loop workload and a CoreSight shell test checking IRQ entry and exit PCs. Use cpu-clock generates timer interrupts. Retry at different timer frequencies and skip if no complete pair is captured. For example, an expected hw int/iret pair is: hw int 5cc928 =3D> ffff800080010c80 insn: 63 04 00 f1 ... iret ffff800080012284 =3D> 5cc928 insn: e0 03 9f d6 The entry PC is the architectural resume address, here SUBS X3, X3, #1 at 0x5cc928. After the IRQ is handled, ERET returns to the same PC to continue execution. Assisted-by: Codex:gpt-6 Signed-off-by: Leo Yan --- tools/perf/tests/builtin-test.c | 1 + tools/perf/tests/shell/coresight/irq_entry_exit.sh | 37 +++++ tools/perf/tests/shell/lib/coresight_exception.sh | 165 +++++++++++++++++= ++++ tools/perf/tests/tests.h | 1 + tools/perf/tests/workloads/Build | 2 + tools/perf/tests/workloads/branch_not_taken_loop.c | 33 +++++ 6 files changed, 239 insertions(+) diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-tes= t.c index 6259ed805c5f75799d52ac742b77cf278f98bd9d..8eab221f115e75a3ef90be975d4= ed0558ceb2b16 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -171,6 +171,7 @@ static struct test_workload *workloads[] =3D { &workload__datasym, &workload__landlock, &workload__traploop, + &workload__branch_not_taken_loop, &workload__inlineloop, &workload__jitdump, &workload__context_switch_loop, diff --git a/tools/perf/tests/shell/coresight/irq_entry_exit.sh b/tools/per= f/tests/shell/coresight/irq_entry_exit.sh new file mode 100755 index 0000000000000000000000000000000000000000..f164daa222b0550ceb106aa6a12= 15740a1432017 --- /dev/null +++ b/tools/perf/tests/shell/coresight/irq_entry_exit.sh @@ -0,0 +1,37 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# CoreSight IRQ entry and exit (exclusive) + +# shellcheck source=3D../lib/coresight_exception.sh +. "$(dirname "$0")/../lib/coresight_exception.sh" + +test_irq_entry_exit() +{ + # IRQs must return to the interrupted PC. Retry at different timer + # frequencies if trace gaps leave no complete entry/exit pair. + for freq in 1000 4000 10000; do + echo "Recording timer IRQs at $freq Hz" + if ! record_trace_with_cpu_clock "$freq" branch_not_taken_loop; then + cat "$tmpdir/record.log" + echo "Failed to record the IRQ workload" + return 1 + fi + + decode_trace || return 1 + + check_exception_pairs "hw int" "iret" 0 + result=3D$? + case $result in + 0) return 0 ;; + 1) cat "$tmpdir/script.log"; return 1 ;; + 2) echo "No complete IRQ pair in this recording" ;; + *) return "$result" ;; + esac + done + + echo "[Skip] No complete IRQ pair after three recordings" + return 2 +} + +setup_exception_test || exit $? +test_irq_entry_exit diff --git a/tools/perf/tests/shell/lib/coresight_exception.sh b/tools/perf= /tests/shell/lib/coresight_exception.sh new file mode 100644 index 0000000000000000000000000000000000000000..f0133c258625147405ba4641ff7= e442437fc66b8 --- /dev/null +++ b/tools/perf/tests/shell/lib/coresight_exception.sh @@ -0,0 +1,165 @@ +# SPDX-License-Identifier: GPL-2.0 +# Common helpers for CoreSight exception entry and return tests. + +cleanup() +{ + case $? in + 0|2) rm -rf "$tmpdir" ;; + *) echo "Test files retained in $tmpdir" ;; + esac +} + +record_trace_with_cpu_clock() +{ + local clock_opts=3D() + + record_freq=3D$1 + shift + + # A zero frequency omits the cpu-clock event. + if [ "$record_freq" -gt 0 ]; then + # Generate timer IRQs without delivering a signal to the workload. + clock_opts=3D(-e cpu-clock:u -F "$record_freq") + fi + + # FIFO control bounds the trace to the workload. + # --kcore supplies the running kernel's instructions for decoding. + taskset -c "$cpu" perf record -B --no-bpf-event --per-thread --kcore \ + -e cs_etm/timestamp=3D0/uk "${clock_opts[@]}" \ + -m,4M -D -1 --control fifo:"$tmpdir/ctl","$tmpdir/ack" \ + -o "$tmpdir/data" -- \ + perf test --record-ctl fifo:"$tmpdir/ctl","$tmpdir/ack" -w "$@" \ + > "$tmpdir/record.log" 2>&1 +} + +record_trace() +{ + record_trace_with_cpu_clock 0 "$@" +} + +decode_trace() +{ + local sw_fields=3D() + + # perf script rejects -F sw: when no software event was recorded. + if [ "$record_freq" -gt 0 ]; then + sw_fields=3D(-F sw:) + fi + + if ! perf script -i "$tmpdir/data" --itrace=3Db \ + -F hw:ip,addr,flags,insn "${sw_fields[@]}" \ + > "$tmpdir/script" 2> "$tmpdir/script.log"; then + cat "$tmpdir/script.log" + echo "Failed to decode the exception trace" + return 1 + fi +} + +# Arguments: entry pattern, exit pattern, expected return PC - entry PC. +# Return 2 if no complete pair survives the trace gaps. +check_exception_pairs() +{ + local difference=3D$3 entry_pc resume_pc pairs=3D0 + + awk -v entry_pattern=3D"$1" -v exit_pattern=3D"$2" ' + function address(pc) { + sub(/^0[xX]/, "", pc) + sub(/^0+/, "", pc) + return "0x" (pc =3D=3D "" ? "0" : tolower(pc)) + } + BEGIN { + entry_pattern =3D "^[[:space:]]*(" entry_pattern ")([[:space:]]|$)" + exit_pattern =3D "^[[:space:]]*(" exit_pattern ")([[:space:]]|$)" + } + NF { + # A trace boundary invalidates all pending entries, including nested one= s. + if ($1 =3D=3D "tr" && ($2 =3D=3D "strt" || $2 =3D=3D "end")) { + depth =3D 0 + next + } + + is_entry =3D ($1 =3D=3D "hw" && $2 =3D=3D "int") || $1 =3D=3D "int" || $= 1 =3D=3D "syscall" + is_exit =3D $1 =3D=3D "iret" || $1 =3D=3D "sysret" + if (!is_entry && !is_exit) + next + + # Branch fields are: flags source =3D> destination [insn: bytes]. + arrow =3D 0 + for (i =3D 1; i <=3D NF; i++) { + if ($i =3D=3D "=3D>") { + arrow =3D i + break + } + } + if (arrow < 3 || arrow =3D=3D NF) { + print "FAIL: Unexpected perf script output: " $0 > "/dev/stderr" + errors++ + depth =3D 0 + next + } + + # Track every exception so an unrelated nested IRET cannot close + # a selected outer entry. Match the requested flags at each depth. + if (is_entry) { + entry_pc[++depth] =3D address($(arrow - 1)) + selected[depth] =3D $0 ~ entry_pattern + next + } + if (!depth) + next + + if (selected[depth] && $0 ~ exit_pattern) + print entry_pc[depth], address($(arrow + 1)) + depth-- + } + END { + if (errors) + exit 1 + }' "$tmpdir/script" > "$tmpdir/exception_pairs" || return 1 + + # Bash uses integer arithmetic, preserving all bits of 64-bit PCs. + while read -r entry_pc resume_pc; do + if [ "$((resume_pc - entry_pc))" -ne "$difference" ]; then + printf "FAIL: Entry %s returns to %s, expected PC difference %d\n" \ + "$entry_pc" "$resume_pc" "$difference" + return 1 + fi + pairs=3D$((pairs + 1)) + done < "$tmpdir/exception_pairs" + + if [ "$pairs" -eq 0 ]; then + echo "No complete exception entry/exit pair" + return 2 + fi + printf "Checked %d exception pairs with PC difference %d\n" "$pairs" "$di= fference" +} + +setup_exception_test() +{ + [ "$(uname -m)" =3D aarch64 ] || return 2 + perf check feature -q libopencsd || return 2 + [ -d /sys/bus/event_source/devices/cs_etm ] || return 2 + + export LC_ALL=3DC + command -v taskset >/dev/null 2>&1 || return 2 + + tmpdir=3D$(mktemp -d /tmp/perf-cs-etm-exception.XXXXXX) || return 1 + trap cleanup EXIT + trap 'exit 1' HUP INT TERM + mkfifo "$tmpdir/ctl" "$tmpdir/ack" || return 1 + + # Keep each exception entry and return in the same trace queue. + cpu=3D$(awk '/Cpus_allowed_list:/ { + split($2, cpus, /[-,]/) + print cpus[1] + }' /proc/self/status) + + # Check permissions, FIFO control and the trace sink before testing. + if ! record_trace callchain; then + cat "$tmpdir/record.log" + echo "[Skip] Cannot record user/kernel CoreSight trace with --kcore" + return 2 + fi + + return 0 +} diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index b2520a564417b61718f1dcb23da1f8cc0f601906..0a61129b31ab6997616f7d04d29= af73961f4f861 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -246,6 +246,7 @@ DECLARE_WORKLOAD(brstack); DECLARE_WORKLOAD(datasym); DECLARE_WORKLOAD(landlock); DECLARE_WORKLOAD(traploop); +DECLARE_WORKLOAD(branch_not_taken_loop); DECLARE_WORKLOAD(inlineloop); DECLARE_WORKLOAD(jitdump); DECLARE_WORKLOAD(context_switch_loop); diff --git a/tools/perf/tests/workloads/Build b/tools/perf/tests/workloads/= Build index 048e371eb63e316453b6b46ebd0a02794c3d25d7..ca22a82073ed08de5d4a27d0a3b= 33ddcba2e3f3e 100644 --- a/tools/perf/tests/workloads/Build +++ b/tools/perf/tests/workloads/Build @@ -9,6 +9,7 @@ perf-test-y +=3D brstack.o perf-test-y +=3D datasym.o perf-test-y +=3D landlock.o perf-test-y +=3D traploop.o +perf-test-y +=3D branch_not_taken_loop.o perf-test-y +=3D inlineloop.o perf-test-y +=3D jitdump.o perf-test-y +=3D context_switch_loop.o @@ -25,6 +26,7 @@ CFLAGS_leafloop.o =3D -g -O0 -fno-inline -fno-omi= t-frame-pointer -U_FORTIF CFLAGS_brstack.o =3D -g -O0 -fno-inline -U_FORTIFY_SOURCE CFLAGS_datasym.o =3D -g -O0 -fno-inline -U_FORTIFY_SOURCE CFLAGS_traploop.o =3D -g -O0 -fno-inline -U_FORTIFY_SOURCE +CFLAGS_branch_not_taken_loop.o =3D -g -O0 -fno-inline -U_FORTIFY_SOURCE CFLAGS_inlineloop.o =3D -g -O2 CFLAGS_deterministic.o =3D -g -O0 -fno-inline -U_FORTIFY_SOURCE CFLAGS_named_threads.o =3D -g -O0 -fno-inline -U_FORTIFY_SOURCE diff --git a/tools/perf/tests/workloads/branch_not_taken_loop.c b/tools/per= f/tests/workloads/branch_not_taken_loop.c new file mode 100644 index 0000000000000000000000000000000000000000..6376b1c476e2f4814a94c91a532= 1ae919a818826 --- /dev/null +++ b/tools/perf/tests/workloads/branch_not_taken_loop.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include "../tests.h" + +#ifdef __aarch64__ +static void branch_not_taken(void) +{ + /* Keep x1 > x2 so B.LS is never taken. */ + asm volatile( + "mov x1, #2\n" + "mov x2, #1\n" + "movz x3, #0xffff\n" + "movk x3, #0x0080, lsl #16\n" + "1: cmp x1, x2\n" + ".Ltest_branch:\n" + "b.ls 2f\n" + ".Lfallthrough:\n" + "subs x3, x3, #1\n" + "b.ne 1b\n" + "2:\n" + : : : "x1", "x2", "x3", "cc"); +} +#else +static void branch_not_taken(void) { } +#endif + +static int branch_not_taken_loop(int argc __maybe_unused, const char **arg= v __maybe_unused) +{ + branch_not_taken(); + return 0; +} + +DEFINE_WORKLOAD(branch_not_taken_loop); --=20 2.34.1 From nobody Thu Sep 24 13:43:08 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id F03D157EDB2; Wed, 23 Sep 2026 15:22:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790176948; cv=none; b=fYjlT5+hmP5Lr3xpEzoIUK7tW4sCLEy88YK5cZNz7A70GVVGvAi3W7cPtqKKeFDx242V8j3BZVPwJ+q/Ycd8Prqt7q3M0ElGvl/A1hto4MrmJQKMl+dRZK/fyKn45tWDHHMpa6fT8/PK+D339RfGC2FOnAMrl7E1suChwZZKGjA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790176948; c=relaxed/simple; bh=9E/qd6jg0Rof28rV1XuWJc0vRTRpsBID5XI48+8mKF0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=txCRuAch4lhwO+9zXj/O5/kqlqSE1CrFkvWiPQ+7u4Amd8GXlfLXrrhe2PMotlHPQ/NlyvJZl2/4tWrh5+OE/tChKetKwXu/qZTdhdrO9p21D6aebUzmTAI0K/JwGIjMtcEjDtZjqhCqnqjVtfgLlQCLMpV+fYwVrBu5Kh+BRHU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=r1MxpRSt; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="r1MxpRSt" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 0DC811E2F; Wed, 23 Sep 2026 08:22:23 -0700 (PDT) Received: from e132581.arm.com (unknown [10.2.196.114]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 4EE3C3F86F; Wed, 23 Sep 2026 08:22:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1790176946; bh=9E/qd6jg0Rof28rV1XuWJc0vRTRpsBID5XI48+8mKF0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=r1MxpRStJNSPHcgVHysUljDmHSLOivvPbjyzGUsbmeaeI8+jCcZP5RQUUkxW9jW+b mi1ykmFg0y1pysnKpnWbRJWXm78LVppZS6gj0dLfgt/5BwUrHmeQLkUHUGRfSl4IcE 84O8igkU6cMBsHMcHEUDLgx+DnaBoMu7O9kBqMbo= From: Leo Yan Date: Wed, 23 Sep 2026 16:21:52 +0100 Subject: [PATCH v2 12/14] perf tests: Check CoreSight syscall entry and exit Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260923-perf_cs_etm_fix_non_taken-v2-12-6ab8c07a5455@arm.com> References: <20260923-perf_cs_etm_fix_non_taken-v2-0-6ab8c07a5455@arm.com> In-Reply-To: <20260923-perf_cs_etm_fix_non_taken-v2-0-6ab8c07a5455@arm.com> To: Arnaldo Carvalho de Melo , Namhyung Kim , Jiri Olsa , Ian Rogers , Adrian Hunter , James Clark , Mike Leach , Suzuki K Poulose , Suyash Mahar , Amir Ayupov Cc: Arnaldo Carvalho de Melo , coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Leo Yan X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1790176913; l=1624; i=leo.yan@arm.com; s=20250604; h=from:subject:message-id; bh=9E/qd6jg0Rof28rV1XuWJc0vRTRpsBID5XI48+8mKF0=; b=4CWv8CvPVQyYp3GMJIhy/EI7F8lzkLhtsiBFi4MK/qtUj+x8lxsWO24q2hVNbk9PyEaLoTK07 lvHbqjzePrLCvhm/lD2KxZzHNtPmwGN6lr6wVdBGx2R4BQvISbQ7NC5 X-Developer-Key: i=leo.yan@arm.com; a=ed25519; pk=k4BaDbvkCXzBFA7Nw184KHGP5thju8lKqJYIrOWxDhI= Record the existing callchain workload, which issues gettid() through SVC. The test requires syscall/sysret pairs to advance the PC by four bytes. For example, an expected syscall/sysret pair is: syscall bb76e4 =3D> ffff800080010c00 insn: 01 00 00 d4 ... sysret ffff800080012284 =3D> bb76e8 insn: e0 03 9f d6 The entry instruction is SVC #0 at 0xbb76e4. On syscall completion, ERET returns to 0xbb76e8, the instruction immediately after SVC. Assisted-by: Codex:gpt-6 Signed-off-by: Leo Yan --- .../tests/shell/coresight/syscall_entry_exit.sh | 21 +++++++++++++++++= ++++ 1 file changed, 21 insertions(+) diff --git a/tools/perf/tests/shell/coresight/syscall_entry_exit.sh b/tools= /perf/tests/shell/coresight/syscall_entry_exit.sh new file mode 100755 index 0000000000000000000000000000000000000000..bf61b1fdf6f15e290295afc7577= 870c6864ddd93 --- /dev/null +++ b/tools/perf/tests/shell/coresight/syscall_entry_exit.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# CoreSight syscall entry and exit (exclusive) + +# shellcheck source=3D../lib/coresight_exception.sh +. "$(dirname "$0")/../lib/coresight_exception.sh" + +test_syscall_entry_exit() +{ + # callchain() invokes gettid() through SVC, which returns to PC + 4. + if ! record_trace callchain; then + cat "$tmpdir/record.log" + echo "Failed to record the callchain workload" + return 1 + fi + decode_trace || return 1 + check_exception_pairs "syscall" "sysret" 4 || return 1 +} + +setup_exception_test || exit $? +test_syscall_entry_exit --=20 2.34.1 From nobody Thu Sep 24 13:43:08 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id A4E7F57F73D; Wed, 23 Sep 2026 15:22:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790176952; cv=none; b=PzCB+UPV2i8GXiYrn/Y4rU/J4yqUTLs6RgEmw7FfQm6rwtFxkvIrwCIJy/SYMI47PVqcVc3+Ry4drKAXsf14tivyFQ9lwQh+w5A1wahOD5J3y7+591h23VIF44RgKHo20TJyqG8SuU8YnVUbnLanutslpIqDHovEpMwVkJIR5FM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790176952; c=relaxed/simple; bh=wAWNock21fh69r9WLtcmCQrLPB75x0/Rq0TuxFYrW1A=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nIY/Q6OtVYPA2pv6+idbusXVhado9zyQgw1rmVPdksnpl2bW5YKYcObnSdGDRm4WptEqIIp3zBFX4hCkuKWu2NZy5teCfF21HiYbcomaFVV6GTOo71n5MawipxNQvT7Mwd25ywZxk/FgY5hDIj4gVzt4ITgYq+q3Da+PO1mNYW0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=Fi7v9wZK; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="Fi7v9wZK" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 96F751E32; Wed, 23 Sep 2026 08:22:25 -0700 (PDT) Received: from e132581.arm.com (unknown [10.2.196.114]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id DAAC53F86F; Wed, 23 Sep 2026 08:22:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1790176949; bh=wAWNock21fh69r9WLtcmCQrLPB75x0/Rq0TuxFYrW1A=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Fi7v9wZKt68Wyn8hugJhkzXQR6KS8/k4HG6wXUtfk+gDP0Jg2FyDay/tMmMHq+WlH aYrStO+HiWYnNYQcbBMsYdVaHtHCZc4UE/9aske0GN497M/C7f5qvgk6pMd4dUcwOl Ew/8NmN89urOYHJP6rPSlyujow81zMmBPHI6PSmQ= From: Leo Yan Date: Wed, 23 Sep 2026 16:21:53 +0100 Subject: [PATCH v2 13/14] perf tests: Check CoreSight abort entry and exit Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260923-perf_cs_etm_fix_non_taken-v2-13-6ab8c07a5455@arm.com> References: <20260923-perf_cs_etm_fix_non_taken-v2-0-6ab8c07a5455@arm.com> In-Reply-To: <20260923-perf_cs_etm_fix_non_taken-v2-0-6ab8c07a5455@arm.com> To: Arnaldo Carvalho de Melo , Namhyung Kim , Jiri Olsa , Ian Rogers , Adrian Hunter , James Clark , Mike Leach , Suzuki K Poulose , Suyash Mahar , Amir Ayupov Cc: Arnaldo Carvalho de Melo , coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Leo Yan X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1790176913; l=5197; i=leo.yan@arm.com; s=20250604; h=from:subject:message-id; bh=wAWNock21fh69r9WLtcmCQrLPB75x0/Rq0TuxFYrW1A=; b=m6woXg7xSqJIji2Grdy2XHeSakZASnTf9mr9BEZQczxOuS+ZaMnlSCyV2a24jYP+mPB+nzra5 j9lydkL0C8rALuOwd07WxkhDhYEzdqyFTfJn8q89j1Gk82OHceQ3M2e X-Developer-Key: i=leo.yan@arm.com; a=ed25519; pk=k4BaDbvkCXzBFA7Nw184KHGP5thju8lKqJYIrOWxDhI= Add page_fault_loop to repeatedly discard an anonymous page with MADV_DONTNEED and read it again. Each demand fault is resolved without signal delivery, so the load must be retried at the same PC. For example, an expected int/iret pair is: int 5ccadc =3D> ffff800080010c00 insn: 00 00 40 39 ... iret ffff800080012284 =3D> 5ccadc insn: e0 03 9f d6 The LDRB W0, [X0] at 0x5ccadc faults before completing. After resolving the page fault, the kernel returns via ERET to the same PC to retry it. Assisted-by: Codex:gpt-6 Signed-off-by: Leo Yan --- tools/perf/tests/builtin-test.c | 1 + .../perf/tests/shell/coresight/abort_entry_exit.sh | 21 ++++++++++++ tools/perf/tests/tests.h | 1 + tools/perf/tests/workloads/Build | 2 ++ tools/perf/tests/workloads/page_fault_loop.c | 37 ++++++++++++++++++= ++++ 5 files changed, 62 insertions(+) diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-tes= t.c index 8eab221f115e75a3ef90be975d4ed0558ceb2b16..1af8dfd45d1a2ff5c3206234cd7= 5fb173e122d88 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -172,6 +172,7 @@ static struct test_workload *workloads[] =3D { &workload__landlock, &workload__traploop, &workload__branch_not_taken_loop, + &workload__page_fault_loop, &workload__inlineloop, &workload__jitdump, &workload__context_switch_loop, diff --git a/tools/perf/tests/shell/coresight/abort_entry_exit.sh b/tools/p= erf/tests/shell/coresight/abort_entry_exit.sh new file mode 100755 index 0000000000000000000000000000000000000000..483cf39b3966e89591d4e06d03a= 3fc6709fc3dc9 --- /dev/null +++ b/tools/perf/tests/shell/coresight/abort_entry_exit.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# CoreSight abort entry and exit (exclusive) + +# shellcheck source=3D../lib/coresight_exception.sh +. "$(dirname "$0")/../lib/coresight_exception.sh" + +test_abort_entry_exit() +{ + # A demand page fault retries the load at the same PC after resolution. + if ! record_trace page_fault_loop; then + cat "$tmpdir/record.log" + echo "Failed to record the page fault workload" + return 1 + fi + decode_trace || return 1 + check_exception_pairs "int" "iret" 0 || return 1 +} + +setup_exception_test || exit $? +test_abort_entry_exit diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 0a61129b31ab6997616f7d04d29af73961f4f861..0fc02c5b060133ef27b80de5c86= 8d798d65a7c53 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -247,6 +247,7 @@ DECLARE_WORKLOAD(datasym); DECLARE_WORKLOAD(landlock); DECLARE_WORKLOAD(traploop); DECLARE_WORKLOAD(branch_not_taken_loop); +DECLARE_WORKLOAD(page_fault_loop); DECLARE_WORKLOAD(inlineloop); DECLARE_WORKLOAD(jitdump); DECLARE_WORKLOAD(context_switch_loop); diff --git a/tools/perf/tests/workloads/Build b/tools/perf/tests/workloads/= Build index ca22a82073ed08de5d4a27d0a3b33ddcba2e3f3e..e18fdaa6fd1927ed406e703a7ec= bcc19a111caf3 100644 --- a/tools/perf/tests/workloads/Build +++ b/tools/perf/tests/workloads/Build @@ -10,6 +10,7 @@ perf-test-y +=3D datasym.o perf-test-y +=3D landlock.o perf-test-y +=3D traploop.o perf-test-y +=3D branch_not_taken_loop.o +perf-test-y +=3D page_fault_loop.o perf-test-y +=3D inlineloop.o perf-test-y +=3D jitdump.o perf-test-y +=3D context_switch_loop.o @@ -27,6 +28,7 @@ CFLAGS_brstack.o =3D -g -O0 -fno-inline -U_FORTI= FY_SOURCE CFLAGS_datasym.o =3D -g -O0 -fno-inline -U_FORTIFY_SOURCE CFLAGS_traploop.o =3D -g -O0 -fno-inline -U_FORTIFY_SOURCE CFLAGS_branch_not_taken_loop.o =3D -g -O0 -fno-inline -U_FORTIFY_SOURCE +CFLAGS_page_fault_loop.o =3D -g -O0 -fno-inline -U_FORTIFY_SOURCE CFLAGS_inlineloop.o =3D -g -O2 CFLAGS_deterministic.o =3D -g -O0 -fno-inline -U_FORTIFY_SOURCE CFLAGS_named_threads.o =3D -g -O0 -fno-inline -U_FORTIFY_SOURCE diff --git a/tools/perf/tests/workloads/page_fault_loop.c b/tools/perf/test= s/workloads/page_fault_loop.c new file mode 100644 index 0000000000000000000000000000000000000000..4afbc4ab0a55400360facdc3a99= ea5a5a9d52596 --- /dev/null +++ b/tools/perf/tests/workloads/page_fault_loop.c @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include "../tests.h" + +static int page_fault_loop(int argc __maybe_unused, const char **argv __ma= ybe_unused) +{ + size_t size =3D getpagesize(); + char *page; + int ret =3D 1; + + page =3D mmap(NULL, size, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (page =3D=3D MAP_FAILED) { + perror("mmap"); + return 1; + } + + for (int i =3D 0; i < 256; i++) { + /* Drop the PTE so the kernel must resolve a fault on each read. */ + if (madvise(page, size, MADV_DONTNEED)) { + perror("madvise"); + goto out; + } + if (READ_ONCE(*page)) { + fprintf(stderr, "Anonymous page is not zero-filled\n"); + goto out; + } + } + ret =3D 0; +out: + munmap(page, size); + return ret; +} + +DEFINE_WORKLOAD(page_fault_loop); --=20 2.34.1 From nobody Thu Sep 24 13:43:08 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 2791D57F746; Wed, 23 Sep 2026 15:22:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790176953; cv=none; b=fLQcWPAgK33PakVvVtsCG6O/xFNkWKeU3AgucBIpIuHdHa0Ol9+3cgMXPjwb1sOmfOEs4JRAnb4HDPZprfSLmnCCUtYFkgPtLMFTCRgWMrI7yondCy/1yV/Cni+oLog6w0XQ0LlcogIJECj/MsE2KojD0kI7TZAajPXLoNIuhik= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790176953; c=relaxed/simple; bh=EMuhC/0lDACH65JGvd017LcTWkEHVrNEuDe6Eoq9Hq4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=E2PlL+fkrHQvKNRzN28ft7WSuksByDJNEERbW/e3qAVgbBylv1UezC4VUDI+xx1veKvmjCYB/KLPzwpWq3TK95tUo/tWBk5/nR4CiKZqiuwqZqe7ddqSCHJxXvmHpysitfTNWjDS5YJ0adUpEqBhFbHc+LDdZFJBngnmMn6mle4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=O2PVX6RG; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="O2PVX6RG" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 2F5631E5E; Wed, 23 Sep 2026 08:22:28 -0700 (PDT) Received: from e132581.arm.com (unknown [10.2.196.114]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 7118C3F86F; Wed, 23 Sep 2026 08:22:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1790176951; bh=EMuhC/0lDACH65JGvd017LcTWkEHVrNEuDe6Eoq9Hq4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=O2PVX6RGsaXYTOIazTUZVn/nRmiznh3pNplutIBqkaPrRzuQXa6IJbwydmzbIYDzf +i0Jol3K7CKipeq07gZDIPAedBkgPm0V0f4JBw+DkV5ssSbVA52LZBjyc7/VLt63DC Z5jxy5wkACxDL/57lXv8azPCS2gCLHAZop+TRofI= From: Leo Yan Date: Wed, 23 Sep 2026 16:21:54 +0100 Subject: [PATCH v2 14/14] perf tests: Check CoreSight emulated instruction entry and exit Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260923-perf_cs_etm_fix_non_taken-v2-14-6ab8c07a5455@arm.com> References: <20260923-perf_cs_etm_fix_non_taken-v2-0-6ab8c07a5455@arm.com> In-Reply-To: <20260923-perf_cs_etm_fix_non_taken-v2-0-6ab8c07a5455@arm.com> To: Arnaldo Carvalho de Melo , Namhyung Kim , Jiri Olsa , Ian Rogers , Adrian Hunter , James Clark , Mike Leach , Suzuki K Poulose , Suyash Mahar , Amir Ayupov Cc: Arnaldo Carvalho de Melo , coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Leo Yan X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1790176913; l=2055; i=leo.yan@arm.com; s=20250604; h=from:subject:message-id; bh=EMuhC/0lDACH65JGvd017LcTWkEHVrNEuDe6Eoq9Hq4=; b=y9kz+vj19LRt/+Lorv7jNh5I5cKJ52fcNPewi0j7HJGoPERH3qYF+Ur/mKSEv5FlvsNgycUWe COq2yyIsyXVCaBboOiqTIVziJ8f3J63kVe8fhHgS7jTWpxDrg4TbUf/ X-Developer-Key: i=leo.yan@arm.com; a=ed25519; pk=k4BaDbvkCXzBFA7Nw184KHGP5thju8lKqJYIrOWxDhI= Use traploop's EL0 read of ID_AA64ISAR0_EL1 to check an emulated instruction. The kernel emulates MRS and advances the return PC by four bytes. Select MRS entries by instruction encoding because page faults also appear as int/iret pairs but return to the same PC. Reuse the common FIFO recorder and pair checker. For example, an expected int/iret pair is: int 5cc808 =3D> ffff800080010c00 insn: 00 06 38 d5 ... iret ffff800080012284 =3D> 5cc80c insn: e0 03 9f d6 The entry instruction is MRS X0, ID_AA64ISAR0_EL1. After emulating the read at 0x5cc808, the kernel returns via ERET to the next instruction at 0x5cc80c. Assisted-by: Codex:gpt-6 Signed-off-by: Leo Yan --- .../perf/tests/shell/coresight/trap_entry_exit.sh | 24 ++++++++++++++++++= ++++ 1 file changed, 24 insertions(+) diff --git a/tools/perf/tests/shell/coresight/trap_entry_exit.sh b/tools/pe= rf/tests/shell/coresight/trap_entry_exit.sh new file mode 100755 index 0000000000000000000000000000000000000000..3ebd4033b247a1a43e013986897= 2afd41ba905ba --- /dev/null +++ b/tools/perf/tests/shell/coresight/trap_entry_exit.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# CoreSight emulated instruction entry and exit (exclusive) + +# shellcheck source=3D../lib/coresight_exception.sh +. "$(dirname "$0")/../lib/coresight_exception.sh" + +test_trap_entry_exit() +{ + # traploop reads ID_AA64ISAR0_EL1 from EL0. The kernel emulates MRS and + # advances the saved PC, so IRET must resume four bytes after the trap. + if ! record_trace traploop 256; then + cat "$tmpdir/record.log" + echo "Failed to record the traploop workload" + return 1 + fi + decode_trace || return 1 + # Page faults also appear as "int", but retry the same PC. Select MRS + # Xt, ID_AA64ISAR0_EL1 by its encoding; the low five bits select Xt. + check_exception_pairs "int.*insn: [01][[:xdigit:]] 06 38 d5" "iret" 4 || = return 1 +} + +setup_exception_test || exit $? +test_trap_entry_exit --=20 2.34.1