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