diff options
| -rw-r--r-- | arch/x86/events/intel/core.c | 6 | ||||
| -rw-r--r-- | arch/x86/include/asm/msr-index.h | 4 | ||||
| -rw-r--r-- | arch/x86/kvm/x86.c | 10 | ||||
| -rw-r--r-- | include/linux/perf_event.h | 1 |
4 files changed, 20 insertions, 1 deletions
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 8baa441d8000..386151b2c62f 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c | |||
| @@ -2307,7 +2307,11 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status) | |||
| 2307 | */ | 2307 | */ |
| 2308 | if (__test_and_clear_bit(55, (unsigned long *)&status)) { | 2308 | if (__test_and_clear_bit(55, (unsigned long *)&status)) { |
| 2309 | handled++; | 2309 | handled++; |
| 2310 | intel_pt_interrupt(); | 2310 | if (unlikely(perf_guest_cbs && perf_guest_cbs->is_in_guest() && |
| 2311 | perf_guest_cbs->handle_intel_pt_intr)) | ||
| 2312 | perf_guest_cbs->handle_intel_pt_intr(); | ||
| 2313 | else | ||
| 2314 | intel_pt_interrupt(); | ||
| 2311 | } | 2315 | } |
| 2312 | 2316 | ||
| 2313 | /* | 2317 | /* |
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index ca5bc0eacb95..be40c094bc49 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h | |||
| @@ -781,6 +781,10 @@ | |||
| 781 | #define MSR_CORE_PERF_GLOBAL_CTRL 0x0000038f | 781 | #define MSR_CORE_PERF_GLOBAL_CTRL 0x0000038f |
| 782 | #define MSR_CORE_PERF_GLOBAL_OVF_CTRL 0x00000390 | 782 | #define MSR_CORE_PERF_GLOBAL_OVF_CTRL 0x00000390 |
| 783 | 783 | ||
| 784 | /* PERF_GLOBAL_OVF_CTL bits */ | ||
| 785 | #define MSR_CORE_PERF_GLOBAL_OVF_CTRL_TRACE_TOPA_PMI_BIT 55 | ||
| 786 | #define MSR_CORE_PERF_GLOBAL_OVF_CTRL_TRACE_TOPA_PMI (1ULL << MSR_CORE_PERF_GLOBAL_OVF_CTRL_TRACE_TOPA_PMI_BIT) | ||
| 787 | |||
| 784 | /* Geode defined MSRs */ | 788 | /* Geode defined MSRs */ |
| 785 | #define MSR_GEODE_BUSCONT_CONF0 0x00001900 | 789 | #define MSR_GEODE_BUSCONT_CONF0 0x00001900 |
| 786 | 790 | ||
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 6c27d224f744..cedd396e3003 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
| @@ -6839,10 +6839,20 @@ static unsigned long kvm_get_guest_ip(void) | |||
| 6839 | return ip; | 6839 | return ip; |
| 6840 | } | 6840 | } |
| 6841 | 6841 | ||
| 6842 | static void kvm_handle_intel_pt_intr(void) | ||
| 6843 | { | ||
| 6844 | struct kvm_vcpu *vcpu = __this_cpu_read(current_vcpu); | ||
| 6845 | |||
| 6846 | kvm_make_request(KVM_REQ_PMI, vcpu); | ||
| 6847 | __set_bit(MSR_CORE_PERF_GLOBAL_OVF_CTRL_TRACE_TOPA_PMI_BIT, | ||
| 6848 | (unsigned long *)&vcpu->arch.pmu.global_status); | ||
| 6849 | } | ||
| 6850 | |||
| 6842 | static struct perf_guest_info_callbacks kvm_guest_cbs = { | 6851 | static struct perf_guest_info_callbacks kvm_guest_cbs = { |
| 6843 | .is_in_guest = kvm_is_in_guest, | 6852 | .is_in_guest = kvm_is_in_guest, |
| 6844 | .is_user_mode = kvm_is_user_mode, | 6853 | .is_user_mode = kvm_is_user_mode, |
| 6845 | .get_guest_ip = kvm_get_guest_ip, | 6854 | .get_guest_ip = kvm_get_guest_ip, |
| 6855 | .handle_intel_pt_intr = kvm_handle_intel_pt_intr, | ||
| 6846 | }; | 6856 | }; |
| 6847 | 6857 | ||
| 6848 | static void kvm_set_mmio_spte_mask(void) | 6858 | static void kvm_set_mmio_spte_mask(void) |
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index e47ef764f613..820c4ff31bc5 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h | |||
| @@ -30,6 +30,7 @@ struct perf_guest_info_callbacks { | |||
| 30 | int (*is_in_guest)(void); | 30 | int (*is_in_guest)(void); |
| 31 | int (*is_user_mode)(void); | 31 | int (*is_user_mode)(void); |
| 32 | unsigned long (*get_guest_ip)(void); | 32 | unsigned long (*get_guest_ip)(void); |
| 33 | void (*handle_intel_pt_intr)(void); | ||
| 33 | }; | 34 | }; |
| 34 | 35 | ||
| 35 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | 36 | #ifdef CONFIG_HAVE_HW_BREAKPOINT |
