* [PATCH 0/4] perf arm_spe: Dump IMPDEF events
@ 2026-04-01 14:25 James Clark
2026-04-01 14:25 ` [PATCH 1/4] perf arm_spe: Make a function to get the MIDR James Clark
` (3 more replies)
0 siblings, 4 replies; 13+ messages in thread
From: James Clark @ 2026-04-01 14:25 UTC (permalink / raw)
To: John Garry, Will Deacon, Mike Leach, Leo Yan, Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
Al Grant
Cc: linux-arm-kernel, linux-perf-users, linux-kernel, James Clark
In the Arm SPE raw data dump, IMPDEF events aren't printed. Add the
ability to add names for some known events or print the raw event number
for unknown events.
For example:
$ perf report -D
... ARM SPE data: size 0xd000 bytes
00000000: b0 18 c6 32 80 00 80 ff a0 PC 0xff80008032c618 el1 ns=1
00000009: 64 e7 42 00 00 CONTEXT 0x42e7 el1
0000000e: 00 00 00 00 00 PAD
00000013: 49 00 LD GP-REG
00000015: 52 16 10 EV RETIRED L1D-ACCESS TLB-ACCESS
On N1 the event line becomes:
00000015: 52 16 10 EV RETIRED L1D-ACCESS TLB-ACCESS LATE-PREFETCH
Or on other cores it becomes:
00000015: 52 16 10 EV RETIRED L1D-ACCESS TLB-ACCESS IMPDEF:12
Signed-off-by: James Clark <james.clark@linaro.org>
---
James Clark (4):
perf arm_spe: Make a function to get the MIDR
perf arm_spe: Turn event name mappings into an array
perf arm_spe: Decode Arm N1 IMPDEF events
perf arm_spe: Print remaining IMPDEF event numbers
tools/perf/util/arm-spe-decoder/Build | 2 +
.../util/arm-spe-decoder/arm-spe-pkt-decoder.c | 147 ++++++++++++++-------
.../util/arm-spe-decoder/arm-spe-pkt-decoder.h | 5 +-
tools/perf/util/arm-spe.c | 49 ++++---
4 files changed, 135 insertions(+), 68 deletions(-)
---
base-commit: 74e2dbe7be5037a5e5eed6bc1ad562747ac88566
change-id: 20260331-james-spe-impdef-decode-d944f4fdcff7
Best regards,
--
James Clark <james.clark@linaro.org>
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 1/4] perf arm_spe: Make a function to get the MIDR
2026-04-01 14:25 [PATCH 0/4] perf arm_spe: Dump IMPDEF events James Clark
@ 2026-04-01 14:25 ` James Clark
2026-04-02 8:55 ` Leo Yan
2026-04-01 14:25 ` [PATCH 2/4] perf arm_spe: Turn event name mappings into an array James Clark
` (2 subsequent siblings)
3 siblings, 1 reply; 13+ messages in thread
From: James Clark @ 2026-04-01 14:25 UTC (permalink / raw)
To: John Garry, Will Deacon, Mike Leach, Leo Yan, Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
Al Grant
Cc: linux-arm-kernel, linux-perf-users, linux-kernel, James Clark
We'll need the MIDR to dump IMPDEF events in the next commits so extract
a function for it.
No functional changes intended.
Signed-off-by: James Clark <james.clark@linaro.org>
---
tools/perf/util/arm-spe.c | 36 ++++++++++++++++++++++--------------
1 file changed, 22 insertions(+), 14 deletions(-)
diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c
index 70dd9bee47c7..7447b000f9cd 100644
--- a/tools/perf/util/arm-spe.c
+++ b/tools/perf/util/arm-spe.c
@@ -958,14 +958,9 @@ static void arm_spe__synth_memory_level(struct arm_spe_queue *speq,
}
}
-static void arm_spe__synth_ds(struct arm_spe_queue *speq,
- const struct arm_spe_record *record,
- union perf_mem_data_src *data_src)
+static int arm_spe__get_midr(struct arm_spe *spe, int cpu, u64 *midr)
{
- struct arm_spe *spe = speq->spe;
- u64 *metadata = NULL;
- u64 midr;
- unsigned int i;
+ u64 *metadata;
/* Metadata version 1 assumes all CPUs are the same (old behavior) */
if (spe->metadata_ver == 1) {
@@ -973,15 +968,28 @@ static void arm_spe__synth_ds(struct arm_spe_queue *speq,
pr_warning_once("Old SPE metadata, re-record to improve decode accuracy\n");
cpuid = perf_env__cpuid(perf_session__env(spe->session));
- midr = strtol(cpuid, NULL, 16);
- } else {
- metadata = arm_spe__get_metadata_by_cpu(spe, speq->cpu);
- if (!metadata)
- return;
-
- midr = metadata[ARM_SPE_CPU_MIDR];
+ *midr = strtol(cpuid, NULL, 16);
+ return 0;
}
+ metadata = arm_spe__get_metadata_by_cpu(spe, cpu);
+ if (!metadata)
+ return -EINVAL;
+
+ *midr = metadata[ARM_SPE_CPU_MIDR];
+ return 0;
+}
+
+static void arm_spe__synth_ds(struct arm_spe_queue *speq,
+ const struct arm_spe_record *record,
+ union perf_mem_data_src *data_src)
+{
+ u64 midr;
+ unsigned int i;
+
+ if (arm_spe__get_midr(speq->spe, speq->cpu, &midr))
+ return;
+
for (i = 0; i < ARRAY_SIZE(data_source_handles); i++) {
if (is_midr_in_range_list(midr, data_source_handles[i].midr_ranges)) {
return data_source_handles[i].ds_synth(record, data_src);
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 2/4] perf arm_spe: Turn event name mappings into an array
2026-04-01 14:25 [PATCH 0/4] perf arm_spe: Dump IMPDEF events James Clark
2026-04-01 14:25 ` [PATCH 1/4] perf arm_spe: Make a function to get the MIDR James Clark
@ 2026-04-01 14:25 ` James Clark
2026-04-02 9:13 ` Leo Yan
2026-04-02 15:30 ` Ian Rogers
2026-04-01 14:25 ` [PATCH 3/4] perf arm_spe: Decode Arm N1 IMPDEF events James Clark
2026-04-01 14:25 ` [PATCH 4/4] perf arm_spe: Print remaining IMPDEF event numbers James Clark
3 siblings, 2 replies; 13+ messages in thread
From: James Clark @ 2026-04-01 14:25 UTC (permalink / raw)
To: John Garry, Will Deacon, Mike Leach, Leo Yan, Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
Al Grant
Cc: linux-arm-kernel, linux-perf-users, linux-kernel, James Clark
This is so we can have a single function that prints events and can be
used with multiple mappings from different CPUs. Remove any bit that was
printed so that later we can print out the remaining unknown impdef
bits.
No functional changes intended.
Signed-off-by: James Clark <james.clark@linaro.org>
---
.../util/arm-spe-decoder/arm-spe-pkt-decoder.c | 88 +++++++++++-----------
1 file changed, 43 insertions(+), 45 deletions(-)
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
index 5769ba2f4140..c880b0dec3a1 100644
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
@@ -276,6 +276,48 @@ static int arm_spe_pkt_out_string(int *err, char **buf_p, size_t *blen,
return ret;
}
+struct ev_string {
+ u8 event;
+ const char *desc;
+};
+
+static const struct ev_string common_ev_strings[] = {
+ { .event = EV_EXCEPTION_GEN, .desc = "EXCEPTION-GEN" },
+ { .event = EV_RETIRED, .desc = "RETIRED" },
+ { .event = EV_L1D_ACCESS, .desc = "L1D-ACCESS" },
+ { .event = EV_L1D_REFILL, .desc = "L1D-REFILL" },
+ { .event = EV_TLB_ACCESS, .desc = "TLB-ACCESS" },
+ { .event = EV_TLB_WALK, .desc = "TLB-REFILL" },
+ { .event = EV_NOT_TAKEN, .desc = "NOT-TAKEN" },
+ { .event = EV_MISPRED, .desc = "MISPRED" },
+ { .event = EV_LLC_ACCESS, .desc = "LLC-ACCESS" },
+ { .event = EV_LLC_MISS, .desc = "LLC-REFILL" },
+ { .event = EV_REMOTE_ACCESS, .desc = "REMOTE-ACCESS" },
+ { .event = EV_ALIGNMENT, .desc = "ALIGNMENT" },
+ { .event = EV_TRANSACTIONAL, .desc = "TXN" },
+ { .event = EV_PARTIAL_PREDICATE, .desc = "SVE-PARTIAL-PRED" },
+ { .event = EV_EMPTY_PREDICATE, .desc = "SVE-EMPTY-PRED" },
+ { .event = EV_L2D_ACCESS, .desc = "L2D-ACCESS" },
+ { .event = EV_L2D_MISS, .desc = "L2D-MISS" },
+ { .event = EV_CACHE_DATA_MODIFIED, .desc = "HITM" },
+ { .event = EV_RECENTLY_FETCHED, .desc = "LFB" },
+ { .event = EV_DATA_SNOOPED, .desc = "SNOOPED" },
+ { .event = EV_STREAMING_SVE_MODE, .desc = "STREAMING-SVE" },
+ { .event = EV_SMCU, .desc = "SMCU" },
+ { .event = 0, .desc = NULL },
+};
+
+static u64 print_event_list(int *err, char **buf, size_t *buf_len,
+ const struct ev_string *ev_strings, u64 payload)
+{
+ for (const struct ev_string *ev = ev_strings; ev->desc != NULL; ev++) {
+ if (payload & BIT(ev->event))
+ arm_spe_pkt_out_string(err, buf, buf_len, " %s", ev->desc);
+ payload &= ~BIT(ev->event);
+ }
+ return payload;
+}
+
static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
char *buf, size_t buf_len)
{
@@ -283,51 +325,7 @@ static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
int err = 0;
arm_spe_pkt_out_string(&err, &buf, &buf_len, "EV");
-
- if (payload & BIT(EV_EXCEPTION_GEN))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " EXCEPTION-GEN");
- if (payload & BIT(EV_RETIRED))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " RETIRED");
- if (payload & BIT(EV_L1D_ACCESS))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " L1D-ACCESS");
- if (payload & BIT(EV_L1D_REFILL))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " L1D-REFILL");
- if (payload & BIT(EV_TLB_ACCESS))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " TLB-ACCESS");
- if (payload & BIT(EV_TLB_WALK))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " TLB-REFILL");
- if (payload & BIT(EV_NOT_TAKEN))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " NOT-TAKEN");
- if (payload & BIT(EV_MISPRED))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " MISPRED");
- if (payload & BIT(EV_LLC_ACCESS))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " LLC-ACCESS");
- if (payload & BIT(EV_LLC_MISS))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " LLC-REFILL");
- if (payload & BIT(EV_REMOTE_ACCESS))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " REMOTE-ACCESS");
- if (payload & BIT(EV_ALIGNMENT))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " ALIGNMENT");
- if (payload & BIT(EV_TRANSACTIONAL))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " TXN");
- if (payload & BIT(EV_PARTIAL_PREDICATE))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " SVE-PARTIAL-PRED");
- if (payload & BIT(EV_EMPTY_PREDICATE))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " SVE-EMPTY-PRED");
- if (payload & BIT(EV_L2D_ACCESS))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " L2D-ACCESS");
- if (payload & BIT(EV_L2D_MISS))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " L2D-MISS");
- if (payload & BIT(EV_CACHE_DATA_MODIFIED))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " HITM");
- if (payload & BIT(EV_RECENTLY_FETCHED))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " LFB");
- if (payload & BIT(EV_DATA_SNOOPED))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " SNOOPED");
- if (payload & BIT(EV_STREAMING_SVE_MODE))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " STREAMING-SVE");
- if (payload & BIT(EV_SMCU))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " SMCU");
+ print_event_list(&err, &buf, &buf_len, common_ev_strings, payload);
return err;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 3/4] perf arm_spe: Decode Arm N1 IMPDEF events
2026-04-01 14:25 [PATCH 0/4] perf arm_spe: Dump IMPDEF events James Clark
2026-04-01 14:25 ` [PATCH 1/4] perf arm_spe: Make a function to get the MIDR James Clark
2026-04-01 14:25 ` [PATCH 2/4] perf arm_spe: Turn event name mappings into an array James Clark
@ 2026-04-01 14:25 ` James Clark
2026-04-02 9:32 ` Leo Yan
2026-04-02 15:26 ` Ian Rogers
2026-04-01 14:25 ` [PATCH 4/4] perf arm_spe: Print remaining IMPDEF event numbers James Clark
3 siblings, 2 replies; 13+ messages in thread
From: James Clark @ 2026-04-01 14:25 UTC (permalink / raw)
To: John Garry, Will Deacon, Mike Leach, Leo Yan, Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
Al Grant
Cc: linux-arm-kernel, linux-perf-users, linux-kernel, James Clark
From the TRM [1], N1 has one IMPDEF event which isn't covered by the
common list. Add a framework so that more cores can be added in the
future and that the N1 IMPDEF event can be decoded. Also increase the
size of the buffer because we're adding more strings and if it gets
truncated it falls back to a hex dump only.
[1]: https://developer.arm.com/documentation/100616/0401/Statistical-Profiling-Extension/implementation-defined-features-of-SPE
Suggested-by: Al Grant <al.grant@arm.com>
Signed-off-by: James Clark <james.clark@linaro.org>
---
tools/perf/util/arm-spe-decoder/Build | 2 +
.../util/arm-spe-decoder/arm-spe-pkt-decoder.c | 45 ++++++++++++++++++++--
.../util/arm-spe-decoder/arm-spe-pkt-decoder.h | 5 ++-
tools/perf/util/arm-spe.c | 13 ++++---
4 files changed, 54 insertions(+), 11 deletions(-)
diff --git a/tools/perf/util/arm-spe-decoder/Build b/tools/perf/util/arm-spe-decoder/Build
index ab500e0efe24..97a298d1e279 100644
--- a/tools/perf/util/arm-spe-decoder/Build
+++ b/tools/perf/util/arm-spe-decoder/Build
@@ -1 +1,3 @@
perf-util-y += arm-spe-pkt-decoder.o arm-spe-decoder.o
+
+CFLAGS_arm-spe-pkt-decoder.o += -I$(srctree)/tools/arch/arm64/include/ -I$(OUTPUT)arch/arm64/include/generated/
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
index c880b0dec3a1..42a7501d4dfe 100644
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
@@ -15,6 +15,8 @@
#include "arm-spe-pkt-decoder.h"
+#include "../../arm64/include/asm/cputype.h"
+
static const char * const arm_spe_packet_name[] = {
[ARM_SPE_PAD] = "PAD",
[ARM_SPE_END] = "END",
@@ -307,6 +309,11 @@ static const struct ev_string common_ev_strings[] = {
{ .event = 0, .desc = NULL },
};
+static const struct ev_string n1_event_strings[] = {
+ { .event = 12, .desc = "LATE-PREFETCH" },
+ { .event = 0, .desc = NULL },
+};
+
static u64 print_event_list(int *err, char **buf, size_t *buf_len,
const struct ev_string *ev_strings, u64 payload)
{
@@ -318,14 +325,44 @@ static u64 print_event_list(int *err, char **buf, size_t *buf_len,
return payload;
}
+struct event_print_handle {
+ const struct midr_range *midr_ranges;
+ const struct ev_string *ev_strings;
+};
+
+#define EV_PRINT(range, strings) \
+ { \
+ .midr_ranges = range, \
+ .ev_strings = strings, \
+ }
+
+static const struct midr_range n1_event_encoding_cpus[] = {
+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
+ {},
+};
+
+static const struct event_print_handle event_print_handles[] = {
+ EV_PRINT(n1_event_encoding_cpus, n1_event_strings),
+};
+
static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
- char *buf, size_t buf_len)
+ char *buf, size_t buf_len, u64 midr)
{
u64 payload = packet->payload;
int err = 0;
arm_spe_pkt_out_string(&err, &buf, &buf_len, "EV");
- print_event_list(&err, &buf, &buf_len, common_ev_strings, payload);
+ payload = print_event_list(&err, &buf, &buf_len, common_ev_strings,
+ payload);
+
+ /* Try to decode IMPDEF bits for known CPUs */
+ for (unsigned int i = 0; i < ARRAY_SIZE(event_print_handles); i++) {
+ if (is_midr_in_range_list(midr,
+ event_print_handles[i].midr_ranges))
+ payload = print_event_list(&err, &buf, &buf_len,
+ event_print_handles[i].ev_strings,
+ payload);
+ }
return err;
}
@@ -506,7 +543,7 @@ static int arm_spe_pkt_desc_counter(const struct arm_spe_pkt *packet,
}
int arm_spe_pkt_desc(const struct arm_spe_pkt *packet, char *buf,
- size_t buf_len)
+ size_t buf_len, u64 midr)
{
int idx = packet->index;
unsigned long long payload = packet->payload;
@@ -522,7 +559,7 @@ int arm_spe_pkt_desc(const struct arm_spe_pkt *packet, char *buf,
arm_spe_pkt_out_string(&err, &buf, &blen, "%s", name);
break;
case ARM_SPE_EVENTS:
- err = arm_spe_pkt_desc_event(packet, buf, buf_len);
+ err = arm_spe_pkt_desc_event(packet, buf, buf_len, midr);
break;
case ARM_SPE_OP_TYPE:
err = arm_spe_pkt_desc_op_type(packet, buf, buf_len);
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
index adf4cde320aa..17b067fe3c87 100644
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
@@ -11,7 +11,7 @@
#include <stddef.h>
#include <stdint.h>
-#define ARM_SPE_PKT_DESC_MAX 256
+#define ARM_SPE_PKT_DESC_MAX 512
#define ARM_SPE_NEED_MORE_BYTES -1
#define ARM_SPE_BAD_PACKET -2
@@ -186,5 +186,6 @@ const char *arm_spe_pkt_name(enum arm_spe_pkt_type);
int arm_spe_get_packet(const unsigned char *buf, size_t len,
struct arm_spe_pkt *packet);
-int arm_spe_pkt_desc(const struct arm_spe_pkt *packet, char *buf, size_t len);
+int arm_spe_pkt_desc(const struct arm_spe_pkt *packet, char *buf, size_t len,
+ u64 midr);
#endif
diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c
index 7447b000f9cd..46f0309c092b 100644
--- a/tools/perf/util/arm-spe.c
+++ b/tools/perf/util/arm-spe.c
@@ -135,7 +135,7 @@ struct data_source_handle {
}
static void arm_spe_dump(struct arm_spe *spe __maybe_unused,
- unsigned char *buf, size_t len)
+ unsigned char *buf, size_t len, u64 midr)
{
struct arm_spe_pkt packet;
size_t pos = 0;
@@ -161,7 +161,7 @@ static void arm_spe_dump(struct arm_spe *spe __maybe_unused,
color_fprintf(stdout, color, " ");
if (ret > 0) {
ret = arm_spe_pkt_desc(&packet, desc,
- ARM_SPE_PKT_DESC_MAX);
+ ARM_SPE_PKT_DESC_MAX, midr);
if (!ret)
color_fprintf(stdout, color, " %s\n", desc);
} else {
@@ -174,10 +174,10 @@ static void arm_spe_dump(struct arm_spe *spe __maybe_unused,
}
static void arm_spe_dump_event(struct arm_spe *spe, unsigned char *buf,
- size_t len)
+ size_t len, u64 midr)
{
printf(".\n");
- arm_spe_dump(spe, buf, len);
+ arm_spe_dump(spe, buf, len, midr);
}
static int arm_spe_get_trace(struct arm_spe_buffer *b, void *data)
@@ -1469,8 +1469,11 @@ static int arm_spe_process_auxtrace_event(struct perf_session *session,
/* Dump here now we have copied a piped trace out of the pipe */
if (dump_trace) {
if (auxtrace_buffer__get_data(buffer, fd)) {
+ u64 midr = 0;
+
+ arm_spe__get_midr(spe, buffer->cpu.cpu, &midr);
arm_spe_dump_event(spe, buffer->data,
- buffer->size);
+ buffer->size, midr);
auxtrace_buffer__put_data(buffer);
}
}
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 4/4] perf arm_spe: Print remaining IMPDEF event numbers
2026-04-01 14:25 [PATCH 0/4] perf arm_spe: Dump IMPDEF events James Clark
` (2 preceding siblings ...)
2026-04-01 14:25 ` [PATCH 3/4] perf arm_spe: Decode Arm N1 IMPDEF events James Clark
@ 2026-04-01 14:25 ` James Clark
2026-04-02 9:46 ` Leo Yan
3 siblings, 1 reply; 13+ messages in thread
From: James Clark @ 2026-04-01 14:25 UTC (permalink / raw)
To: John Garry, Will Deacon, Mike Leach, Leo Yan, Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
Al Grant
Cc: linux-arm-kernel, linux-perf-users, linux-kernel, James Clark
Any IMPDEF events not printed out from a known core's IMPDEF list or for
a completely unknown core will still not be shown to the user. Fix this
by printing the remaining bits as comma separated raw numbers, e.g.
"IMPDEF:1,2,3,4".
Suggested-by: Al Grant <al.grant@arm.com>
Signed-off-by: James Clark <james.clark@linaro.org>
---
tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
index 42a7501d4dfe..b93712ce0aca 100644
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
@@ -364,6 +364,24 @@ static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
payload);
}
+ /*
+ * Print remaining IMPDEF bits that weren't printed above as raw
+ * "IMPDEF:1,2,3,4" etc.
+ */
+ if (payload) {
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " IMPDEF:",
+ payload);
+ for (int i = 0; i < 64; i++) {
+ const char *sep = payload & (payload - 1) ? "," : "";
+
+ if (payload & BIT(i)) {
+ arm_spe_pkt_out_string(&err, &buf, &buf_len,
+ "%d%s", i, sep);
+ payload &= ~BIT(i);
+ }
+ }
+ }
+
return err;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 1/4] perf arm_spe: Make a function to get the MIDR
2026-04-01 14:25 ` [PATCH 1/4] perf arm_spe: Make a function to get the MIDR James Clark
@ 2026-04-02 8:55 ` Leo Yan
0 siblings, 0 replies; 13+ messages in thread
From: Leo Yan @ 2026-04-02 8:55 UTC (permalink / raw)
To: James Clark
Cc: John Garry, Will Deacon, Mike Leach, Leo Yan, Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
Al Grant, linux-arm-kernel, linux-perf-users, linux-kernel
On Wed, Apr 01, 2026 at 03:25:49PM +0100, James Clark wrote:
> We'll need the MIDR to dump IMPDEF events in the next commits so extract
> a function for it.
>
> No functional changes intended.
>
> Signed-off-by: James Clark <james.clark@linaro.org>
Reviewed-by: Leo Yan <leo.yan@arm.com>
> ---
> tools/perf/util/arm-spe.c | 36 ++++++++++++++++++++++--------------
> 1 file changed, 22 insertions(+), 14 deletions(-)
>
> diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c
> index 70dd9bee47c7..7447b000f9cd 100644
> --- a/tools/perf/util/arm-spe.c
> +++ b/tools/perf/util/arm-spe.c
> @@ -958,14 +958,9 @@ static void arm_spe__synth_memory_level(struct arm_spe_queue *speq,
> }
> }
>
> -static void arm_spe__synth_ds(struct arm_spe_queue *speq,
> - const struct arm_spe_record *record,
> - union perf_mem_data_src *data_src)
> +static int arm_spe__get_midr(struct arm_spe *spe, int cpu, u64 *midr)
> {
> - struct arm_spe *spe = speq->spe;
> - u64 *metadata = NULL;
> - u64 midr;
> - unsigned int i;
> + u64 *metadata;
>
> /* Metadata version 1 assumes all CPUs are the same (old behavior) */
> if (spe->metadata_ver == 1) {
> @@ -973,15 +968,28 @@ static void arm_spe__synth_ds(struct arm_spe_queue *speq,
>
> pr_warning_once("Old SPE metadata, re-record to improve decode accuracy\n");
> cpuid = perf_env__cpuid(perf_session__env(spe->session));
> - midr = strtol(cpuid, NULL, 16);
> - } else {
> - metadata = arm_spe__get_metadata_by_cpu(spe, speq->cpu);
> - if (!metadata)
> - return;
> -
> - midr = metadata[ARM_SPE_CPU_MIDR];
> + *midr = strtol(cpuid, NULL, 16);
> + return 0;
> }
>
> + metadata = arm_spe__get_metadata_by_cpu(spe, cpu);
> + if (!metadata)
> + return -EINVAL;
> +
> + *midr = metadata[ARM_SPE_CPU_MIDR];
> + return 0;
> +}
> +
> +static void arm_spe__synth_ds(struct arm_spe_queue *speq,
> + const struct arm_spe_record *record,
> + union perf_mem_data_src *data_src)
> +{
> + u64 midr;
> + unsigned int i;
> +
> + if (arm_spe__get_midr(speq->spe, speq->cpu, &midr))
> + return;
> +
> for (i = 0; i < ARRAY_SIZE(data_source_handles); i++) {
> if (is_midr_in_range_list(midr, data_source_handles[i].midr_ranges)) {
> return data_source_handles[i].ds_synth(record, data_src);
>
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/4] perf arm_spe: Turn event name mappings into an array
2026-04-01 14:25 ` [PATCH 2/4] perf arm_spe: Turn event name mappings into an array James Clark
@ 2026-04-02 9:13 ` Leo Yan
2026-04-02 9:48 ` James Clark
2026-04-02 15:30 ` Ian Rogers
1 sibling, 1 reply; 13+ messages in thread
From: Leo Yan @ 2026-04-02 9:13 UTC (permalink / raw)
To: James Clark
Cc: John Garry, Will Deacon, Mike Leach, Leo Yan, Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
Al Grant, linux-arm-kernel, linux-perf-users, linux-kernel
On Wed, Apr 01, 2026 at 03:25:50PM +0100, James Clark wrote:
> This is so we can have a single function that prints events and can be
> used with multiple mappings from different CPUs. Remove any bit that was
> printed so that later we can print out the remaining unknown impdef
> bits.
>
> No functional changes intended.
>
> Signed-off-by: James Clark <james.clark@linaro.org>
> ---
> .../util/arm-spe-decoder/arm-spe-pkt-decoder.c | 88 +++++++++++-----------
> 1 file changed, 43 insertions(+), 45 deletions(-)
>
> diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
> index 5769ba2f4140..c880b0dec3a1 100644
> --- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
> +++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
> @@ -276,6 +276,48 @@ static int arm_spe_pkt_out_string(int *err, char **buf_p, size_t *blen,
> return ret;
> }
>
> +struct ev_string {
> + u8 event;
> + const char *desc;
> +};
Maybe we can have more ambition to define a more general structure:
struct packet_field_string {
u64 bit_mask;
u64 bit_val;
const char *desc;
};
Thus, this also can be used by other bit fields decoding. We can do
this now or if later refactor for other packets.
Either way is fine for me:
Reviewed-by: Leo Yan <leo.yan@arm.com>
> +
> +static const struct ev_string common_ev_strings[] = {
> + { .event = EV_EXCEPTION_GEN, .desc = "EXCEPTION-GEN" },
> + { .event = EV_RETIRED, .desc = "RETIRED" },
> + { .event = EV_L1D_ACCESS, .desc = "L1D-ACCESS" },
> + { .event = EV_L1D_REFILL, .desc = "L1D-REFILL" },
> + { .event = EV_TLB_ACCESS, .desc = "TLB-ACCESS" },
> + { .event = EV_TLB_WALK, .desc = "TLB-REFILL" },
> + { .event = EV_NOT_TAKEN, .desc = "NOT-TAKEN" },
> + { .event = EV_MISPRED, .desc = "MISPRED" },
> + { .event = EV_LLC_ACCESS, .desc = "LLC-ACCESS" },
> + { .event = EV_LLC_MISS, .desc = "LLC-REFILL" },
> + { .event = EV_REMOTE_ACCESS, .desc = "REMOTE-ACCESS" },
> + { .event = EV_ALIGNMENT, .desc = "ALIGNMENT" },
> + { .event = EV_TRANSACTIONAL, .desc = "TXN" },
> + { .event = EV_PARTIAL_PREDICATE, .desc = "SVE-PARTIAL-PRED" },
> + { .event = EV_EMPTY_PREDICATE, .desc = "SVE-EMPTY-PRED" },
> + { .event = EV_L2D_ACCESS, .desc = "L2D-ACCESS" },
> + { .event = EV_L2D_MISS, .desc = "L2D-MISS" },
> + { .event = EV_CACHE_DATA_MODIFIED, .desc = "HITM" },
> + { .event = EV_RECENTLY_FETCHED, .desc = "LFB" },
> + { .event = EV_DATA_SNOOPED, .desc = "SNOOPED" },
> + { .event = EV_STREAMING_SVE_MODE, .desc = "STREAMING-SVE" },
> + { .event = EV_SMCU, .desc = "SMCU" },
> + { .event = 0, .desc = NULL },
> +};
> +
> +static u64 print_event_list(int *err, char **buf, size_t *buf_len,
> + const struct ev_string *ev_strings, u64 payload)
> +{
> + for (const struct ev_string *ev = ev_strings; ev->desc != NULL; ev++) {
> + if (payload & BIT(ev->event))
> + arm_spe_pkt_out_string(err, buf, buf_len, " %s", ev->desc);
> + payload &= ~BIT(ev->event);
> + }
> + return payload;
> +}
> +
> static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
> char *buf, size_t buf_len)
> {
> @@ -283,51 +325,7 @@ static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
> int err = 0;
>
> arm_spe_pkt_out_string(&err, &buf, &buf_len, "EV");
> -
> - if (payload & BIT(EV_EXCEPTION_GEN))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " EXCEPTION-GEN");
> - if (payload & BIT(EV_RETIRED))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " RETIRED");
> - if (payload & BIT(EV_L1D_ACCESS))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " L1D-ACCESS");
> - if (payload & BIT(EV_L1D_REFILL))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " L1D-REFILL");
> - if (payload & BIT(EV_TLB_ACCESS))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " TLB-ACCESS");
> - if (payload & BIT(EV_TLB_WALK))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " TLB-REFILL");
> - if (payload & BIT(EV_NOT_TAKEN))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " NOT-TAKEN");
> - if (payload & BIT(EV_MISPRED))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " MISPRED");
> - if (payload & BIT(EV_LLC_ACCESS))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " LLC-ACCESS");
> - if (payload & BIT(EV_LLC_MISS))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " LLC-REFILL");
> - if (payload & BIT(EV_REMOTE_ACCESS))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " REMOTE-ACCESS");
> - if (payload & BIT(EV_ALIGNMENT))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " ALIGNMENT");
> - if (payload & BIT(EV_TRANSACTIONAL))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " TXN");
> - if (payload & BIT(EV_PARTIAL_PREDICATE))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " SVE-PARTIAL-PRED");
> - if (payload & BIT(EV_EMPTY_PREDICATE))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " SVE-EMPTY-PRED");
> - if (payload & BIT(EV_L2D_ACCESS))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " L2D-ACCESS");
> - if (payload & BIT(EV_L2D_MISS))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " L2D-MISS");
> - if (payload & BIT(EV_CACHE_DATA_MODIFIED))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " HITM");
> - if (payload & BIT(EV_RECENTLY_FETCHED))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " LFB");
> - if (payload & BIT(EV_DATA_SNOOPED))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " SNOOPED");
> - if (payload & BIT(EV_STREAMING_SVE_MODE))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " STREAMING-SVE");
> - if (payload & BIT(EV_SMCU))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " SMCU");
> + print_event_list(&err, &buf, &buf_len, common_ev_strings, payload);
>
> return err;
> }
>
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 3/4] perf arm_spe: Decode Arm N1 IMPDEF events
2026-04-01 14:25 ` [PATCH 3/4] perf arm_spe: Decode Arm N1 IMPDEF events James Clark
@ 2026-04-02 9:32 ` Leo Yan
2026-04-02 9:49 ` James Clark
2026-04-02 15:26 ` Ian Rogers
1 sibling, 1 reply; 13+ messages in thread
From: Leo Yan @ 2026-04-02 9:32 UTC (permalink / raw)
To: James Clark
Cc: John Garry, Will Deacon, Mike Leach, Leo Yan, Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
Al Grant, linux-arm-kernel, linux-perf-users, linux-kernel
On Wed, Apr 01, 2026 at 03:25:51PM +0100, James Clark wrote:
[...]
> static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
> - char *buf, size_t buf_len)
> + char *buf, size_t buf_len, u64 midr)
Just wandering if we can add a "midr" field into struct arm_spe_pkt ?
Then we don't need to change many functions for populating midr.
The rest is good for me.
Thanks,
Leo
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 4/4] perf arm_spe: Print remaining IMPDEF event numbers
2026-04-01 14:25 ` [PATCH 4/4] perf arm_spe: Print remaining IMPDEF event numbers James Clark
@ 2026-04-02 9:46 ` Leo Yan
0 siblings, 0 replies; 13+ messages in thread
From: Leo Yan @ 2026-04-02 9:46 UTC (permalink / raw)
To: James Clark
Cc: John Garry, Will Deacon, Mike Leach, Leo Yan, Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
Al Grant, linux-arm-kernel, linux-perf-users, linux-kernel
On Wed, Apr 01, 2026 at 03:25:52PM +0100, James Clark wrote:
> Any IMPDEF events not printed out from a known core's IMPDEF list or for
> a completely unknown core will still not be shown to the user. Fix this
> by printing the remaining bits as comma separated raw numbers, e.g.
> "IMPDEF:1,2,3,4".
>
> Suggested-by: Al Grant <al.grant@arm.com>
> Signed-off-by: James Clark <james.clark@linaro.org>
> ---
> tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
> diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
> index 42a7501d4dfe..b93712ce0aca 100644
> --- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
> +++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
> @@ -364,6 +364,24 @@ static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
> payload);
> }
>
> + /*
> + * Print remaining IMPDEF bits that weren't printed above as raw
> + * "IMPDEF:1,2,3,4" etc.
> + */
> + if (payload) {
> + arm_spe_pkt_out_string(&err, &buf, &buf_len, " IMPDEF:",
> + payload);
> + for (int i = 0; i < 64; i++) {
Nitpick: use for_each_set_bit(i, &payload, 64) instead.
> + const char *sep = payload & (payload - 1) ? "," : "";
> +
> + if (payload & BIT(i)) {
> + arm_spe_pkt_out_string(&err, &buf, &buf_len,
> + "%d%s", i, sep);
> + payload &= ~BIT(i);
> + }
> + }
> + }
> +
> return err;
> }
>
>
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/4] perf arm_spe: Turn event name mappings into an array
2026-04-02 9:13 ` Leo Yan
@ 2026-04-02 9:48 ` James Clark
0 siblings, 0 replies; 13+ messages in thread
From: James Clark @ 2026-04-02 9:48 UTC (permalink / raw)
To: Leo Yan
Cc: John Garry, Will Deacon, Mike Leach, Leo Yan, Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
Al Grant, linux-arm-kernel, linux-perf-users, linux-kernel
On 02/04/2026 10:13 am, Leo Yan wrote:
> On Wed, Apr 01, 2026 at 03:25:50PM +0100, James Clark wrote:
>> This is so we can have a single function that prints events and can be
>> used with multiple mappings from different CPUs. Remove any bit that was
>> printed so that later we can print out the remaining unknown impdef
>> bits.
>>
>> No functional changes intended.
>>
>> Signed-off-by: James Clark <james.clark@linaro.org>
>> ---
>> .../util/arm-spe-decoder/arm-spe-pkt-decoder.c | 88 +++++++++++-----------
>> 1 file changed, 43 insertions(+), 45 deletions(-)
>>
>> diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
>> index 5769ba2f4140..c880b0dec3a1 100644
>> --- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
>> +++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
>> @@ -276,6 +276,48 @@ static int arm_spe_pkt_out_string(int *err, char **buf_p, size_t *blen,
>> return ret;
>> }
>>
>> +struct ev_string {
>> + u8 event;
>> + const char *desc;
>> +};
>
> Maybe we can have more ambition to define a more general structure:
>
> struct packet_field_string {
> u64 bit_mask;
> u64 bit_val;
> const char *desc;
> };
>
> Thus, this also can be used by other bit fields decoding. We can do
> this now or if later refactor for other packets.
>
> Either way is fine for me:
>
> Reviewed-by: Leo Yan <leo.yan@arm.com>
>
Thanks. I think I'll leave it as it is, there's a risk of making it too
generic and then it doesn't fit any other use case anyway. We can always
add it later.
>> +
>> +static const struct ev_string common_ev_strings[] = {
>> + { .event = EV_EXCEPTION_GEN, .desc = "EXCEPTION-GEN" },
>> + { .event = EV_RETIRED, .desc = "RETIRED" },
>> + { .event = EV_L1D_ACCESS, .desc = "L1D-ACCESS" },
>> + { .event = EV_L1D_REFILL, .desc = "L1D-REFILL" },
>> + { .event = EV_TLB_ACCESS, .desc = "TLB-ACCESS" },
>> + { .event = EV_TLB_WALK, .desc = "TLB-REFILL" },
>> + { .event = EV_NOT_TAKEN, .desc = "NOT-TAKEN" },
>> + { .event = EV_MISPRED, .desc = "MISPRED" },
>> + { .event = EV_LLC_ACCESS, .desc = "LLC-ACCESS" },
>> + { .event = EV_LLC_MISS, .desc = "LLC-REFILL" },
>> + { .event = EV_REMOTE_ACCESS, .desc = "REMOTE-ACCESS" },
>> + { .event = EV_ALIGNMENT, .desc = "ALIGNMENT" },
>> + { .event = EV_TRANSACTIONAL, .desc = "TXN" },
>> + { .event = EV_PARTIAL_PREDICATE, .desc = "SVE-PARTIAL-PRED" },
>> + { .event = EV_EMPTY_PREDICATE, .desc = "SVE-EMPTY-PRED" },
>> + { .event = EV_L2D_ACCESS, .desc = "L2D-ACCESS" },
>> + { .event = EV_L2D_MISS, .desc = "L2D-MISS" },
>> + { .event = EV_CACHE_DATA_MODIFIED, .desc = "HITM" },
>> + { .event = EV_RECENTLY_FETCHED, .desc = "LFB" },
>> + { .event = EV_DATA_SNOOPED, .desc = "SNOOPED" },
>> + { .event = EV_STREAMING_SVE_MODE, .desc = "STREAMING-SVE" },
>> + { .event = EV_SMCU, .desc = "SMCU" },
>> + { .event = 0, .desc = NULL },
>> +};
>> +
>> +static u64 print_event_list(int *err, char **buf, size_t *buf_len,
>> + const struct ev_string *ev_strings, u64 payload)
>> +{
>> + for (const struct ev_string *ev = ev_strings; ev->desc != NULL; ev++) {
>> + if (payload & BIT(ev->event))
>> + arm_spe_pkt_out_string(err, buf, buf_len, " %s", ev->desc);
>> + payload &= ~BIT(ev->event);
>> + }
>> + return payload;
>> +}
>> +
>> static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
>> char *buf, size_t buf_len)
>> {
>> @@ -283,51 +325,7 @@ static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
>> int err = 0;
>>
>> arm_spe_pkt_out_string(&err, &buf, &buf_len, "EV");
>> -
>> - if (payload & BIT(EV_EXCEPTION_GEN))
>> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " EXCEPTION-GEN");
>> - if (payload & BIT(EV_RETIRED))
>> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " RETIRED");
>> - if (payload & BIT(EV_L1D_ACCESS))
>> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " L1D-ACCESS");
>> - if (payload & BIT(EV_L1D_REFILL))
>> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " L1D-REFILL");
>> - if (payload & BIT(EV_TLB_ACCESS))
>> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " TLB-ACCESS");
>> - if (payload & BIT(EV_TLB_WALK))
>> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " TLB-REFILL");
>> - if (payload & BIT(EV_NOT_TAKEN))
>> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " NOT-TAKEN");
>> - if (payload & BIT(EV_MISPRED))
>> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " MISPRED");
>> - if (payload & BIT(EV_LLC_ACCESS))
>> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " LLC-ACCESS");
>> - if (payload & BIT(EV_LLC_MISS))
>> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " LLC-REFILL");
>> - if (payload & BIT(EV_REMOTE_ACCESS))
>> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " REMOTE-ACCESS");
>> - if (payload & BIT(EV_ALIGNMENT))
>> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " ALIGNMENT");
>> - if (payload & BIT(EV_TRANSACTIONAL))
>> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " TXN");
>> - if (payload & BIT(EV_PARTIAL_PREDICATE))
>> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " SVE-PARTIAL-PRED");
>> - if (payload & BIT(EV_EMPTY_PREDICATE))
>> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " SVE-EMPTY-PRED");
>> - if (payload & BIT(EV_L2D_ACCESS))
>> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " L2D-ACCESS");
>> - if (payload & BIT(EV_L2D_MISS))
>> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " L2D-MISS");
>> - if (payload & BIT(EV_CACHE_DATA_MODIFIED))
>> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " HITM");
>> - if (payload & BIT(EV_RECENTLY_FETCHED))
>> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " LFB");
>> - if (payload & BIT(EV_DATA_SNOOPED))
>> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " SNOOPED");
>> - if (payload & BIT(EV_STREAMING_SVE_MODE))
>> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " STREAMING-SVE");
>> - if (payload & BIT(EV_SMCU))
>> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " SMCU");
>> + print_event_list(&err, &buf, &buf_len, common_ev_strings, payload);
>>
>> return err;
>> }
>>
>> --
>> 2.34.1
>>
>>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 3/4] perf arm_spe: Decode Arm N1 IMPDEF events
2026-04-02 9:32 ` Leo Yan
@ 2026-04-02 9:49 ` James Clark
0 siblings, 0 replies; 13+ messages in thread
From: James Clark @ 2026-04-02 9:49 UTC (permalink / raw)
To: Leo Yan
Cc: John Garry, Will Deacon, Mike Leach, Leo Yan, Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
Al Grant, linux-arm-kernel, linux-perf-users, linux-kernel
On 02/04/2026 10:32 am, Leo Yan wrote:
> On Wed, Apr 01, 2026 at 03:25:51PM +0100, James Clark wrote:
>
> [...]
>
>> static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
>> - char *buf, size_t buf_len)
>> + char *buf, size_t buf_len, u64 midr)
>
> Just wandering if we can add a "midr" field into struct arm_spe_pkt ?
> Then we don't need to change many functions for populating midr.
>
> The rest is good for me.
>
> Thanks,
> Leo
Yeah I can do that. I was worried they were stored in an array and it
would be a waste of space, but they're not so it's ok.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 3/4] perf arm_spe: Decode Arm N1 IMPDEF events
2026-04-01 14:25 ` [PATCH 3/4] perf arm_spe: Decode Arm N1 IMPDEF events James Clark
2026-04-02 9:32 ` Leo Yan
@ 2026-04-02 15:26 ` Ian Rogers
1 sibling, 0 replies; 13+ messages in thread
From: Ian Rogers @ 2026-04-02 15:26 UTC (permalink / raw)
To: James Clark
Cc: John Garry, Will Deacon, Mike Leach, Leo Yan, Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Adrian Hunter, Al Grant,
linux-arm-kernel, linux-perf-users, linux-kernel
On Wed, Apr 1, 2026 at 7:26 AM James Clark <james.clark@linaro.org> wrote:
>
> From the TRM [1], N1 has one IMPDEF event which isn't covered by the
> common list. Add a framework so that more cores can be added in the
> future and that the N1 IMPDEF event can be decoded. Also increase the
> size of the buffer because we're adding more strings and if it gets
> truncated it falls back to a hex dump only.
>
> [1]: https://developer.arm.com/documentation/100616/0401/Statistical-Profiling-Extension/implementation-defined-features-of-SPE
> Suggested-by: Al Grant <al.grant@arm.com>
> Signed-off-by: James Clark <james.clark@linaro.org>
> ---
> tools/perf/util/arm-spe-decoder/Build | 2 +
> .../util/arm-spe-decoder/arm-spe-pkt-decoder.c | 45 ++++++++++++++++++++--
> .../util/arm-spe-decoder/arm-spe-pkt-decoder.h | 5 ++-
> tools/perf/util/arm-spe.c | 13 ++++---
> 4 files changed, 54 insertions(+), 11 deletions(-)
>
> diff --git a/tools/perf/util/arm-spe-decoder/Build b/tools/perf/util/arm-spe-decoder/Build
> index ab500e0efe24..97a298d1e279 100644
> --- a/tools/perf/util/arm-spe-decoder/Build
> +++ b/tools/perf/util/arm-spe-decoder/Build
> @@ -1 +1,3 @@
> perf-util-y += arm-spe-pkt-decoder.o arm-spe-decoder.o
> +
> +CFLAGS_arm-spe-pkt-decoder.o += -I$(srctree)/tools/arch/arm64/include/ -I$(OUTPUT)arch/arm64/include/generated/
> diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
> index c880b0dec3a1..42a7501d4dfe 100644
> --- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
> +++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
> @@ -15,6 +15,8 @@
>
> #include "arm-spe-pkt-decoder.h"
>
> +#include "../../arm64/include/asm/cputype.h"
Sashiko spotted:
https://sashiko.dev/#/patchset/20260401-james-spe-impdef-decode-v1-0-ad0d372c220c%40linaro.org
"""
This isn't a bug, but does this include directive rely on accidental
path normalization?
The relative path ../../arm64/include/asm/cputype.h does not exist relative
to arm-spe-pkt-decoder.c. It only compiles because the Build file adds
-I$(srctree)/tools/arch/arm64/include/ to CFLAGS.
Would it be cleaner to use #include <asm/cputype.h> to explicitly rely on
the include path?
[ ... ]
"""
I wouldn't use <asm/cputype.h> due to cross-compilation and the like,
instead just add the extra "../" into the include path.
> +
> static const char * const arm_spe_packet_name[] = {
> [ARM_SPE_PAD] = "PAD",
> [ARM_SPE_END] = "END",
> @@ -307,6 +309,11 @@ static const struct ev_string common_ev_strings[] = {
> { .event = 0, .desc = NULL },
> };
>
> +static const struct ev_string n1_event_strings[] = {
> + { .event = 12, .desc = "LATE-PREFETCH" },
> + { .event = 0, .desc = NULL },
> +};
> +
> static u64 print_event_list(int *err, char **buf, size_t *buf_len,
> const struct ev_string *ev_strings, u64 payload)
> {
> @@ -318,14 +325,44 @@ static u64 print_event_list(int *err, char **buf, size_t *buf_len,
> return payload;
> }
>
> +struct event_print_handle {
> + const struct midr_range *midr_ranges;
> + const struct ev_string *ev_strings;
> +};
> +
> +#define EV_PRINT(range, strings) \
> + { \
> + .midr_ranges = range, \
> + .ev_strings = strings, \
> + }
> +
> +static const struct midr_range n1_event_encoding_cpus[] = {
> + MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
> + {},
> +};
> +
> +static const struct event_print_handle event_print_handles[] = {
> + EV_PRINT(n1_event_encoding_cpus, n1_event_strings),
> +};
> +
> static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
> - char *buf, size_t buf_len)
> + char *buf, size_t buf_len, u64 midr)
> {
> u64 payload = packet->payload;
> int err = 0;
>
> arm_spe_pkt_out_string(&err, &buf, &buf_len, "EV");
> - print_event_list(&err, &buf, &buf_len, common_ev_strings, payload);
> + payload = print_event_list(&err, &buf, &buf_len, common_ev_strings,
> + payload);
> +
> + /* Try to decode IMPDEF bits for known CPUs */
> + for (unsigned int i = 0; i < ARRAY_SIZE(event_print_handles); i++) {
> + if (is_midr_in_range_list(midr,
> + event_print_handles[i].midr_ranges))
> + payload = print_event_list(&err, &buf, &buf_len,
> + event_print_handles[i].ev_strings,
> + payload);
> + }
>
> return err;
> }
> @@ -506,7 +543,7 @@ static int arm_spe_pkt_desc_counter(const struct arm_spe_pkt *packet,
> }
>
> int arm_spe_pkt_desc(const struct arm_spe_pkt *packet, char *buf,
> - size_t buf_len)
> + size_t buf_len, u64 midr)
> {
> int idx = packet->index;
> unsigned long long payload = packet->payload;
> @@ -522,7 +559,7 @@ int arm_spe_pkt_desc(const struct arm_spe_pkt *packet, char *buf,
> arm_spe_pkt_out_string(&err, &buf, &blen, "%s", name);
> break;
> case ARM_SPE_EVENTS:
> - err = arm_spe_pkt_desc_event(packet, buf, buf_len);
> + err = arm_spe_pkt_desc_event(packet, buf, buf_len, midr);
> break;
> case ARM_SPE_OP_TYPE:
> err = arm_spe_pkt_desc_op_type(packet, buf, buf_len);
> diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
> index adf4cde320aa..17b067fe3c87 100644
> --- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
> +++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
> @@ -11,7 +11,7 @@
> #include <stddef.h>
> #include <stdint.h>
>
> -#define ARM_SPE_PKT_DESC_MAX 256
> +#define ARM_SPE_PKT_DESC_MAX 512
>
> #define ARM_SPE_NEED_MORE_BYTES -1
> #define ARM_SPE_BAD_PACKET -2
> @@ -186,5 +186,6 @@ const char *arm_spe_pkt_name(enum arm_spe_pkt_type);
> int arm_spe_get_packet(const unsigned char *buf, size_t len,
> struct arm_spe_pkt *packet);
>
> -int arm_spe_pkt_desc(const struct arm_spe_pkt *packet, char *buf, size_t len);
> +int arm_spe_pkt_desc(const struct arm_spe_pkt *packet, char *buf, size_t len,
> + u64 midr);
> #endif
> diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c
> index 7447b000f9cd..46f0309c092b 100644
> --- a/tools/perf/util/arm-spe.c
> +++ b/tools/perf/util/arm-spe.c
> @@ -135,7 +135,7 @@ struct data_source_handle {
> }
>
> static void arm_spe_dump(struct arm_spe *spe __maybe_unused,
> - unsigned char *buf, size_t len)
> + unsigned char *buf, size_t len, u64 midr)
> {
> struct arm_spe_pkt packet;
> size_t pos = 0;
> @@ -161,7 +161,7 @@ static void arm_spe_dump(struct arm_spe *spe __maybe_unused,
> color_fprintf(stdout, color, " ");
> if (ret > 0) {
> ret = arm_spe_pkt_desc(&packet, desc,
> - ARM_SPE_PKT_DESC_MAX);
> + ARM_SPE_PKT_DESC_MAX, midr);
> if (!ret)
> color_fprintf(stdout, color, " %s\n", desc);
> } else {
> @@ -174,10 +174,10 @@ static void arm_spe_dump(struct arm_spe *spe __maybe_unused,
> }
>
> static void arm_spe_dump_event(struct arm_spe *spe, unsigned char *buf,
> - size_t len)
> + size_t len, u64 midr)
> {
> printf(".\n");
> - arm_spe_dump(spe, buf, len);
> + arm_spe_dump(spe, buf, len, midr);
> }
>
> static int arm_spe_get_trace(struct arm_spe_buffer *b, void *data)
> @@ -1469,8 +1469,11 @@ static int arm_spe_process_auxtrace_event(struct perf_session *session,
> /* Dump here now we have copied a piped trace out of the pipe */
> if (dump_trace) {
> if (auxtrace_buffer__get_data(buffer, fd)) {
> + u64 midr = 0;
> +
> + arm_spe__get_midr(spe, buffer->cpu.cpu, &midr);
Sashiko claims to have spotted an issue here:
"""
Is it possible for arm_spe__get_midr() to cause a segmentation fault here?
If the trace is from an older recording (metadata version 1) and the
environment lacks a CPUID string (such as during cross-architecture
analysis), perf_env__cpuid() returns NULL.
It appears arm_spe__get_midr() then passes this NULL pointer to
strtol(cpuid, NULL, 16), which leads to undefined behavior.
"""
But this feels like, if this happens you're already having a bad time
and these changes aren't necessarily making things worse.
Thanks,
Ian
> arm_spe_dump_event(spe, buffer->data,
> - buffer->size);
> + buffer->size, midr);
> auxtrace_buffer__put_data(buffer);
> }
> }
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/4] perf arm_spe: Turn event name mappings into an array
2026-04-01 14:25 ` [PATCH 2/4] perf arm_spe: Turn event name mappings into an array James Clark
2026-04-02 9:13 ` Leo Yan
@ 2026-04-02 15:30 ` Ian Rogers
1 sibling, 0 replies; 13+ messages in thread
From: Ian Rogers @ 2026-04-02 15:30 UTC (permalink / raw)
To: James Clark
Cc: John Garry, Will Deacon, Mike Leach, Leo Yan, Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Adrian Hunter, Al Grant,
linux-arm-kernel, linux-perf-users, linux-kernel
On Wed, Apr 1, 2026 at 7:26 AM James Clark <james.clark@linaro.org> wrote:
>
> This is so we can have a single function that prints events and can be
> used with multiple mappings from different CPUs. Remove any bit that was
> printed so that later we can print out the remaining unknown impdef
> bits.
>
> No functional changes intended.
>
> Signed-off-by: James Clark <james.clark@linaro.org>
> ---
> .../util/arm-spe-decoder/arm-spe-pkt-decoder.c | 88 +++++++++++-----------
> 1 file changed, 43 insertions(+), 45 deletions(-)
>
> diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
> index 5769ba2f4140..c880b0dec3a1 100644
> --- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
> +++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
> @@ -276,6 +276,48 @@ static int arm_spe_pkt_out_string(int *err, char **buf_p, size_t *blen,
> return ret;
> }
>
> +struct ev_string {
> + u8 event;
> + const char *desc;
> +};
> +
> +static const struct ev_string common_ev_strings[] = {
> + { .event = EV_EXCEPTION_GEN, .desc = "EXCEPTION-GEN" },
> + { .event = EV_RETIRED, .desc = "RETIRED" },
> + { .event = EV_L1D_ACCESS, .desc = "L1D-ACCESS" },
> + { .event = EV_L1D_REFILL, .desc = "L1D-REFILL" },
> + { .event = EV_TLB_ACCESS, .desc = "TLB-ACCESS" },
> + { .event = EV_TLB_WALK, .desc = "TLB-REFILL" },
> + { .event = EV_NOT_TAKEN, .desc = "NOT-TAKEN" },
> + { .event = EV_MISPRED, .desc = "MISPRED" },
> + { .event = EV_LLC_ACCESS, .desc = "LLC-ACCESS" },
> + { .event = EV_LLC_MISS, .desc = "LLC-REFILL" },
> + { .event = EV_REMOTE_ACCESS, .desc = "REMOTE-ACCESS" },
> + { .event = EV_ALIGNMENT, .desc = "ALIGNMENT" },
> + { .event = EV_TRANSACTIONAL, .desc = "TXN" },
> + { .event = EV_PARTIAL_PREDICATE, .desc = "SVE-PARTIAL-PRED" },
> + { .event = EV_EMPTY_PREDICATE, .desc = "SVE-EMPTY-PRED" },
> + { .event = EV_L2D_ACCESS, .desc = "L2D-ACCESS" },
> + { .event = EV_L2D_MISS, .desc = "L2D-MISS" },
> + { .event = EV_CACHE_DATA_MODIFIED, .desc = "HITM" },
> + { .event = EV_RECENTLY_FETCHED, .desc = "LFB" },
> + { .event = EV_DATA_SNOOPED, .desc = "SNOOPED" },
> + { .event = EV_STREAMING_SVE_MODE, .desc = "STREAMING-SVE" },
> + { .event = EV_SMCU, .desc = "SMCU" },
> + { .event = 0, .desc = NULL },
> +};
> +
> +static u64 print_event_list(int *err, char **buf, size_t *buf_len,
> + const struct ev_string *ev_strings, u64 payload)
> +{
> + for (const struct ev_string *ev = ev_strings; ev->desc != NULL; ev++) {
> + if (payload & BIT(ev->event))
> + arm_spe_pkt_out_string(err, buf, buf_len, " %s", ev->desc);
> + payload &= ~BIT(ev->event);
Sashiko has a bunch of worries in these patches about 32-bit builds:
https://sashiko.dev/#/patchset/20260401-james-spe-impdef-decode-v1-0-ad0d372c220c%40linaro.org
The one here is:
"""
Since payload is a u64, does using ~BIT(ev->event) unintentionally clear
the upper 32 bits on 32-bit architectures?
On 32-bit systems, BIT() evaluates to a 32-bit unsigned long. The bitwise
NOT operation creates a 32-bit mask, which is then zero-extended to 64 bits
during the compound assignment to the payload.
This would discard bits 32-63, contradicting the intent mentioned in the
commit message to preserve the remaining unknown impdef bits for later
printing.
Would using BIT_ULL() be safer here to ensure a 64-bit inverted mask?
"""
Thanks,
Ian
> + }
> + return payload;
> +}
> +
> static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
> char *buf, size_t buf_len)
> {
> @@ -283,51 +325,7 @@ static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
> int err = 0;
>
> arm_spe_pkt_out_string(&err, &buf, &buf_len, "EV");
> -
> - if (payload & BIT(EV_EXCEPTION_GEN))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " EXCEPTION-GEN");
> - if (payload & BIT(EV_RETIRED))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " RETIRED");
> - if (payload & BIT(EV_L1D_ACCESS))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " L1D-ACCESS");
> - if (payload & BIT(EV_L1D_REFILL))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " L1D-REFILL");
> - if (payload & BIT(EV_TLB_ACCESS))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " TLB-ACCESS");
> - if (payload & BIT(EV_TLB_WALK))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " TLB-REFILL");
> - if (payload & BIT(EV_NOT_TAKEN))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " NOT-TAKEN");
> - if (payload & BIT(EV_MISPRED))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " MISPRED");
> - if (payload & BIT(EV_LLC_ACCESS))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " LLC-ACCESS");
> - if (payload & BIT(EV_LLC_MISS))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " LLC-REFILL");
> - if (payload & BIT(EV_REMOTE_ACCESS))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " REMOTE-ACCESS");
> - if (payload & BIT(EV_ALIGNMENT))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " ALIGNMENT");
> - if (payload & BIT(EV_TRANSACTIONAL))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " TXN");
> - if (payload & BIT(EV_PARTIAL_PREDICATE))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " SVE-PARTIAL-PRED");
> - if (payload & BIT(EV_EMPTY_PREDICATE))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " SVE-EMPTY-PRED");
> - if (payload & BIT(EV_L2D_ACCESS))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " L2D-ACCESS");
> - if (payload & BIT(EV_L2D_MISS))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " L2D-MISS");
> - if (payload & BIT(EV_CACHE_DATA_MODIFIED))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " HITM");
> - if (payload & BIT(EV_RECENTLY_FETCHED))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " LFB");
> - if (payload & BIT(EV_DATA_SNOOPED))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " SNOOPED");
> - if (payload & BIT(EV_STREAMING_SVE_MODE))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " STREAMING-SVE");
> - if (payload & BIT(EV_SMCU))
> - arm_spe_pkt_out_string(&err, &buf, &buf_len, " SMCU");
> + print_event_list(&err, &buf, &buf_len, common_ev_strings, payload);
>
> return err;
> }
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2026-04-02 15:30 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-01 14:25 [PATCH 0/4] perf arm_spe: Dump IMPDEF events James Clark
2026-04-01 14:25 ` [PATCH 1/4] perf arm_spe: Make a function to get the MIDR James Clark
2026-04-02 8:55 ` Leo Yan
2026-04-01 14:25 ` [PATCH 2/4] perf arm_spe: Turn event name mappings into an array James Clark
2026-04-02 9:13 ` Leo Yan
2026-04-02 9:48 ` James Clark
2026-04-02 15:30 ` Ian Rogers
2026-04-01 14:25 ` [PATCH 3/4] perf arm_spe: Decode Arm N1 IMPDEF events James Clark
2026-04-02 9:32 ` Leo Yan
2026-04-02 9:49 ` James Clark
2026-04-02 15:26 ` Ian Rogers
2026-04-01 14:25 ` [PATCH 4/4] perf arm_spe: Print remaining IMPDEF event numbers James Clark
2026-04-02 9:46 ` Leo Yan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox