summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/events/intel/core.c6
-rw-r--r--arch/x86/include/asm/msr-index.h4
-rw-r--r--arch/x86/kvm/x86.c10
-rw-r--r--include/linux/perf_event.h1
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
6842static 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
6842static struct perf_guest_info_callbacks kvm_guest_cbs = { 6851static 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
6848static void kvm_set_mmio_spte_mask(void) 6858static 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