~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/perf/arch/loongarch/util/kvm-stat.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 #include <errno.h>
  3 #include <memory.h>
  4 #include "util/kvm-stat.h"
  5 #include "util/parse-events.h"
  6 #include "util/debug.h"
  7 #include "util/evsel.h"
  8 #include "util/evlist.h"
  9 #include "util/pmus.h"
 10 
 11 #define LOONGARCH_EXCEPTION_INT         0
 12 #define LOONGARCH_EXCEPTION_PIL         1
 13 #define LOONGARCH_EXCEPTION_PIS         2
 14 #define LOONGARCH_EXCEPTION_PIF         3
 15 #define LOONGARCH_EXCEPTION_PME         4
 16 #define LOONGARCH_EXCEPTION_FPD         15
 17 #define LOONGARCH_EXCEPTION_SXD         16
 18 #define LOONGARCH_EXCEPTION_ASXD        17
 19 #define LOONGARCH_EXCEPTION_GSPR        22
 20 #define  LOONGARCH_EXCEPTION_CPUCFG     100
 21 #define  LOONGARCH_EXCEPTION_CSR        101
 22 #define  LOONGARCH_EXCEPTION_IOCSR      102
 23 #define  LOONGARCH_EXCEPTION_IDLE       103
 24 #define  LOONGARCH_EXCEPTION_OTHERS     104
 25 #define LOONGARCH_EXCEPTION_HVC         23
 26 
 27 #define loongarch_exception_type                                \
 28         {LOONGARCH_EXCEPTION_INT,  "Interrupt" },               \
 29         {LOONGARCH_EXCEPTION_PIL,  "Mem Read" },                \
 30         {LOONGARCH_EXCEPTION_PIS,  "Mem Store" },               \
 31         {LOONGARCH_EXCEPTION_PIF,  "Inst Fetch" },              \
 32         {LOONGARCH_EXCEPTION_PME,  "Mem Modify" },              \
 33         {LOONGARCH_EXCEPTION_FPD,  "FPU" },                     \
 34         {LOONGARCH_EXCEPTION_SXD,  "LSX" },                     \
 35         {LOONGARCH_EXCEPTION_ASXD, "LASX" },                    \
 36         {LOONGARCH_EXCEPTION_GSPR, "Privilege Error" },         \
 37         {LOONGARCH_EXCEPTION_HVC,  "Hypercall" },               \
 38         {LOONGARCH_EXCEPTION_CPUCFG, "CPUCFG" },                \
 39         {LOONGARCH_EXCEPTION_CSR,    "CSR" },                   \
 40         {LOONGARCH_EXCEPTION_IOCSR,  "IOCSR" },                 \
 41         {LOONGARCH_EXCEPTION_IDLE,   "Idle" },                  \
 42         {LOONGARCH_EXCEPTION_OTHERS, "Others" }
 43 
 44 define_exit_reasons_table(loongarch_exit_reasons, loongarch_exception_type);
 45 
 46 const char *vcpu_id_str = "vcpu_id";
 47 const char *kvm_exit_reason = "reason";
 48 const char *kvm_entry_trace = "kvm:kvm_enter";
 49 const char *kvm_reenter_trace = "kvm:kvm_reenter";
 50 const char *kvm_exit_trace = "kvm:kvm_exit";
 51 const char *kvm_events_tp[] = {
 52         "kvm:kvm_enter",
 53         "kvm:kvm_reenter",
 54         "kvm:kvm_exit",
 55         "kvm:kvm_exit_gspr",
 56         NULL,
 57 };
 58 
 59 static bool event_begin(struct evsel *evsel,
 60                         struct perf_sample *sample, struct event_key *key)
 61 {
 62         return exit_event_begin(evsel, sample, key);
 63 }
 64 
 65 static bool event_end(struct evsel *evsel,
 66                       struct perf_sample *sample __maybe_unused,
 67                       struct event_key *key __maybe_unused)
 68 {
 69         /*
 70          * LoongArch kvm is different with other architectures
 71          *
 72          * There is kvm:kvm_reenter or kvm:kvm_enter event adjacent with
 73          * kvm:kvm_exit event.
 74          *   kvm:kvm_enter   means returning to vmm and then to guest
 75          *   kvm:kvm_reenter means returning to guest immediately
 76          */
 77         return evsel__name_is(evsel, kvm_entry_trace) || evsel__name_is(evsel, kvm_reenter_trace);
 78 }
 79 
 80 static void event_gspr_get_key(struct evsel *evsel,
 81                                struct perf_sample *sample, struct event_key *key)
 82 {
 83         unsigned int insn;
 84 
 85         key->key = LOONGARCH_EXCEPTION_OTHERS;
 86         insn = evsel__intval(evsel, sample, "inst_word");
 87 
 88         switch (insn >> 24) {
 89         case 0:
 90                 /* CPUCFG inst trap */
 91                 if ((insn >> 10) == 0x1b)
 92                         key->key = LOONGARCH_EXCEPTION_CPUCFG;
 93                 break;
 94         case 4:
 95                 /* CSR inst trap */
 96                 key->key = LOONGARCH_EXCEPTION_CSR;
 97                 break;
 98         case 6:
 99                 /* IOCSR inst trap */
100                 if ((insn >> 15) == 0xc90)
101                         key->key = LOONGARCH_EXCEPTION_IOCSR;
102                 else if ((insn >> 15) == 0xc91)
103                         /* Idle inst trap */
104                         key->key = LOONGARCH_EXCEPTION_IDLE;
105                 break;
106         default:
107                 key->key = LOONGARCH_EXCEPTION_OTHERS;
108                 break;
109         }
110 }
111 
112 static struct child_event_ops child_events[] = {
113         { .name = "kvm:kvm_exit_gspr", .get_key = event_gspr_get_key },
114         { NULL, NULL },
115 };
116 
117 static struct kvm_events_ops exit_events = {
118         .is_begin_event = event_begin,
119         .is_end_event = event_end,
120         .child_ops = child_events,
121         .decode_key = exit_event_decode_key,
122         .name = "VM-EXIT"
123 };
124 
125 struct kvm_reg_events_ops kvm_reg_events_ops[] = {
126         { .name = "vmexit", .ops = &exit_events, },
127         { NULL, NULL },
128 };
129 
130 const char * const kvm_skip_events[] = {
131         NULL,
132 };
133 
134 int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid __maybe_unused)
135 {
136         kvm->exit_reasons_isa = "loongarch64";
137         kvm->exit_reasons = loongarch_exit_reasons;
138         return 0;
139 }
140 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php