xref: /linux/tools/perf/arch/arm64/util/kvm-stat.c (revision ce1d3bc2)
11218838dSSergey Senozhatsky // SPDX-License-Identifier: GPL-2.0
21218838dSSergey Senozhatsky #include <errno.h>
31218838dSSergey Senozhatsky #include <memory.h>
4b96da02bSIan Rogers #include "../../../util/evsel.h"
5b96da02bSIan Rogers #include "../../../util/kvm-stat.h"
61218838dSSergey Senozhatsky #include "arm64_exception_types.h"
71218838dSSergey Senozhatsky #include "debug.h"
81218838dSSergey Senozhatsky 
91218838dSSergey Senozhatsky define_exit_reasons_table(arm64_exit_reasons, kvm_arm_exception_type);
101218838dSSergey Senozhatsky define_exit_reasons_table(arm64_trap_exit_reasons, kvm_arm_exception_class);
111218838dSSergey Senozhatsky 
121218838dSSergey Senozhatsky const char *kvm_trap_exit_reason = "esr_ec";
131218838dSSergey Senozhatsky const char *vcpu_id_str = "id";
141218838dSSergey Senozhatsky const char *kvm_exit_reason = "ret";
151218838dSSergey Senozhatsky const char *kvm_entry_trace = "kvm:kvm_entry";
161218838dSSergey Senozhatsky const char *kvm_exit_trace = "kvm:kvm_exit";
171218838dSSergey Senozhatsky 
181218838dSSergey Senozhatsky const char *kvm_events_tp[] = {
191218838dSSergey Senozhatsky 	"kvm:kvm_entry",
201218838dSSergey Senozhatsky 	"kvm:kvm_exit",
211218838dSSergey Senozhatsky 	NULL,
221218838dSSergey Senozhatsky };
231218838dSSergey Senozhatsky 
event_get_key(struct evsel * evsel,struct perf_sample * sample,struct event_key * key)241218838dSSergey Senozhatsky static void event_get_key(struct evsel *evsel,
251218838dSSergey Senozhatsky 			  struct perf_sample *sample,
261218838dSSergey Senozhatsky 			  struct event_key *key)
271218838dSSergey Senozhatsky {
281218838dSSergey Senozhatsky 	key->info = 0;
291218838dSSergey Senozhatsky 	key->key = evsel__intval(evsel, sample, kvm_exit_reason);
301218838dSSergey Senozhatsky 	key->exit_reasons = arm64_exit_reasons;
311218838dSSergey Senozhatsky 
321218838dSSergey Senozhatsky 	/*
331218838dSSergey Senozhatsky 	 * TRAP exceptions carry exception class info in esr_ec field
341218838dSSergey Senozhatsky 	 * and, hence, we need to use a different exit_reasons table to
351218838dSSergey Senozhatsky 	 * properly decode event's est_ec.
361218838dSSergey Senozhatsky 	 */
371218838dSSergey Senozhatsky 	if (key->key == ARM_EXCEPTION_TRAP) {
381218838dSSergey Senozhatsky 		key->key = evsel__intval(evsel, sample, kvm_trap_exit_reason);
391218838dSSergey Senozhatsky 		key->exit_reasons = arm64_trap_exit_reasons;
401218838dSSergey Senozhatsky 	}
411218838dSSergey Senozhatsky }
421218838dSSergey Senozhatsky 
event_begin(struct evsel * evsel,struct perf_sample * sample __maybe_unused,struct event_key * key __maybe_unused)431218838dSSergey Senozhatsky static bool event_begin(struct evsel *evsel,
441218838dSSergey Senozhatsky 			struct perf_sample *sample __maybe_unused,
451218838dSSergey Senozhatsky 			struct event_key *key __maybe_unused)
461218838dSSergey Senozhatsky {
47*ce1d3bc2SArnaldo Carvalho de Melo 	return evsel__name_is(evsel, kvm_entry_trace);
481218838dSSergey Senozhatsky }
491218838dSSergey Senozhatsky 
event_end(struct evsel * evsel,struct perf_sample * sample,struct event_key * key)501218838dSSergey Senozhatsky static bool event_end(struct evsel *evsel,
511218838dSSergey Senozhatsky 		      struct perf_sample *sample,
521218838dSSergey Senozhatsky 		      struct event_key *key)
531218838dSSergey Senozhatsky {
54*ce1d3bc2SArnaldo Carvalho de Melo 	if (evsel__name_is(evsel, kvm_exit_trace)) {
551218838dSSergey Senozhatsky 		event_get_key(evsel, sample, key);
561218838dSSergey Senozhatsky 		return true;
571218838dSSergey Senozhatsky 	}
581218838dSSergey Senozhatsky 	return false;
591218838dSSergey Senozhatsky }
601218838dSSergey Senozhatsky 
611218838dSSergey Senozhatsky static struct kvm_events_ops exit_events = {
621218838dSSergey Senozhatsky 	.is_begin_event = event_begin,
631218838dSSergey Senozhatsky 	.is_end_event	= event_end,
641218838dSSergey Senozhatsky 	.decode_key	= exit_event_decode_key,
651218838dSSergey Senozhatsky 	.name		= "VM-EXIT"
661218838dSSergey Senozhatsky };
671218838dSSergey Senozhatsky 
681218838dSSergey Senozhatsky struct kvm_reg_events_ops kvm_reg_events_ops[] = {
691218838dSSergey Senozhatsky 	{
701218838dSSergey Senozhatsky 		.name	= "vmexit",
711218838dSSergey Senozhatsky 		.ops	= &exit_events,
721218838dSSergey Senozhatsky 	},
73a00b7e39SMasami Hiramatsu 	{ NULL, NULL },
741218838dSSergey Senozhatsky };
751218838dSSergey Senozhatsky 
761218838dSSergey Senozhatsky const char * const kvm_skip_events[] = {
771218838dSSergey Senozhatsky 	NULL,
781218838dSSergey Senozhatsky };
791218838dSSergey Senozhatsky 
cpu_isa_init(struct perf_kvm_stat * kvm,const char * cpuid __maybe_unused)801218838dSSergey Senozhatsky int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid __maybe_unused)
811218838dSSergey Senozhatsky {
821218838dSSergey Senozhatsky 	kvm->exit_reasons_isa = "arm64";
831218838dSSergey Senozhatsky 	return 0;
841218838dSSergey Senozhatsky }
85