Below patch implements the perf_guest_info_callbacks on kvm. Signed-off-by: Zhang Yanmin <yanmin_zhang@xxxxxxxxxxxxxxx> --- diff -Nraup linux-2.6_tip0417/arch/x86/kvm/vmx.c linux-2.6_tip0417_perfkvm/arch/x86/kvm/vmx.c --- linux-2.6_tip0417/arch/x86/kvm/vmx.c 2010-04-19 09:51:47.908673911 +0800 +++ linux-2.6_tip0417_perfkvm/arch/x86/kvm/vmx.c 2010-04-19 09:53:59.690399987 +0800 @@ -3654,8 +3654,11 @@ static void vmx_complete_interrupts(stru /* We need to handle NMIs before interrupts are enabled */ if ((exit_intr_info & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_NMI_INTR && - (exit_intr_info & INTR_INFO_VALID_MASK)) + (exit_intr_info & INTR_INFO_VALID_MASK)) { + kvm_before_handle_nmi(&vmx->vcpu); asm("int $2"); + kvm_after_handle_nmi(&vmx->vcpu); + } idtv_info_valid = idt_vectoring_info & VECTORING_INFO_VALID_MASK; diff -Nraup linux-2.6_tip0417/arch/x86/kvm/x86.c linux-2.6_tip0417_perfkvm/arch/x86/kvm/x86.c --- linux-2.6_tip0417/arch/x86/kvm/x86.c 2010-04-19 09:51:47.892676413 +0800 +++ linux-2.6_tip0417_perfkvm/arch/x86/kvm/x86.c 2010-04-19 09:53:59.691378953 +0800 @@ -40,6 +40,7 @@ #include <linux/user-return-notifier.h> #include <linux/srcu.h> #include <linux/slab.h> +#include <linux/perf_event.h> #include <trace/events/kvm.h> #undef TRACE_INCLUDE_FILE #define CREATE_TRACE_POINTS @@ -3765,6 +3766,47 @@ static void kvm_timer_init(void) } } +static DEFINE_PER_CPU(struct kvm_vcpu *, current_vcpu); + +static int kvm_is_in_guest(void) +{ + return percpu_read(current_vcpu) != NULL; +} + +static int kvm_is_user_mode(void) +{ + int user_mode = 3; + if (percpu_read(current_vcpu)) + user_mode = kvm_x86_ops->get_cpl(percpu_read(current_vcpu)); + return user_mode != 0; +} + +static unsigned long kvm_get_guest_ip(void) +{ + unsigned long ip = 0; + if (percpu_read(current_vcpu)) + ip = kvm_rip_read(percpu_read(current_vcpu)); + return ip; +} + +static struct perf_guest_info_callbacks kvm_guest_cbs = { + .is_in_guest = kvm_is_in_guest, + .is_user_mode = kvm_is_user_mode, + .get_guest_ip = kvm_get_guest_ip, +}; + +void kvm_before_handle_nmi(struct kvm_vcpu *vcpu) +{ + percpu_write(current_vcpu, vcpu); +} +EXPORT_SYMBOL_GPL(kvm_before_handle_nmi); + +void kvm_after_handle_nmi(struct kvm_vcpu *vcpu) +{ + percpu_write(current_vcpu, NULL); +} +EXPORT_SYMBOL_GPL(kvm_after_handle_nmi); + int kvm_arch_init(void *opaque) { int r; @@ -3801,6 +3843,8 @@ int kvm_arch_init(void *opaque) kvm_timer_init(); + perf_register_guest_info_callbacks(&kvm_guest_cbs); + return 0; out: @@ -3809,6 +3853,8 @@ out: void kvm_arch_exit(void) { + perf_unregister_guest_info_callbacks(&kvm_guest_cbs); + if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) cpufreq_unregister_notifier(&kvmclock_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER); diff -Nraup linux-2.6_tip0417/arch/x86/kvm/x86.h linux-2.6_tip0417_perfkvm/arch/x86/kvm/x86.h --- linux-2.6_tip0417/arch/x86/kvm/x86.h 2010-04-19 09:51:47.884709050 +0800 +++ linux-2.6_tip0417_perfkvm/arch/x86/kvm/x86.h 2010-04-19 09:53:59.691378953 +0800 @@ -65,4 +65,7 @@ static inline int is_paging(struct kvm_v return kvm_read_cr0_bits(vcpu, X86_CR0_PG); } +void kvm_before_handle_nmi(struct kvm_vcpu *vcpu); +void kvm_after_handle_nmi(struct kvm_vcpu *vcpu); + #endif -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html