[PATCH v5 13/14] perf tools: Initial support for gtrace decoder
From: Mayuresh Chitale
Date: Mon Aug 10 2026 - 11:40:39 EST
Add bare bones support for gtrace decoder so that the data received
from the hardware by the gtrace perf driver can be written to the
perf record output file. Actual decoding of the trace payload is not yet
implemented.
Co-developed-by: Anup Patel <anup.patel@xxxxxxxxxxxxxxxx>
Signed-off-by: Anup Patel <anup.patel@xxxxxxxxxxxxxxxx>
Signed-off-by: Mayuresh Chitale <mayuresh.chitale@xxxxxxxxxxxxxxxx>
Reviewed-by: Adrian Hunter <adrian.hunter@xxxxxxxxx>
---
tools/perf/util/Build | 1 +
tools/perf/util/auxtrace.c | 3 ++
tools/perf/util/gtrace-decoder.c | 93 ++++++++++++++++++++++++++++++++
tools/perf/util/gtrace.h | 1 +
4 files changed, 98 insertions(+)
create mode 100644 tools/perf/util/gtrace-decoder.c
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 5e2265018826..7bd752b5ae6a 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -148,6 +148,7 @@ perf-util-y += cs-etm.o
perf-util-y += cs-etm-decoder/
endif
perf-util-y += cs-etm-base.o
+perf-util-y += gtrace-decoder.o
perf-util-y += parse-branch-options.o
perf-util-y += parse-regs-options.o
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
index d7f27ca15b81..8eda626aede5 100644
--- a/tools/perf/util/auxtrace.c
+++ b/tools/perf/util/auxtrace.c
@@ -54,6 +54,7 @@
#include "arm-spe.h"
#include "hisi-ptt.h"
#include "s390-cpumsf.h"
+#include "gtrace.h"
#include "util/mmap.h"
#include "powerpc-vpadtl.h"
@@ -1428,6 +1429,8 @@ int perf_event__process_auxtrace_info(const struct perf_tool *tool __maybe_unuse
err = powerpc_vpadtl_process_auxtrace_info(event, session);
break;
case PERF_AUXTRACE_GTRACE:
+ err = gtrace__process_auxtrace_info(event, session);
+ break;
case PERF_AUXTRACE_UNKNOWN:
default:
return -EINVAL;
diff --git a/tools/perf/util/gtrace-decoder.c b/tools/perf/util/gtrace-decoder.c
new file mode 100644
index 000000000000..4a1571431edb
--- /dev/null
+++ b/tools/perf/util/gtrace-decoder.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Generic hardware trace (gtrace) decoder
+ * Copyright (c) 2026 Qualcomm Technologies, Inc.
+ */
+
+#include <errno.h>
+#include <inttypes.h>
+#include <internal/lib.h>
+#include "evlist.h"
+#include "session.h"
+#include "gtrace.h"
+
+struct gtrace_decoder {
+ struct auxtrace auxtrace;
+ u32 auxtrace_type;
+ struct perf_session *session;
+ struct machine *machine;
+ u32 pmu_type;
+};
+
+static int gtrace_process_event(struct perf_session *session __maybe_unused,
+ union perf_event *event __maybe_unused,
+ struct perf_sample *sample __maybe_unused,
+ const struct perf_tool *tool __maybe_unused)
+{
+ return 0;
+}
+
+static int gtrace_process_auxtrace_event(struct perf_session *session __maybe_unused,
+ union perf_event *event __maybe_unused,
+ const struct perf_tool *tool __maybe_unused)
+{
+ return 0;
+}
+
+static int gtrace_flush(struct perf_session *session __maybe_unused,
+ const struct perf_tool *tool __maybe_unused)
+{
+ return 0;
+}
+
+static void gtrace_free_events(struct perf_session *session __maybe_unused)
+{
+}
+
+static void gtrace_free(struct perf_session *session)
+{
+ struct gtrace_decoder *ptr = container_of(session->auxtrace, struct gtrace_decoder,
+ auxtrace);
+
+ session->auxtrace = NULL;
+ free(ptr);
+}
+
+static bool gtrace_evsel_is_auxtrace(struct perf_session *session,
+ struct evsel *evsel)
+{
+ struct gtrace_decoder *ptr = container_of(session->auxtrace,
+ struct gtrace_decoder, auxtrace);
+
+ return evsel->core.attr.type == ptr->pmu_type;
+}
+
+int gtrace__process_auxtrace_info(union perf_event *event,
+ struct perf_session *session)
+{
+ struct perf_record_auxtrace_info *auxtrace_info = &event->auxtrace_info;
+ struct gtrace_decoder *ptr;
+
+ if (auxtrace_info->header.size < GTRACE_AUXTRACE_PRIV_SIZE +
+ sizeof(struct perf_record_auxtrace_info))
+ return -EINVAL;
+
+ ptr = zalloc(sizeof(*ptr));
+ if (!ptr)
+ return -ENOMEM;
+
+ ptr->session = session;
+ ptr->machine = &session->machines.host;
+ ptr->auxtrace_type = auxtrace_info->type;
+ ptr->pmu_type = auxtrace_info->priv[0];
+
+ ptr->auxtrace.process_event = gtrace_process_event;
+ ptr->auxtrace.process_auxtrace_event = gtrace_process_auxtrace_event;
+ ptr->auxtrace.flush_events = gtrace_flush;
+ ptr->auxtrace.free_events = gtrace_free_events;
+ ptr->auxtrace.free = gtrace_free;
+ ptr->auxtrace.evsel_is_auxtrace = gtrace_evsel_is_auxtrace;
+ session->auxtrace = &ptr->auxtrace;
+
+ return 0;
+}
diff --git a/tools/perf/util/gtrace.h b/tools/perf/util/gtrace.h
index 4b87bdaf55c6..3531508b1dfb 100644
--- a/tools/perf/util/gtrace.h
+++ b/tools/perf/util/gtrace.h
@@ -8,5 +8,6 @@
#define GTRACE_AUXTRACE_PRIV_SIZE sizeof(u64)
+int gtrace__process_auxtrace_info(union perf_event *event, struct perf_session *session);
#endif
--
2.43.0