linux/tools/perf/arch/arm64/util/kvm-stat.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#include <errno.h>
   3#include <memory.h>
   4#include "../../../util/evsel.h"
   5#include "../../../util/kvm-stat.h"
   6#include "arm64_exception_types.h"
   7#include "debug.h"
   8
   9define_exit_reasons_table(arm64_exit_reasons, kvm_arm_exception_type);
  10define_exit_reasons_table(arm64_trap_exit_reasons, kvm_arm_exception_class);
  11
  12const char *kvm_trap_exit_reason = "esr_ec";
  13const char *vcpu_id_str = "id";
  14const int decode_str_len = 20;
  15const char *kvm_exit_reason = "ret";
  16const char *kvm_entry_trace = "kvm:kvm_entry";
  17const char *kvm_exit_trace = "kvm:kvm_exit";
  18
  19const char *kvm_events_tp[] = {
  20        "kvm:kvm_entry",
  21        "kvm:kvm_exit",
  22        NULL,
  23};
  24
  25static void event_get_key(struct evsel *evsel,
  26                          struct perf_sample *sample,
  27                          struct event_key *key)
  28{
  29        key->info = 0;
  30        key->key = evsel__intval(evsel, sample, kvm_exit_reason);
  31        key->exit_reasons = arm64_exit_reasons;
  32
  33        /*
  34         * TRAP exceptions carry exception class info in esr_ec field
  35         * and, hence, we need to use a different exit_reasons table to
  36         * properly decode event's est_ec.
  37         */
  38        if (key->key == ARM_EXCEPTION_TRAP) {
  39                key->key = evsel__intval(evsel, sample, kvm_trap_exit_reason);
  40                key->exit_reasons = arm64_trap_exit_reasons;
  41        }
  42}
  43
  44static bool event_begin(struct evsel *evsel,
  45                        struct perf_sample *sample __maybe_unused,
  46                        struct event_key *key __maybe_unused)
  47{
  48        return !strcmp(evsel->name, kvm_entry_trace);
  49}
  50
  51static bool event_end(struct evsel *evsel,
  52                      struct perf_sample *sample,
  53                      struct event_key *key)
  54{
  55        if (!strcmp(evsel->name, kvm_exit_trace)) {
  56                event_get_key(evsel, sample, key);
  57                return true;
  58        }
  59        return false;
  60}
  61
  62static struct kvm_events_ops exit_events = {
  63        .is_begin_event = event_begin,
  64        .is_end_event   = event_end,
  65        .decode_key     = exit_event_decode_key,
  66        .name           = "VM-EXIT"
  67};
  68
  69struct kvm_reg_events_ops kvm_reg_events_ops[] = {
  70        {
  71                .name   = "vmexit",
  72                .ops    = &exit_events,
  73        },
  74        { NULL, NULL },
  75};
  76
  77const char * const kvm_skip_events[] = {
  78        NULL,
  79};
  80
  81int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid __maybe_unused)
  82{
  83        kvm->exit_reasons_isa = "arm64";
  84        return 0;
  85}
  86