Merge branch 'misc.namei' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[linux-2.6-microblaze.git] / arch / arm64 / kvm / perf.c
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
16 static int kvm_is_in_guest(void)
17 {
18         return kvm_get_running_vcpu() != NULL;
19 }
20
21 static 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
33 static 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
51 int kvm_perf_init(void)
52 {
53         if (kvm_pmu_probe_pmuver() != ID_AA64DFR0_PMUVER_IMP_DEF && !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
59 int kvm_perf_teardown(void)
60 {
61         return perf_unregister_guest_info_callbacks(&kvm_guest_cbs);
62 }