hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/tools/perf/arch/powerpc/util/kvm-stat.c
....@@ -3,9 +3,13 @@
33 #include "util/kvm-stat.h"
44 #include "util/parse-events.h"
55 #include "util/debug.h"
6
+#include "util/evsel.h"
7
+#include "util/evlist.h"
8
+#include "util/pmu.h"
69
710 #include "book3s_hv_exits.h"
811 #include "book3s_hcalls.h"
12
+#include <subcmd/parse-options.h>
913
1014 #define NR_TPS 4
1115
....@@ -30,12 +34,12 @@
3034 const char *kvm_events_tp[NR_TPS + 1];
3135 const char *kvm_exit_reason;
3236
33
-static void hcall_event_get_key(struct perf_evsel *evsel,
37
+static void hcall_event_get_key(struct evsel *evsel,
3438 struct perf_sample *sample,
3539 struct event_key *key)
3640 {
3741 key->info = 0;
38
- key->key = perf_evsel__intval(evsel, sample, "req");
42
+ key->key = evsel__intval(evsel, sample, "req");
3943 }
4044
4145 static const char *get_hcall_exit_reason(u64 exit_code)
....@@ -53,14 +57,14 @@
5357 return "UNKNOWN";
5458 }
5559
56
-static bool hcall_event_end(struct perf_evsel *evsel,
60
+static bool hcall_event_end(struct evsel *evsel,
5761 struct perf_sample *sample __maybe_unused,
5862 struct event_key *key __maybe_unused)
5963 {
6064 return (!strcmp(evsel->name, kvm_events_tp[3]));
6165 }
6266
63
-static bool hcall_event_begin(struct perf_evsel *evsel,
67
+static bool hcall_event_begin(struct evsel *evsel,
6468 struct perf_sample *sample, struct event_key *key)
6569 {
6670 if (!strcmp(evsel->name, kvm_events_tp[2])) {
....@@ -104,20 +108,20 @@
104108 };
105109
106110
107
-static int is_tracepoint_available(const char *str, struct perf_evlist *evlist)
111
+static int is_tracepoint_available(const char *str, struct evlist *evlist)
108112 {
109113 struct parse_events_error err;
110114 int ret;
111115
112
- err.str = NULL;
116
+ bzero(&err, sizeof(err));
113117 ret = parse_events(evlist, str, &err);
114118 if (err.str)
115
- pr_err("%s : %s\n", str, err.str);
119
+ parse_events_print_error(&err, "tracepoint");
116120 return ret;
117121 }
118122
119123 static int ppc__setup_book3s_hv(struct perf_kvm_stat *kvm,
120
- struct perf_evlist *evlist)
124
+ struct evlist *evlist)
121125 {
122126 const char **events_ptr;
123127 int i, nr_tp = 0, err = -1;
....@@ -144,7 +148,7 @@
144148 /* Wrapper to setup kvm tracepoints */
145149 static int ppc__setup_kvm_tp(struct perf_kvm_stat *kvm)
146150 {
147
- struct perf_evlist *evlist = perf_evlist__new();
151
+ struct evlist *evlist = evlist__new();
148152
149153 if (evlist == NULL)
150154 return -ENOMEM;
....@@ -170,3 +174,46 @@
170174
171175 return ret;
172176 }
177
+
178
+/*
179
+ * Incase of powerpc architecture, pmu registers are programmable
180
+ * by guest kernel. So monitoring guest via host may not provide
181
+ * valid samples with default 'cycles' event. It is better to use
182
+ * 'trace_imc/trace_cycles' event for guest profiling, since it
183
+ * can track the guest instruction pointer in the trace-record.
184
+ *
185
+ * Function to parse the arguments and return appropriate values.
186
+ */
187
+int kvm_add_default_arch_event(int *argc, const char **argv)
188
+{
189
+ const char **tmp;
190
+ bool event = false;
191
+ int i, j = *argc;
192
+
193
+ const struct option event_options[] = {
194
+ OPT_BOOLEAN('e', "event", &event, NULL),
195
+ OPT_END()
196
+ };
197
+
198
+ tmp = calloc(j + 1, sizeof(char *));
199
+ if (!tmp)
200
+ return -EINVAL;
201
+
202
+ for (i = 0; i < j; i++)
203
+ tmp[i] = argv[i];
204
+
205
+ parse_options(j, tmp, event_options, NULL, PARSE_OPT_KEEP_UNKNOWN);
206
+ if (!event) {
207
+ if (pmu_have_event("trace_imc", "trace_cycles")) {
208
+ argv[j++] = strdup("-e");
209
+ argv[j++] = strdup("trace_imc/trace_cycles/");
210
+ *argc += 2;
211
+ } else {
212
+ free(tmp);
213
+ return -EINVAL;
214
+ }
215
+ }
216
+
217
+ free(tmp);
218
+ return 0;
219
+}