[PATCH v4 11/12] perf tools: Initial support for RISC-V trace decoder

Adrian Hunter adrian.hunter at intel.com
Wed May 20 04:32:15 PDT 2026


On 29/04/2026 15:51, Anup Patel wrote:
> From: Mayuresh Chitale <mayuresh.chitale at oss.qualcomm.com>
> 
> Add bare bones support for RISC-V trace decoder so that the data received
> from the hardware by the RISC-V trace perf driver can be written to the
> perf record output file.
> 
> Co-developed-by: Anup Patel <anup.patel at oss.qualcomm.com>
> Signed-off-by: Anup Patel <anup.patel at oss.qualcomm.com>
> Signed-off-by: Mayuresh Chitale <mayuresh.chitale at oss.qualcomm.com>

Reviewed-by: Adrian Hunter <adrian.hunter at intel.com>

> ---
>  tools/perf/util/Build             |  1 +
>  tools/perf/util/auxtrace.c        |  3 +
>  tools/perf/util/rvtrace-decoder.c | 91 +++++++++++++++++++++++++++++++
>  tools/perf/util/rvtrace.h         |  1 +
>  4 files changed, 96 insertions(+)
>  create mode 100644 tools/perf/util/rvtrace-decoder.c
> 
> diff --git a/tools/perf/util/Build b/tools/perf/util/Build
> index 70cc91d00804..1cd1491f93c8 100644
> --- a/tools/perf/util/Build
> +++ b/tools/perf/util/Build
> @@ -147,6 +147,7 @@ perf-util-y += cs-etm.o
>  perf-util-y += cs-etm-decoder/
>  endif
>  perf-util-y += cs-etm-base.o
> +perf-util-y += rvtrace-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 944a43d48739..c6bd6642ce05 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 "rvtrace.h"
>  #include "util/mmap.h"
>  #include "powerpc-vpadtl.h"
>  
> @@ -1412,6 +1413,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_RISCV_TRACE:
> +		err = rvtrace__process_auxtrace_info(event, session);
> +		break;
>  	case PERF_AUXTRACE_UNKNOWN:
>  	default:
>  		return -EINVAL;
> diff --git a/tools/perf/util/rvtrace-decoder.c b/tools/perf/util/rvtrace-decoder.c
> new file mode 100644
> index 000000000000..58db5ca62c1a
> --- /dev/null
> +++ b/tools/perf/util/rvtrace-decoder.c
> @@ -0,0 +1,91 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * RISC-V trace Decoder
> + */
> +
> +#include <errno.h>
> +#include <inttypes.h>
> +#include "evlist.h"
> +#include <internal/lib.h>
> +#include "rvtrace.h"
> +
> +struct rvtrace_decoder {
> +	struct auxtrace auxtrace;
> +	u32 auxtrace_type;
> +	struct perf_session *session;
> +	struct machine *machine;
> +	u32 pmu_type;
> +};
> +
> +static int rvtrace_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 rvtrace_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 rvtrace_flush(struct perf_session *session __maybe_unused,
> +			 const struct perf_tool *tool __maybe_unused)
> +{
> +	return 0;
> +}
> +
> +static void rvtrace_free_events(struct perf_session *session __maybe_unused)
> +{
> +}
> +
> +static void rvtrace_free(struct perf_session *session)
> +{
> +	struct rvtrace_decoder *ptr = container_of(session->auxtrace, struct rvtrace_decoder,
> +					    auxtrace);
> +
> +	session->auxtrace = NULL;
> +	free(ptr);
> +}
> +
> +static bool rvtrace_evsel_is_auxtrace(struct perf_session *session,
> +				      struct evsel *evsel)
> +{
> +	struct rvtrace_decoder *ptr = container_of(session->auxtrace,
> +						   struct rvtrace_decoder, auxtrace);
> +
> +	return evsel->core.attr.type == ptr->pmu_type;
> +}
> +
> +int rvtrace__process_auxtrace_info(union perf_event *event,
> +				   struct perf_session *session)
> +{
> +	struct perf_record_auxtrace_info *auxtrace_info = &event->auxtrace_info;
> +	struct rvtrace_decoder *ptr;
> +
> +	if (auxtrace_info->header.size < RVTRACE_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 = rvtrace_process_event;
> +	ptr->auxtrace.process_auxtrace_event = rvtrace_process_auxtrace_event;
> +	ptr->auxtrace.flush_events = rvtrace_flush;
> +	ptr->auxtrace.free_events = rvtrace_free_events;
> +	ptr->auxtrace.free = rvtrace_free;
> +	ptr->auxtrace.evsel_is_auxtrace = rvtrace_evsel_is_auxtrace;
> +	session->auxtrace = &ptr->auxtrace;
> +
> +	return 0;
> +}
> diff --git a/tools/perf/util/rvtrace.h b/tools/perf/util/rvtrace.h
> index 24b32947fb4c..8e3eb4d681a7 100644
> --- a/tools/perf/util/rvtrace.h
> +++ b/tools/perf/util/rvtrace.h
> @@ -15,4 +15,5 @@
>  
>  #define RVTRACE_AUXTRACE_PRIV_SIZE	sizeof(u64)
>  
> +int rvtrace__process_auxtrace_info(union perf_event *event, struct perf_session *session);
>  #endif




More information about the linux-riscv mailing list