From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758694AbdJQB4c (ORCPT ); Mon, 16 Oct 2017 21:56:32 -0400 Received: from mga11.intel.com ([192.55.52.93]:40386 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758592AbdJQB4a (ORCPT ); Mon, 16 Oct 2017 21:56:30 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.43,389,1503385200"; d="scan'208";a="1231549906" From: Luwei Kang To: kvm@vger.kernel.org Cc: pbonzini@redhat.com, rkrcmar@redhat.com, tglx@linutronix.de, mingo@redhat.com, hpa@zytor.com, x86@kernel.org, linux-kernel@vger.kernel.org, Chao Peng , Luwei Kang Subject: [PATCH 4/9] perf/x86/intel/pt: add Intel processor trace virtualization call backs Date: Mon, 16 Oct 2017 20:13:10 +0800 Message-Id: <1508155990-4799-1-git-send-email-luwei.kang@intel.com> X-Mailer: git-send-email 2.7.4 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Chao Peng Add Intel processor trace virtualization call backs to suppress host event in guest only mode. Signed-off-by: Chao Peng Signed-off-by: Luwei Kang --- arch/x86/events/intel/pt.c | 21 +++++++++++++++++++++ arch/x86/include/asm/intel_pt.h | 9 +++++++++ 2 files changed, 30 insertions(+) diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c index a5a7e44..ec54bba 100644 --- a/arch/x86/events/intel/pt.c +++ b/arch/x86/events/intel/pt.c @@ -36,6 +36,7 @@ static DEFINE_PER_CPU(struct pt, pt_ctx); static struct pt_pmu pt_pmu; +static struct pt_virt_ops *virt_ops; /* * Capabilities of Intel PT hardware, such as number of address bits or @@ -177,6 +178,18 @@ static ssize_t pt_cap_show(struct device *cdev, NULL, }; +void pt_register_virt_ops(struct pt_virt_ops *ops) +{ + virt_ops = ops; +} +EXPORT_SYMBOL_GPL(pt_register_virt_ops); + +void pt_unregister_virt_ops(void) +{ + virt_ops = NULL; +} +EXPORT_SYMBOL_GPL(pt_unregister_virt_ops); + static int __init pt_pmu_hw_init(void) { struct dev_ext_attribute *de_attrs; @@ -1244,6 +1257,9 @@ void intel_pt_interrupt(void) struct pt_buffer *buf; struct perf_event *event = pt->handle.event; + if (virt_ops && virt_ops->pmi && virt_ops->pmi()) + return; + /* * There may be a dangling PT bit in the interrupt status register * after PT has been disabled by pt_event_stop(). Make sure we don't @@ -1444,6 +1460,11 @@ static void pt_event_destroy(struct perf_event *event) static int pt_event_init(struct perf_event *event) { + /* suppress host event in guest only mode */ + if (virt_ops && virt_ops->get_mode && + virt_ops->get_mode() == PT_MODE_GUEST) + return -EPERM; + if (event->attr.type != pt_pmu.pmu.type) return -ENOENT; diff --git a/arch/x86/include/asm/intel_pt.h b/arch/x86/include/asm/intel_pt.h index b5dd33c..6a5d475 100644 --- a/arch/x86/include/asm/intel_pt.h +++ b/arch/x86/include/asm/intel_pt.h @@ -26,12 +26,21 @@ enum pt_capabilities { PT_CAP_psb_periods, }; +struct pt_virt_ops { + enum pt_mode (*get_mode)(void); + bool (*pmi)(void); +}; + #if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_INTEL) void cpu_emergency_stop_pt(void); extern u32 pt_cap_get(enum pt_capabilities cap); +extern void pt_register_virt_ops(struct pt_virt_ops *ops); +extern void pt_unregister_virt_ops(void); #else static inline void cpu_emergency_stop_pt(void) {} static inline u32 pt_cap_get(enum pt_capabilities cap) { return 0; } +static void pt_register_virt_ops(struct pt_virt_ops *ops) { } +static void pt_unregister_virt_ops(void) { } #endif #endif /* _ASM_X86_INTEL_PT_H */ -- 1.8.3.1