lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250911124448.1771-4-cp0613@linux.alibaba.com>
Date: Thu, 11 Sep 2025 20:44:47 +0800
From: cp0613@...ux.alibaba.com
To: paul.walmsley@...ive.com,
	palmer@...belt.com,
	aou@...s.berkeley.edu,
	alex@...ti.fr,
	guoren@...nel.org
Cc: linux-riscv@...ts.infradead.org,
	linux-kernel@...r.kernel.org,
	Chen Pei <cp0613@...ux.alibaba.com>
Subject: [RFC PATCH 3/4] tools: perf: Support perf record with aux buffer for riscv trace

From: Chen Pei <cp0613@...ux.alibaba.com>

This patch implements AUXTRACE support for RISC-V Trace. The
corresponding driver needs to implement the setup_aux and free_aux
PMU driver ops.

The aux buffer is a type of ring buffer used in trace scenarios,
and RISC-V Trace should also reuse this capability.

Signed-off-by: Chen Pei <cp0613@...ux.alibaba.com>
---
 arch/riscv/events/riscv_trace.c          |  61 ++++++++
 arch/riscv/events/riscv_trace.h          |   8 +
 tools/perf/arch/riscv/util/Build         |   3 +
 tools/perf/arch/riscv/util/auxtrace.c    |  33 ++++
 tools/perf/arch/riscv/util/pmu.c         |  18 +++
 tools/perf/arch/riscv/util/riscv-trace.c | 183 +++++++++++++++++++++++
 tools/perf/arch/riscv/util/tsc.c         |  15 ++
 tools/perf/util/Build                    |   1 +
 tools/perf/util/auxtrace.c               |   4 +
 tools/perf/util/auxtrace.h               |   1 +
 tools/perf/util/riscv-trace.c            | 162 ++++++++++++++++++++
 tools/perf/util/riscv-trace.h            |  18 +++
 12 files changed, 507 insertions(+)
 create mode 100644 tools/perf/arch/riscv/util/auxtrace.c
 create mode 100644 tools/perf/arch/riscv/util/pmu.c
 create mode 100644 tools/perf/arch/riscv/util/riscv-trace.c
 create mode 100644 tools/perf/arch/riscv/util/tsc.c
 create mode 100644 tools/perf/util/riscv-trace.c
 create mode 100644 tools/perf/util/riscv-trace.h

diff --git a/arch/riscv/events/riscv_trace.c b/arch/riscv/events/riscv_trace.c
index e408d9a4034a..3ac4a3be5d3e 100644
--- a/arch/riscv/events/riscv_trace.c
+++ b/arch/riscv/events/riscv_trace.c
@@ -8,6 +8,7 @@
 #include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/perf_event.h>
+#include <linux/vmalloc.h>
 
 #include "riscv_trace.h"
 
@@ -81,6 +82,9 @@ static void riscv_trace_event_start(struct perf_event *event, int flags)
 {
 	pr_info("%s:%d on_cpu=%d cpu=%d\n", __func__, __LINE__,
 		event->oncpu, event->cpu);
+	// TODO: Begin aux buffer
+	// struct xuantie_ntrace_aux_buf *buf;
+	// buf = perf_aux_output_begin(&riscv_trace_pmu.handle, event);
 	// TODO: Enable the trace component
 }
 
@@ -89,6 +93,61 @@ static void riscv_trace_event_stop(struct perf_event *event, int flags)
 	pr_info("%s:%d on_cpu=%d cpu=%d\n", __func__, __LINE__,
 		event->oncpu, event->cpu);
 	// TODO: Disable the trace component
