diff options
author | Avi Kivity <avi@redhat.com> | 2010-04-19 05:52:53 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-05-17 05:17:58 -0400 |
commit | 9beeaa2d689842f7760aa16c512e6bb8182d38b6 (patch) | |
tree | 62cea0772127c4b1c0b476e46dec6830d36809c1 /arch/x86/kvm/x86.c | |
parent | 3246af0ece6c61689847417977733f0b12dc4b6f (diff) | |
parent | a1645ce12adb6c9cc9e19d7695466204e3f017fe (diff) |
Merge branch 'perf'
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r-- | arch/x86/kvm/x86.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 30efeead4511..58a96e6a234c 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/user-return-notifier.h> | 40 | #include <linux/user-return-notifier.h> |
41 | #include <linux/srcu.h> | 41 | #include <linux/srcu.h> |
42 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
43 | #include <linux/perf_event.h> | ||
43 | #include <trace/events/kvm.h> | 44 | #include <trace/events/kvm.h> |
44 | 45 | ||
45 | #define CREATE_TRACE_POINTS | 46 | #define CREATE_TRACE_POINTS |
@@ -3955,6 +3956,47 @@ static void kvm_timer_init(void) | |||
3955 | } | 3956 | } |
3956 | } | 3957 | } |
3957 | 3958 | ||
3959 | static DEFINE_PER_CPU(struct kvm_vcpu *, current_vcpu); | ||
3960 | |||
3961 | static int kvm_is_in_guest(void) | ||
3962 | { | ||
3963 | return percpu_read(current_vcpu) != NULL; | ||
3964 | } | ||
3965 | |||
3966 | static int kvm_is_user_mode(void) | ||
3967 | { | ||
3968 | int user_mode = 3; | ||
3969 | if (percpu_read(current_vcpu)) | ||
3970 | user_mode = kvm_x86_ops->get_cpl(percpu_read(current_vcpu)); | ||
3971 | return user_mode != 0; | ||
3972 | } | ||
3973 | |||
3974 | static unsigned long kvm_get_guest_ip(void) | ||
3975 | { | ||
3976 | unsigned long ip = 0; | ||
3977 | if (percpu_read(current_vcpu)) | ||
3978 | ip = kvm_rip_read(percpu_read(current_vcpu)); | ||
3979 | return ip; | ||
3980 | } | ||
3981 | |||
3982 | static struct perf_guest_info_callbacks kvm_guest_cbs = { | ||
3983 | .is_in_guest = kvm_is_in_guest, | ||
3984 | .is_user_mode = kvm_is_user_mode, | ||
3985 | .get_guest_ip = kvm_get_guest_ip, | ||
3986 | }; | ||
3987 | |||
3988 | void kvm_before_handle_nmi(struct kvm_vcpu *vcpu) | ||
3989 | { | ||
3990 | percpu_write(current_vcpu, vcpu); | ||
3991 | } | ||
3992 | EXPORT_SYMBOL_GPL(kvm_before_handle_nmi); | ||
3993 | |||
3994 | void kvm_after_handle_nmi(struct kvm_vcpu *vcpu) | ||
3995 | { | ||
3996 | percpu_write(current_vcpu, NULL); | ||
3997 | } | ||
3998 | EXPORT_SYMBOL_GPL(kvm_after_handle_nmi); | ||
3999 | |||
3958 | int kvm_arch_init(void *opaque) | 4000 | int kvm_arch_init(void *opaque) |
3959 | { | 4001 | { |
3960 | int r; | 4002 | int r; |
@@ -3991,6 +4033,8 @@ int kvm_arch_init(void *opaque) | |||
3991 | 4033 | ||
3992 | kvm_timer_init(); | 4034 | kvm_timer_init(); |
3993 | 4035 | ||
4036 | perf_register_guest_info_callbacks(&kvm_guest_cbs); | ||
4037 | |||
3994 | return 0; | 4038 | return 0; |
3995 | 4039 | ||
3996 | out: | 4040 | out: |
@@ -3999,6 +4043,8 @@ out: | |||
3999 | 4043 | ||
4000 | void kvm_arch_exit(void) | 4044 | void kvm_arch_exit(void) |
4001 | { | 4045 | { |
4046 | perf_unregister_guest_info_callbacks(&kvm_guest_cbs); | ||
4047 | |||
4002 | if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) | 4048 | if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) |
4003 | cpufreq_unregister_notifier(&kvmclock_cpufreq_notifier_block, | 4049 | cpufreq_unregister_notifier(&kvmclock_cpufreq_notifier_block, |
4004 | CPUFREQ_TRANSITION_NOTIFIER); | 4050 | CPUFREQ_TRANSITION_NOTIFIER); |