blob: d45b8b9a44151810e1ac9e4ba77c41b7053c6375 [file] [log] [blame]
Thomas Gleixnercaab2772019-06-03 07:44:50 +02001// SPDX-License-Identifier: GPL-2.0-only
Marc Zyngier210552c2013-03-05 03:18:00 +00002/*
3 * Based on the x86 implementation.
4 *
5 * Copyright (C) 2012 ARM Ltd.
6 * Author: Marc Zyngier <marc.zyngier@arm.com>
Marc Zyngier210552c2013-03-05 03:18:00 +00007 */
8
9#include <linux/perf_event.h>
10#include <linux/kvm_host.h>
11
12#include <asm/kvm_emulate.h>
13
14static int kvm_is_in_guest(void)
15{
Paolo Bonzini7495e222020-01-09 09:57:19 -050016 return kvm_get_running_vcpu() != NULL;
Marc Zyngier210552c2013-03-05 03:18:00 +000017}
18
19static int kvm_is_user_mode(void)
20{
21 struct kvm_vcpu *vcpu;
22
Paolo Bonzini7495e222020-01-09 09:57:19 -050023 vcpu = kvm_get_running_vcpu();
Marc Zyngier210552c2013-03-05 03:18:00 +000024
25 if (vcpu)
26 return !vcpu_mode_priv(vcpu);
27
28 return 0;
29}
30
31static unsigned long kvm_get_guest_ip(void)
32{
33 struct kvm_vcpu *vcpu;
34
Paolo Bonzini7495e222020-01-09 09:57:19 -050035 vcpu = kvm_get_running_vcpu();
Marc Zyngier210552c2013-03-05 03:18:00 +000036
37 if (vcpu)
38 return *vcpu_pc(vcpu);
39
40 return 0;
41}
42
43static struct perf_guest_info_callbacks kvm_guest_cbs = {
44 .is_in_guest = kvm_is_in_guest,
45 .is_user_mode = kvm_is_user_mode,
46 .get_guest_ip = kvm_get_guest_ip,
47};
48
49int kvm_perf_init(void)
50{
51 return perf_register_guest_info_callbacks(&kvm_guest_cbs);
52}
53
54int kvm_perf_teardown(void)
55{
56 return perf_unregister_guest_info_callbacks(&kvm_guest_cbs);
57}