1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Arch specific functions for perf kvm stat. 4 * 5 * Copyright 2024 Beijing ESWIN Computing Technology Co., Ltd. 6 * 7 */ 8 #include <errno.h> 9 #include <memory.h> 10 #include "../evsel.h" 11 #include "../kvm-stat.h" 12 #include "riscv_trap_types.h" 13 #include "debug.h" 14 15 define_exit_reasons_table(riscv_exit_reasons, kvm_riscv_trap_class); 16 17 static const char * const __kvm_events_tp[] = { 18 "kvm:kvm_entry", 19 "kvm:kvm_exit", 20 NULL, 21 }; 22 23 static void event_get_key(struct perf_sample *sample, 24 struct event_key *key) 25 { 26 int xlen = 64; // TODO: 32-bit support. 27 28 key->info = 0; 29 key->key = perf_sample__intval(sample, kvm_exit_reason(EM_RISCV)) & ~CAUSE_IRQ_FLAG(xlen); 30 key->exit_reasons = riscv_exit_reasons; 31 } 32 33 static bool event_begin(struct perf_sample *sample, 34 struct event_key *key __maybe_unused) 35 { 36 return evsel__name_is(sample->evsel, kvm_entry_trace(EM_RISCV)); 37 } 38 39 static bool event_end(struct perf_sample *sample, 40 struct event_key *key) 41 { 42 if (evsel__name_is(sample->evsel, kvm_exit_trace(EM_RISCV))) { 43 event_get_key(sample, key); 44 return true; 45 } 46 return false; 47 } 48 49 static const struct kvm_events_ops exit_events = { 50 .is_begin_event = event_begin, 51 .is_end_event = event_end, 52 .decode_key = exit_event_decode_key, 53 .name = "VM-EXIT" 54 }; 55 56 static const struct kvm_reg_events_ops __kvm_reg_events_ops[] = { 57 { 58 .name = "vmexit", 59 .ops = &exit_events, 60 }, 61 { NULL, NULL }, 62 }; 63 64 static const char * const __kvm_skip_events[] = { 65 NULL, 66 }; 67 68 int __cpu_isa_init_riscv(struct perf_kvm_stat *kvm) 69 { 70 kvm->exit_reasons_isa = "riscv64"; 71 return 0; 72 } 73 74 const char * const *__kvm_events_tp_riscv(void) 75 { 76 return __kvm_events_tp; 77 } 78 79 const struct kvm_reg_events_ops *__kvm_reg_events_ops_riscv(void) 80 { 81 return __kvm_reg_events_ops; 82 } 83 84 const char * const *__kvm_skip_events_riscv(void) 85 { 86 return __kvm_skip_events; 87 } 88