xref: /linux/tools/perf/util/kvm-stat-arch/kvm-stat-riscv.c (revision c7decec2f2d2ab0366567f9e30c0e1418cece43f)
1ceea279fSIan Rogers // SPDX-License-Identifier: GPL-2.0
2ceea279fSIan Rogers /*
3ceea279fSIan Rogers  * Arch specific functions for perf kvm stat.
4ceea279fSIan Rogers  *
5ceea279fSIan Rogers  * Copyright 2024 Beijing ESWIN Computing Technology Co., Ltd.
6ceea279fSIan Rogers  *
7ceea279fSIan Rogers  */
8ceea279fSIan Rogers #include <errno.h>
9ceea279fSIan Rogers #include <memory.h>
10ceea279fSIan Rogers #include "../evsel.h"
11ceea279fSIan Rogers #include "../kvm-stat.h"
12ceea279fSIan Rogers #include "riscv_trap_types.h"
13ceea279fSIan Rogers #include "debug.h"
14ceea279fSIan Rogers 
15ceea279fSIan Rogers define_exit_reasons_table(riscv_exit_reasons, kvm_riscv_trap_class);
16ceea279fSIan Rogers 
17ceea279fSIan Rogers static const char * const __kvm_events_tp[] = {
18ceea279fSIan Rogers 	"kvm:kvm_entry",
19ceea279fSIan Rogers 	"kvm:kvm_exit",
20ceea279fSIan Rogers 	NULL,
21ceea279fSIan Rogers };
22ceea279fSIan Rogers 
event_get_key(struct evsel * evsel,struct perf_sample * sample,struct event_key * key)23ceea279fSIan Rogers static void event_get_key(struct evsel *evsel,
24ceea279fSIan Rogers 			  struct perf_sample *sample,
25ceea279fSIan Rogers 			  struct event_key *key)
26ceea279fSIan Rogers {
27ceea279fSIan Rogers 	int xlen = 64; // TODO: 32-bit support.
28ceea279fSIan Rogers 
29ceea279fSIan Rogers 	key->info = 0;
30*43af5484SIan Rogers 	key->key = evsel__intval(evsel, sample, kvm_exit_reason(EM_RISCV)) & ~CAUSE_IRQ_FLAG(xlen);
31ceea279fSIan Rogers 	key->exit_reasons = riscv_exit_reasons;
32ceea279fSIan Rogers }
33ceea279fSIan Rogers 
event_begin(struct evsel * evsel,struct perf_sample * sample __maybe_unused,struct event_key * key __maybe_unused)34ceea279fSIan Rogers static bool event_begin(struct evsel *evsel,
35ceea279fSIan Rogers 			struct perf_sample *sample __maybe_unused,
36ceea279fSIan Rogers 			struct event_key *key __maybe_unused)
37ceea279fSIan Rogers {
38*43af5484SIan Rogers 	return evsel__name_is(evsel, kvm_entry_trace(EM_RISCV));
39ceea279fSIan Rogers }
40ceea279fSIan Rogers 
event_end(struct evsel * evsel,struct perf_sample * sample,struct event_key * key)41ceea279fSIan Rogers static bool event_end(struct evsel *evsel,
42ceea279fSIan Rogers 		      struct perf_sample *sample,
43ceea279fSIan Rogers 		      struct event_key *key)
44ceea279fSIan Rogers {
45*43af5484SIan Rogers 	if (evsel__name_is(evsel, kvm_exit_trace(EM_RISCV))) {
46ceea279fSIan Rogers 		event_get_key(evsel, sample, key);
47ceea279fSIan Rogers 		return true;
48ceea279fSIan Rogers 	}
49ceea279fSIan Rogers 	return false;
50ceea279fSIan Rogers }
51ceea279fSIan Rogers 
52ceea279fSIan Rogers static const struct kvm_events_ops exit_events = {
53ceea279fSIan Rogers 	.is_begin_event = event_begin,
54ceea279fSIan Rogers 	.is_end_event	= event_end,
55ceea279fSIan Rogers 	.decode_key	= exit_event_decode_key,
56ceea279fSIan Rogers 	.name		= "VM-EXIT"
57ceea279fSIan Rogers };
58ceea279fSIan Rogers 
59ceea279fSIan Rogers static const struct kvm_reg_events_ops __kvm_reg_events_ops[] = {
60ceea279fSIan Rogers 	{
61ceea279fSIan Rogers 		.name	= "vmexit",
62ceea279fSIan Rogers 		.ops	= &exit_events,
63ceea279fSIan Rogers 	},
64ceea279fSIan Rogers 	{ NULL, NULL },
65ceea279fSIan Rogers };
66ceea279fSIan Rogers 
67ceea279fSIan Rogers static const char * const __kvm_skip_events[] = {
68ceea279fSIan Rogers 	NULL,
69ceea279fSIan Rogers };
70ceea279fSIan Rogers 
__cpu_isa_init_riscv(struct perf_kvm_stat * kvm)71ceea279fSIan Rogers int __cpu_isa_init_riscv(struct perf_kvm_stat *kvm)
72ceea279fSIan Rogers {
73ceea279fSIan Rogers 	kvm->exit_reasons_isa = "riscv64";
74ceea279fSIan Rogers 	return 0;
75ceea279fSIan Rogers }
76ceea279fSIan Rogers 
__kvm_events_tp_riscv(void)77ceea279fSIan Rogers const char * const *__kvm_events_tp_riscv(void)
78ceea279fSIan Rogers {
79ceea279fSIan Rogers 	return __kvm_events_tp;
80ceea279fSIan Rogers }
81ceea279fSIan Rogers 
__kvm_reg_events_ops_riscv(void)82ceea279fSIan Rogers const struct kvm_reg_events_ops *__kvm_reg_events_ops_riscv(void)
83ceea279fSIan Rogers {
84ceea279fSIan Rogers 	return __kvm_reg_events_ops;
85ceea279fSIan Rogers }
86ceea279fSIan Rogers 
__kvm_skip_events_riscv(void)87ceea279fSIan Rogers const char * const *__kvm_skip_events_riscv(void)
88ceea279fSIan Rogers {
89ceea279fSIan Rogers 	return __kvm_skip_events;
90ceea279fSIan Rogers }
91