kvm-stat.c (3016B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Arch specific functions for perf kvm stat. 4 * 5 * Copyright 2014 IBM Corp. 6 * Author(s): Alexander Yarygin <yarygin@linux.vnet.ibm.com> 7 */ 8 9#include <errno.h> 10#include <string.h> 11#include "../../util/kvm-stat.h" 12#include "../../util/evsel.h" 13#include <asm/sie.h> 14 15define_exit_reasons_table(sie_exit_reasons, sie_intercept_code); 16define_exit_reasons_table(sie_icpt_insn_codes, icpt_insn_codes); 17define_exit_reasons_table(sie_sigp_order_codes, sigp_order_codes); 18define_exit_reasons_table(sie_diagnose_codes, diagnose_codes); 19define_exit_reasons_table(sie_icpt_prog_codes, icpt_prog_codes); 20 21const char *vcpu_id_str = "id"; 22const int decode_str_len = 40; 23const char *kvm_exit_reason = "icptcode"; 24const char *kvm_entry_trace = "kvm:kvm_s390_sie_enter"; 25const char *kvm_exit_trace = "kvm:kvm_s390_sie_exit"; 26 27static void event_icpt_insn_get_key(struct evsel *evsel, 28 struct perf_sample *sample, 29 struct event_key *key) 30{ 31 unsigned long insn; 32 33 insn = evsel__intval(evsel, sample, "instruction"); 34 key->key = icpt_insn_decoder(insn); 35 key->exit_reasons = sie_icpt_insn_codes; 36} 37 38static void event_sigp_get_key(struct evsel *evsel, 39 struct perf_sample *sample, 40 struct event_key *key) 41{ 42 key->key = evsel__intval(evsel, sample, "order_code"); 43 key->exit_reasons = sie_sigp_order_codes; 44} 45 46static void event_diag_get_key(struct evsel *evsel, 47 struct perf_sample *sample, 48 struct event_key *key) 49{ 50 key->key = evsel__intval(evsel, sample, "code"); 51 key->exit_reasons = sie_diagnose_codes; 52} 53 54static void event_icpt_prog_get_key(struct evsel *evsel, 55 struct perf_sample *sample, 56 struct event_key *key) 57{ 58 key->key = evsel__intval(evsel, sample, "code"); 59 key->exit_reasons = sie_icpt_prog_codes; 60} 61 62static struct child_event_ops child_events[] = { 63 { .name = "kvm:kvm_s390_intercept_instruction", 64 .get_key = event_icpt_insn_get_key }, 65 { .name = "kvm:kvm_s390_handle_sigp", 66 .get_key = event_sigp_get_key }, 67 { .name = "kvm:kvm_s390_handle_diag", 68 .get_key = event_diag_get_key }, 69 { .name = "kvm:kvm_s390_intercept_prog", 70 .get_key = event_icpt_prog_get_key }, 71 { NULL, NULL }, 72}; 73 74static struct kvm_events_ops exit_events = { 75 .is_begin_event = exit_event_begin, 76 .is_end_event = exit_event_end, 77 .child_ops = child_events, 78 .decode_key = exit_event_decode_key, 79 .name = "VM-EXIT" 80}; 81 82const char *kvm_events_tp[] = { 83 "kvm:kvm_s390_sie_enter", 84 "kvm:kvm_s390_sie_exit", 85 "kvm:kvm_s390_intercept_instruction", 86 "kvm:kvm_s390_handle_sigp", 87 "kvm:kvm_s390_handle_diag", 88 "kvm:kvm_s390_intercept_prog", 89 NULL, 90}; 91 92struct kvm_reg_events_ops kvm_reg_events_ops[] = { 93 { .name = "vmexit", .ops = &exit_events }, 94 { NULL, NULL }, 95}; 96 97const char * const kvm_skip_events[] = { 98 "Wait state", 99 NULL, 100}; 101 102int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid) 103{ 104 if (strstr(cpuid, "IBM")) { 105 kvm->exit_reasons = sie_exit_reasons; 106 kvm->exit_reasons_isa = "SIE"; 107 } else 108 return -ENOTSUP; 109 110 return 0; 111}