+	// TODO: End aux buffer
+	// struct xuantie_ntrace_aux_buf *buf;
+	// buf = perf_get_aux(&riscv_trace_pmu.handle);
+	// Fill aux buffer
+	// perf_aux_output_end(&riscv_trace_pmu.handle, size);
+}
+
+static void *riscv_trace_buffer_setup_aux(struct perf_event *event, void **pages,
+					 int nr_pages, bool overwrite)
+{
+	struct riscv_trace_aux_buf *buf;
+	struct page **pagelist;
+	int i;
+
+	if (overwrite) {
+		pr_warn("Overwrite mode is not supported\n");
+		return NULL;
+	}
+
+	buf = kzalloc(sizeof(*buf), GFP_KERNEL);
+	if (!buf)
+		return NULL;
+
+	pagelist = kcalloc(nr_pages, sizeof(*pagelist), GFP_KERNEL);
+	if (!pagelist)
+		goto err;
+
+	for (i = 0; i < nr_pages; i++)
+		pagelist[i] = virt_to_page(pages[i]);
+
+	buf->base = vmap(pagelist, nr_pages, VM_MAP, PAGE_KERNEL);
+	if (!buf->base) {
+		kfree(pagelist);
+		goto err;
+	}
+
+	buf->nr_pages = nr_pages;
+	buf->length = nr_pages * PAGE_SIZE;
+	buf->pos = 0;
+
+	pr_info("nr_pages=%d length=%d\n", buf->nr_pages, buf->length);
+
+	kfree(pagelist);
+	return buf;
+err:
+	kfree(buf);
+	return NULL;
+}
+
+static void riscv_trace_buffer_free_aux(void *aux)
+{
+	struct riscv_trace_aux_buf *buf = aux;
+
+	vunmap(buf->base);
+	kfree(buf);
 }
 
 static int __init riscv_trace_init(void)
@@ -128,6 +187,8 @@ static int __init riscv_trace_init(void)
 	riscv_trace_pmu.pmu.del          = riscv_trace_event_del;
 	riscv_trace_pmu.pmu.start        = riscv_trace_event_start;
 	riscv_trace_pmu.pmu.stop         = riscv_trace_event_stop;
+	riscv_trace_pmu.pmu.setup_aux    = riscv_trace_buffer_setup_aux;
+	riscv_trace_pmu.pmu.free_aux     = riscv_trace_buffer_free_aux;
 
 	return perf_pmu_register(&riscv_trace_pmu.pmu, "riscv_trace", -1);
 }
