| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 |
- // SPDX-License-Identifier: GPL-2.0
- #include "debug.h"
- #include "evsel.h"
- #include "kvm-stat.h"
- #include <dwarf-regs.h>
- bool kvm_exit_event(struct evsel *evsel)
- {
- uint16_t e_machine = evsel__e_machine(evsel, /*e_flags=*/NULL);
- return evsel__name_is(evsel, kvm_exit_trace(e_machine));
- }
- void exit_event_get_key(struct evsel *evsel,
- struct perf_sample *sample,
- struct event_key *key)
- {
- uint16_t e_machine = evsel__e_machine(evsel, /*e_flags=*/NULL);
- key->info = 0;
- key->key = evsel__intval(evsel, sample, kvm_exit_reason(e_machine));
- }
- bool exit_event_begin(struct evsel *evsel,
- struct perf_sample *sample, struct event_key *key)
- {
- if (kvm_exit_event(evsel)) {
- exit_event_get_key(evsel, sample, key);
- return true;
- }
- return false;
- }
- bool kvm_entry_event(struct evsel *evsel)
- {
- uint16_t e_machine = evsel__e_machine(evsel, /*e_flags=*/NULL);
- return evsel__name_is(evsel, kvm_entry_trace(e_machine));
- }
- bool exit_event_end(struct evsel *evsel,
- struct perf_sample *sample __maybe_unused,
- struct event_key *key __maybe_unused)
- {
- return kvm_entry_event(evsel);
- }
- static const char *get_exit_reason(struct perf_kvm_stat *kvm,
- struct exit_reasons_table *tbl,
- u64 exit_code)
- {
- while (tbl->reason != NULL) {
- if (tbl->exit_code == exit_code)
- return tbl->reason;
- tbl++;
- }
- pr_err("unknown kvm exit code:%lld on %s\n",
- (unsigned long long)exit_code, kvm->exit_reasons_isa);
- return "UNKNOWN";
- }
- void exit_event_decode_key(struct perf_kvm_stat *kvm,
- struct event_key *key,
- char *decode)
- {
- const char *exit_reason = get_exit_reason(kvm, key->exit_reasons,
- key->key);
- scnprintf(decode, KVM_EVENT_NAME_LEN, "%s", exit_reason);
- }
- int setup_kvm_events_tp(struct perf_kvm_stat *kvm, uint16_t e_machine)
- {
- switch (e_machine) {
- case EM_PPC:
- case EM_PPC64:
- return __setup_kvm_events_tp_powerpc(kvm);
- default:
- return 0;
- }
- }
- int cpu_isa_init(struct perf_kvm_stat *kvm, uint16_t e_machine, const char *cpuid)
- {
- switch (e_machine) {
- case EM_AARCH64:
- return __cpu_isa_init_arm64(kvm);
- case EM_LOONGARCH:
- return __cpu_isa_init_loongarch(kvm);
- case EM_PPC:
- case EM_PPC64:
- return __cpu_isa_init_powerpc(kvm);
- case EM_RISCV:
- return __cpu_isa_init_riscv(kvm);
- case EM_S390:
- return __cpu_isa_init_s390(kvm, cpuid);
- case EM_X86_64:
- case EM_386:
- return __cpu_isa_init_x86(kvm, cpuid);
- default:
- pr_err("Unsupported kvm-stat host %d\n", e_machine);
- return -1;
- }
- }
- const char *vcpu_id_str(uint16_t e_machine)
- {
- switch (e_machine) {
- case EM_AARCH64:
- case EM_RISCV:
- case EM_S390:
- return "id";
- case EM_LOONGARCH:
- case EM_PPC:
- case EM_PPC64:
- case EM_X86_64:
- case EM_386:
- return "vcpu_id";
- default:
- pr_err("Unsupported kvm-stat host %d\n", e_machine);
- return NULL;
- }
- }
- const char *kvm_exit_reason(uint16_t e_machine)
- {
- switch (e_machine) {
- case EM_AARCH64:
- return "ret";
- case EM_LOONGARCH:
- return "reason";
- case EM_PPC:
- case EM_PPC64:
- return "trap";
- case EM_RISCV:
- return "scause";
- case EM_S390:
- return "icptcode";
- case EM_X86_64:
- case EM_386:
- return "exit_reason";
- default:
- pr_err("Unsupported kvm-stat host %d\n", e_machine);
- return NULL;
- }
- }
- const char *kvm_entry_trace(uint16_t e_machine)
- {
- switch (e_machine) {
- case EM_AARCH64:
- case EM_RISCV:
- case EM_X86_64:
- case EM_386:
- return "kvm:kvm_entry";
- case EM_LOONGARCH:
- return "kvm:kvm_enter";
- case EM_PPC:
- case EM_PPC64:
- return "kvm_hv:kvm_guest_enter";
- case EM_S390:
- return "kvm:kvm_s390_sie_enter";
- default:
- pr_err("Unsupported kvm-stat host %d\n", e_machine);
- return NULL;
- }
- }
- const char *kvm_exit_trace(uint16_t e_machine)
- {
- switch (e_machine) {
- case EM_AARCH64:
- case EM_LOONGARCH:
- case EM_RISCV:
- case EM_X86_64:
- case EM_386:
- return "kvm:kvm_exit";
- case EM_PPC:
- case EM_PPC64:
- return "kvm_hv:kvm_guest_exit";
- case EM_S390:
- return "kvm:kvm_s390_sie_exit";
- default:
- pr_err("Unsupported kvm-stat host %d\n", e_machine);
- return NULL;
- }
- }
- const char * const *kvm_events_tp(uint16_t e_machine)
- {
- switch (e_machine) {
- case EM_AARCH64:
- return __kvm_events_tp_arm64();
- case EM_LOONGARCH:
- return __kvm_events_tp_loongarch();
- case EM_PPC:
- case EM_PPC64:
- return __kvm_events_tp_powerpc();
- case EM_RISCV:
- return __kvm_events_tp_riscv();
- case EM_S390:
- return __kvm_events_tp_s390();
- case EM_X86_64:
- case EM_386:
- return __kvm_events_tp_x86();
- default:
- pr_err("Unsupported kvm-stat host %d\n", e_machine);
- return NULL;
- }
- }
- const struct kvm_reg_events_ops *kvm_reg_events_ops(uint16_t e_machine)
- {
- switch (e_machine) {
- case EM_AARCH64:
- return __kvm_reg_events_ops_arm64();
- case EM_LOONGARCH:
- return __kvm_reg_events_ops_loongarch();
- case EM_PPC:
- case EM_PPC64:
- return __kvm_reg_events_ops_powerpc();
- case EM_RISCV:
- return __kvm_reg_events_ops_riscv();
- case EM_S390:
- return __kvm_reg_events_ops_s390();
- case EM_X86_64:
- case EM_386:
- return __kvm_reg_events_ops_x86();
- default:
- pr_err("Unsupported kvm-stat host %d\n", e_machine);
- return NULL;
- }
- }
- const char * const *kvm_skip_events(uint16_t e_machine)
- {
- switch (e_machine) {
- case EM_AARCH64:
- return __kvm_skip_events_arm64();
- case EM_LOONGARCH:
- return __kvm_skip_events_loongarch();
- case EM_PPC:
- case EM_PPC64:
- return __kvm_skip_events_powerpc();
- case EM_RISCV:
- return __kvm_skip_events_riscv();
- case EM_S390:
- return __kvm_skip_events_s390();
- case EM_X86_64:
- case EM_386:
- return __kvm_skip_events_x86();
- default:
- pr_err("Unsupported kvm-stat host %d\n", e_machine);
- return NULL;
- }
- }
- int kvm_add_default_arch_event(uint16_t e_machine, int *argc, const char **argv)
- {
- switch (e_machine) {
- case EM_PPC:
- case EM_PPC64:
- return __kvm_add_default_arch_event_powerpc(argc, argv);
- case EM_X86_64:
- case EM_386:
- return __kvm_add_default_arch_event_x86(argc, argv);
- default:
- return 0;
- }
- }
|