1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __PERF_KVM_STAT_H
3 #define __PERF_KVM_STAT_H
4 
5 #ifdef HAVE_KVM_STAT_SUPPORT
6 
7 #include "tool.h"
8 #include "stat.h"
9 #include "record.h"
10 
11 struct evsel;
12 struct evlist;
13 struct perf_session;
14 
15 struct event_key {
16 	#define INVALID_KEY     (~0ULL)
17 	u64 key;
18 	int info;
19 	struct exit_reasons_table *exit_reasons;
20 };
21 
22 struct kvm_event_stats {
23 	u64 time;
24 	struct stats stats;
25 };
26 
27 struct kvm_event {
28 	struct list_head hash_entry;
29 	struct rb_node rb;
30 
31 	struct event_key key;
32 
33 	struct kvm_event_stats total;
34 
35 	#define DEFAULT_VCPU_NUM 8
36 	int max_vcpu;
37 	struct kvm_event_stats *vcpu;
38 };
39 
40 typedef int (*key_cmp_fun)(struct kvm_event*, struct kvm_event*, int);
41 
42 struct kvm_event_key {
43 	const char *name;
44 	key_cmp_fun key;
45 };
46 
47 struct perf_kvm_stat;
48 
49 struct child_event_ops {
50 	void (*get_key)(struct evsel *evsel,
51 			struct perf_sample *sample,
52 			struct event_key *key);
53 	const char *name;
54 };
55 
56 struct kvm_events_ops {
57 	bool (*is_begin_event)(struct evsel *evsel,
58 			       struct perf_sample *sample,
59 			       struct event_key *key);
60 	bool (*is_end_event)(struct evsel *evsel,
61 			     struct perf_sample *sample, struct event_key *key);
62 	struct child_event_ops *child_ops;
63 	void (*decode_key)(struct perf_kvm_stat *kvm, struct event_key *key,
64 			   char *decode);
65 	const char *name;
66 };
67 
68 struct exit_reasons_table {
69 	unsigned long exit_code;
70 	const char *reason;
71 };
72 
73 #define EVENTS_BITS		12
74 #define EVENTS_CACHE_SIZE	(1UL << EVENTS_BITS)
75 
76 struct perf_kvm_stat {
77 	struct perf_tool    tool;
78 	struct record_opts  opts;
79 	struct evlist  *evlist;
80 	struct perf_session *session;
81 
82 	const char *file_name;
83 	const char *report_event;
84 	const char *sort_key;
85 	int trace_vcpu;
86 
87 	struct exit_reasons_table *exit_reasons;
88 	const char *exit_reasons_isa;
89 
90 	struct kvm_events_ops *events_ops;
91 	key_cmp_fun compare;
92 	struct list_head kvm_events_cache[EVENTS_CACHE_SIZE];
93 
94 	u64 total_time;
95 	u64 total_count;
96 	u64 lost_events;
97 	u64 duration;
98 
99 	struct intlist *pid_list;
100 
101 	struct rb_root result;
102 
103 	int timerfd;
104 	unsigned int display_time;
105 	bool live;
106 	bool force;
107 };
108 
109 struct kvm_reg_events_ops {
110 	const char *name;
111 	struct kvm_events_ops *ops;
112 };
113 
114 void exit_event_get_key(struct evsel *evsel,
115 			struct perf_sample *sample,
116 			struct event_key *key);
117 bool exit_event_begin(struct evsel *evsel,
118 		      struct perf_sample *sample,
119 		      struct event_key *key);
120 bool exit_event_end(struct evsel *evsel,
121 		    struct perf_sample *sample,
122 		    struct event_key *key);
123 void exit_event_decode_key(struct perf_kvm_stat *kvm,
124 			   struct event_key *key,
125 			   char *decode);
126 
127 bool kvm_exit_event(struct evsel *evsel);
128 bool kvm_entry_event(struct evsel *evsel);
129 int setup_kvm_events_tp(struct perf_kvm_stat *kvm);
130 
131 #define define_exit_reasons_table(name, symbols)	\
132 	static struct exit_reasons_table name[] = {	\
133 		symbols, { -1, NULL }			\
134 	}
135 
136 /*
137  * arch specific callbacks and data structures
138  */
139 int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid);
140 
141 extern const char *kvm_events_tp[];
142 extern struct kvm_reg_events_ops kvm_reg_events_ops[];
143 extern const char * const kvm_skip_events[];
144 extern const char *vcpu_id_str;
145 extern const int decode_str_len;
146 extern const char *kvm_exit_reason;
147 extern const char *kvm_entry_trace;
148 extern const char *kvm_exit_trace;
149 #endif /* HAVE_KVM_STAT_SUPPORT */
150 
151 extern int kvm_add_default_arch_event(int *argc, const char **argv);
152 #endif /* __PERF_KVM_STAT_H */
153