diff --git a/arch/riscv/events/riscv_trace.h b/arch/riscv/events/riscv_trace.h
index ef0af0d0b2ee..c28216227006 100644
--- a/arch/riscv/events/riscv_trace.h
+++ b/arch/riscv/events/riscv_trace.h
@@ -75,6 +75,14 @@ extern struct list_head riscv_trace_controllers;
 struct riscv_trace_pmu {
 	struct pmu pmu;
 	struct riscv_trace_filter_attr filter_attr;
+	struct perf_output_handle handle;
+};
+
+struct riscv_trace_aux_buf {
+	u32 length;
+	u32 nr_pages;
+	void *base;
+	u32 pos;
 };
 
 static inline const char *riscv_trace_type2str(enum RISCV_TRACE_COMPONENT_TYPE
diff --git a/tools/perf/arch/riscv/util/Build b/tools/perf/arch/riscv/util/Build
index 58a672246024..d1599b70ef2f 100644
--- a/tools/perf/arch/riscv/util/Build
+++ b/tools/perf/arch/riscv/util/Build
@@ -1,5 +1,8 @@
 perf-util-y += perf_regs.o
 perf-util-y += header.o
+perf-util-y += tsc.o
 
 perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o
 perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
+
+perf-util-$(CONFIG_AUXTRACE) += pmu.o auxtrace.o riscv-trace.o
diff --git a/tools/perf/arch/riscv/util/auxtrace.c b/tools/perf/arch/riscv/util/auxtrace.c
new file mode 100644
index 000000000000..51c8dac5ff61
--- /dev/null
+++ b/tools/perf/arch/riscv/util/auxtrace.c
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <dirent.h>
+#include <stdbool.h>
+#include <linux/zalloc.h>
+#include <api/fs/fs.h>
+
+#include "../../../util/auxtrace.h"
+#include "../../../util/debug.h"
+#include "../../../util/evlist.h"
+#include "../../../util/pmu.h"
+#include "../../../util/pmus.h"
+#include "riscv-trace.h"
+
+struct auxtrace_record
+*auxtrace_record__init(struct evlist *evlist, int *err)
+{
+	struct perf_pmu	*riscv_trace_pmu = NULL;
+	struct evsel *evsel;
+	bool found_riscv_trace = false;
+
+	riscv_trace_pmu = perf_pmus__find(RISCV_TRACE_PMU_NAME);
+
+	evlist__for_each_entry(evlist, evsel) {
+		if (riscv_trace_pmu && evsel->core.attr.type == riscv_trace_pmu->type)
+			found_riscv_trace = true;
+	}
+
+	if (found_riscv_trace)
+		return riscv_trace_recording_init(err, riscv_trace_pmu);
+
+	return NULL;
+}
diff --git a/tools/perf/arch/riscv/util/pmu.c b/tools/perf/arch/riscv/util/pmu.c
new file mode 100644
index 000000000000..921b083c4f6b
--- /dev/null
+++ b/tools/perf/arch/riscv/util/pmu.c
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <string.h>
+#include <linux/perf_event.h>
+#include <linux/string.h>
+
+#include "riscv-trace.h"
+#include "../../../util/pmu.h"
+
+void perf_pmu__arch_init(struct perf_pmu *pmu)
+{
+#ifdef HAVE_AUXTRACE_SUPPORT
+	if (!strcmp(pmu->name, RISCV_TRACE_PMU_NAME)) {
+		pmu->auxtrace = true;
+		pmu->selectable = true;
+	}
+#endif
+}
diff --git a/tools/perf/arch/riscv/util/riscv-trace.c b/tools/perf/arch/riscv/util/riscv-trace.c
new file mode 100644
index 000000000000..0632f1f43c15
--- /dev/null
+++ b/tools/perf/arch/riscv/util/riscv-trace.c
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/bitops.h>
+#include <linux/log2.h>
+#include <linux/zalloc.h>
+#include <time.h>
+
+#include <internal/lib.h> // page_size
+#include "../../../util/auxtrace.h"
+#include "../../../util/cpumap.h"
+#include "../../../util/debug.h"
+#include "../../../util/event.h"
+#include "../../../util/evlist.h"
+#include "../../../util/evsel.h"
+#include "../../../util/pmu.h"
+#include "../../../util/record.h"
+#include "../../../util/session.h"
+#include "../../../util/tsc.h"
+#include "../../../util/riscv-trace.h"
+
+#define KiB(x) ((x) * 1024)
+#define MiB(x) ((x) * 1024 * 1024)
+
+struct riscv_trace_recording {
+	struct auxtrace_record	itr;
+	struct perf_pmu *riscv_trace_pmu;
+	struct evlist *evlist;
+};
+
+static size_t
+riscv_trace_info_priv_size(struct auxtrace_record *itr __maybe_unused,
+			struct evlist *evlist __maybe_unused)
+{
+	return RISCV_TRACE_AUXTRACE_PRIV_SIZE;
+}
+
+static int riscv_trace_info_fill(struct auxtrace_record *itr,
+			      struct perf_session *session,
+			      struct perf_record_auxtrace_info *auxtrace_info,
+			      size_t priv_size)
+{
+	struct riscv_trace_recording *pttr =
+			container_of(itr, struct riscv_trace_recording, itr);
+	struct perf_pmu *riscv_trace_pmu = pttr->riscv_trace_pmu;
+
+	if (priv_size != RISCV_TRACE_AUXTRACE_PRIV_SIZE)
+		return -EINVAL;
+
+	if (!session->evlist->core.nr_mmaps)
+		return -EINVAL;
+
+	auxtrace_info->type = PERF_AUXTRACE_RISCV_TRACE;
+	auxtrace_info->priv[0] = riscv_trace_pmu->type;
+
+	return 0;
+}
+
+static int riscv_trace_set_auxtrace_mmap_page(struct record_opts *opts)
+{
+	bool privileged = perf_event_paranoid_check(-1);
+
+	if (!opts->full_auxtrace)
+		return 0;
+
+	if (opts->full_auxtrace && !opts->auxtrace_mmap_pages) {
+		if (privileged) {
+			opts->auxtrace_mmap_pages = MiB(16) / page_size;
+		} else {
+			opts->auxtrace_mmap_pages = KiB(128) / page_size;
+			if (opts->mmap_pages == UINT_MAX)
+				opts->mmap_pages = KiB(256) / page_size;
+		}
+	}
+
+	/* Validate auxtrace_mmap_pages */
+	if (opts->auxtrace_mmap_pages) {
+		size_t sz = opts->auxtrace_mmap_pages * (size_t)page_size;
+		size_t min_sz = KiB(8);
+
+		if (sz < min_sz || !is_power_of_2(sz)) {
+			pr_err("Invalid mmap size for riscv trace: must be at least %zuKiB and a power of 2\n",
+			       min_sz / 1024);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static int riscv_trace_recording_options(struct auxtrace_record *itr,
+				      struct evlist *evlist,
+				      struct record_opts *opts)
+{
+	struct riscv_trace_recording *pttr =
+			container_of(itr, struct riscv_trace_recording, itr);
+	struct perf_pmu *riscv_trace_pmu = pttr->riscv_trace_pmu;
+	struct evsel *evsel, *riscv_trace_evsel = NULL;
+	struct evsel *tracking_evsel;
+	int err;
+
+	pttr->evlist = evlist;
+	evlist__for_each_entry(evlist, evsel) {
+		if (evsel->core.attr.type == riscv_trace_pmu->type) {
+			if (riscv_trace_evsel) {
+				pr_err("There may be only one " RISCV_TRACE_PMU_NAME "x event\n");
+				return -EINVAL;
+			}
+			evsel->core.attr.freq = 0;
+			evsel->core.attr.sample_period = 1;
+			evsel->needs_auxtrace_mmap = true;
+			riscv_trace_evsel = evsel;
+			opts->full_auxtrace = true;
+		}
+	}
+
+	err = riscv_trace_set_auxtrace_mmap_page(opts);
+	if (err)
+		return err;
+	/*
+	 * To obtain the auxtrace buffer file descriptor, the auxtrace event
+	 * must come first.
+	 */
+	evlist__to_front(evlist, riscv_trace_evsel);
+	evsel__set_sample_bit(riscv_trace_evsel, TIME);
+
+	/* Add dummy event to keep tracking */
+	err = parse_event(evlist, "dummy:u");
+	if (err)
+		return err;
+
+	tracking_evsel = evlist__last(evlist);
+	evlist__set_tracking_event(evlist, tracking_evsel);
+
+	tracking_evsel->core.attr.freq = 0;
+	tracking_evsel->core.attr.sample_period = 1;
+	evsel__set_sample_bit(tracking_evsel, TIME);
+
+	return 0;
+}
+
+static u64 riscv_trace_reference(struct auxtrace_record *itr __maybe_unused)
+{
+	return rdtsc();
+}
+
+static void riscv_trace_recording_free(struct auxtrace_record *itr)
+{
+	struct riscv_trace_recording *pttr =
+			container_of(itr, struct riscv_trace_recording, itr);
+
+	free(pttr);
+}
+
+struct auxtrace_record *riscv_trace_recording_init(int *err,
+						struct perf_pmu *riscv_trace_pmu)
+{
+	struct riscv_trace_recording *pttr;
+
+	if (!riscv_trace_pmu) {
+		*err = -ENODEV;
+		return NULL;
+	}
+
+	pttr = zalloc(sizeof(*pttr));
+	if (!pttr) {
+		*err = -ENOMEM;
+		return NULL;
+	}
+
+	pttr->riscv_trace_pmu = riscv_trace_pmu;
+	pttr->itr.recording_options = riscv_trace_recording_options;
+	pttr->itr.info_priv_size = riscv_trace_info_priv_size;
+	pttr->itr.info_fill = riscv_trace_info_fill;
+	pttr->itr.free = riscv_trace_recording_free;
+	pttr->itr.reference = riscv_trace_reference;
+	pttr->itr.read_finish = auxtrace_record__read_finish;
+	pttr->itr.alignment = 0;
+
+	*err = 0;
+	return &pttr->itr;
+}
diff --git a/tools/perf/arch/riscv/util/tsc.c b/tools/perf/arch/riscv/util/tsc.c
new file mode 100644
index 000000000000..cf021e423f79
--- /dev/null
+++ b/tools/perf/arch/riscv/util/tsc.c
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/types.h>
+
+#include "../../../util/tsc.h"
+
+u64 rdtsc(void)
+{
+	u64 val;
+
+	// https://lore.kernel.org/all/YxIzgYP3MujXdqwj@aurel32.net/T/
+	asm volatile("rdtime %0" : "=r"(val));
+
+	return val;
+}
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 4959e7a990e4..4726a100a156 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -136,6 +136,7 @@ perf-util-$(CONFIG_AUXTRACE) += arm-spe-decoder/
 perf-util-$(CONFIG_AUXTRACE) += hisi-ptt.o
 perf-util-$(CONFIG_AUXTRACE) += hisi-ptt-decoder/
 perf-util-$(CONFIG_AUXTRACE) += s390-cpumsf.o
+perf-util-$(CONFIG_AUXTRACE) += riscv-trace.o
 
 ifdef CONFIG_LIBOPENCSD
 perf-util-$(CONFIG_AUXTRACE) += cs-etm.o
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
index ebd32f1b8f12..b4d8f3c5ebb1 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 "riscv-trace.h"
 #include "util/mmap.h"
 
 #include <linux/ctype.h>
@@ -1393,6 +1394,9 @@ int perf_event__process_auxtrace_info(struct perf_session *session,
 	case PERF_AUXTRACE_HISI_PTT:
 		err = hisi_ptt_process_auxtrace_info(event, session);
 		break;
+	case PERF_AUXTRACE_RISCV_TRACE:
+		err = riscv_trace_process_auxtrace_info(event, session);
+		break;
 	case PERF_AUXTRACE_UNKNOWN:
 	default:
 		return -EINVAL;
diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h
index f001cbb68f8e..5b7ce4a99709 100644
--- a/tools/perf/util/auxtrace.h
+++ b/tools/perf/util/auxtrace.h
@@ -50,6 +50,7 @@ enum auxtrace_type {
 	PERF_AUXTRACE_ARM_SPE,
 	PERF_AUXTRACE_S390_CPUMSF,
 	PERF_AUXTRACE_HISI_PTT,
+	PERF_AUXTRACE_RISCV_TRACE,
 };
 
 enum itrace_period_type {
diff --git a/tools/perf/util/riscv-trace.c b/tools/perf/util/riscv-trace.c
new file mode 100644
index 000000000000..c9bc3f6a7857
--- /dev/null
+++ b/tools/perf/util/riscv-trace.c
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <byteswap.h>
+#include <endian.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <linux/bitops.h>
+#include <linux/kernel.h>
+#include <linux/log2.h>
+#include <linux/types.h>
+#include <linux/zalloc.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "auxtrace.h"
+#include "color.h"
+#include "debug.h"
+#include "evsel.h"
+#include "riscv-trace.h"
+#include "machine.h"
+#include "session.h"
+#include "tool.h"
+#include <internal/lib.h>
+
+struct riscv_trace {
+	struct auxtrace auxtrace;
+	u32 auxtrace_type;
+	struct perf_session *session;
+	struct machine *machine;
+	u32 pmu_type;
+};
+
+static void riscv_trace_dump(struct riscv_trace *trace __maybe_unused,
+			  unsigned char *buf, size_t len)
+{
+
+	const char *color = PERF_COLOR_BLUE;
+
+	color_fprintf(stdout, color, ". ... %s: buf=%p len=%zubytes\n", __func__, buf, len);
+	for (size_t i = 0; i < len; i++)
+		printf("%02x ", buf[i]);
+}
+
+static void riscv_trace_dump_event(struct riscv_trace *trace, unsigned char *buf,
+				size_t len)
+{
+	printf(".\n");
+
+	riscv_trace_dump(trace, buf, len);
+}
+
+static int riscv_trace_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 riscv_trace_process_auxtrace_event(struct perf_session *session,
+					   union perf_event *event,
+					   const struct perf_tool *tool __maybe_unused)
+{
+	struct riscv_trace *trace = container_of(session->auxtrace, struct riscv_trace,
+					    auxtrace);
+	int fd = perf_data__fd(session->data);
+	int size = event->auxtrace.size;
+	void *data = malloc(size);
+	off_t data_offset;
+	int err;
+
+	if (!data)
+		return -errno;
+
+	if (perf_data__is_pipe(session->data)) {
+		data_offset = 0;
+	} else {
+		data_offset = lseek(fd, 0, SEEK_CUR);
+		if (data_offset == -1) {
+			free(data);
+			return -errno;
+		}
+	}
+
+	err = readn(fd, data, size);
+	if (err != (ssize_t)size) {
+		free(data);
+		return -errno;
+	}
+
+	if (dump_trace)
+		riscv_trace_dump_event(trace, data, size);
+
+	free(data);
+	return 0;
+}
+
+static int riscv_trace_flush(struct perf_session *session __maybe_unused,
+			  const struct perf_tool *tool __maybe_unused)
+{
+	return 0;
+}
+
+static void riscv_trace_free_events(struct perf_session *session __maybe_unused)
+{
+}
+
+static void riscv_trace_free(struct perf_session *session)
+{
+	struct riscv_trace *trace = container_of(session->auxtrace, struct riscv_trace,
+					    auxtrace);
+
+	session->auxtrace = NULL;
+	free(trace);
+}
+
+static bool riscv_trace_evsel_is_auxtrace(struct perf_session *session,
+				       struct evsel *evsel)
+{
+	struct riscv_trace *trace = container_of(session->auxtrace, struct riscv_trace, auxtrace);
+
+	return evsel->core.attr.type == trace->pmu_type;
+}
+
+static void riscv_trace_print_info(__u64 type)
+{
+	if (!dump_trace)
+		return;
+
+	fprintf(stdout, "  PMU Type           %" PRId64 "\n", (s64) type);
+}
+
+int riscv_trace_process_auxtrace_info(union perf_event *event,
+				   struct perf_session *session)
+{
+	struct perf_record_auxtrace_info *auxtrace_info = &event->auxtrace_info;
+	struct riscv_trace *trace;
+
+	if (auxtrace_info->header.size < RISCV_TRACE_AUXTRACE_PRIV_SIZE +
+				sizeof(struct perf_record_auxtrace_info))
+		return -EINVAL;
+
+	trace = zalloc(sizeof(*trace));
+	if (!trace)
+		return -ENOMEM;
+
+	trace->session = session;
+	trace->machine = &session->machines.host; /* No kvm support */
+	trace->auxtrace_type = auxtrace_info->type;
+	trace->pmu_type = auxtrace_info->priv[0];
+
+	trace->auxtrace.process_event = riscv_trace_process_event;
+	trace->auxtrace.process_auxtrace_event = riscv_trace_process_auxtrace_event;
+	trace->auxtrace.flush_events = riscv_trace_flush;
+	trace->auxtrace.free_events = riscv_trace_free_events;
+	trace->auxtrace.free = riscv_trace_free;
+	trace->auxtrace.evsel_is_auxtrace = riscv_trace_evsel_is_auxtrace;
+	session->auxtrace = &trace->auxtrace;
+
+	riscv_trace_print_info(auxtrace_info->priv[0]);
+
+	return 0;
+}
diff --git a/tools/perf/util/riscv-trace.h b/tools/perf/util/riscv-trace.h
new file mode 100644
index 000000000000..4901ea323b77
--- /dev/null
+++ b/tools/perf/util/riscv-trace.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef INCLUDE__PERF_RISCV_TRACE_H__
+#define INCLUDE__PERF_RISCV_TRACE_H__
+
+#define RISCV_TRACE_PMU_NAME		"riscv_trace"
+#define RISCV_TRACE_AUXTRACE_PRIV_SIZE	sizeof(u64)
+
+union perf_event;
+struct perf_session;
+struct perf_pmu;
+
+struct auxtrace_record *riscv_trace_recording_init(int *err,
+						struct perf_pmu *riscv_ntrace_pmu);
+
+int riscv_trace_process_auxtrace_info(union perf_event *event,
+				   struct perf_session *session);
+
+#endif
-- 
2.49.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