1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Based on the x86 implementation. 4 * 5 * Copyright (C) 2012 ARM Ltd. 6 * Author: Marc Zyngier <marc.zyngier@arm.com> 7 */ 8 9 #include <linux/perf_event.h> 10 #include <linux/kvm_host.h> 11 12 #include <asm/kvm_emulate.h> 13 14 DEFINE_STATIC_KEY_FALSE(kvm_arm_pmu_available); 15 kvm_is_in_guest(void)16static int kvm_is_in_guest(void) 17 { 18 return kvm_get_running_vcpu() != NULL; 19 } 20 kvm_is_user_mode(void)21static int kvm_is_user_mode(void) 22 { 23 struct kvm_vcpu *vcpu; 24 25 vcpu = kvm_get_running_vcpu(); 26 27 if (vcpu) 28 return !vcpu_mode_priv(vcpu); 29 30 return 0; 31 } 32 kvm_get_guest_ip(void)33static unsigned long kvm_get_guest_ip(void) 34 { 35 struct kvm_vcpu *vcpu; 36 37 vcpu = kvm_get_running_vcpu(); 38 39 if (vcpu) 40 return *vcpu_pc(vcpu); 41 42 return 0; 43 } 44 45 static struct perf_guest_info_callbacks kvm_guest_cbs = { 46 .is_in_guest = kvm_is_in_guest, 47 .is_user_mode = kvm_is_user_mode, 48 .get_guest_ip = kvm_get_guest_ip, 49 }; 50 kvm_perf_init(void)51int kvm_perf_init(void) 52 { 53 if (kvm_pmu_probe_pmuver() != 0xf && !is_protected_kvm_enabled()) 54 static_branch_enable(&kvm_arm_pmu_available); 55 56 return perf_register_guest_info_callbacks(&kvm_guest_cbs); 57 } 58 kvm_perf_teardown(void)59int kvm_perf_teardown(void) 60 { 61 return perf_unregister_guest_info_callbacks(&kvm_guest_cbs); 62 } 63