From: Like Xu <likexu@xxxxxxxxxxx> To reuse the interrupt callback function registered by KVM in perf, add incoming parameter to distinguish the context of the caller, which is currently only supported in the case of GUEST_INTEL_PT. No functional change intended. Signed-off-by: Like Xu <likexu@xxxxxxxxxxx> --- arch/x86/events/intel/bts.c | 1 + arch/x86/events/intel/core.c | 2 +- arch/x86/include/asm/kvm_host.h | 7 ++++++- arch/x86/kvm/vmx/vmx.c | 7 +++++-- include/linux/kvm_host.h | 2 +- include/linux/perf_event.h | 8 ++++---- virt/kvm/kvm_main.c | 2 +- 7 files changed, 19 insertions(+), 10 deletions(-) diff --git a/arch/x86/events/intel/bts.c b/arch/x86/events/intel/bts.c index 974e917e65b2..ffdcde5b97b1 100644 --- a/arch/x86/events/intel/bts.c +++ b/arch/x86/events/intel/bts.c @@ -14,6 +14,7 @@ #include <linux/debugfs.h> #include <linux/device.h> #include <linux/coredump.h> +#include <linux/kvm_host.h> #include <linux/sizes.h> #include <asm/perf_event.h> diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 48e313265a15..a7b5237d5a4e 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -2962,7 +2962,7 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status) */ if (__test_and_clear_bit(GLOBAL_STATUS_TRACE_TOPAPMI_BIT, (unsigned long *)&status)) { handled++; - if (!perf_handle_guest_intr()) + if (!perf_handle_guest_intr(GUEST_INTEL_PT)) intel_pt_interrupt(); } diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 8cf472a4ca06..166a77a61f2d 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1661,12 +1661,17 @@ struct kvm_x86_nested_ops { uint16_t (*get_evmcs_version)(struct kvm_vcpu *vcpu); }; +enum { + GUEST_INTEL_PT = 0, + GUEST_INVALID +}; + struct kvm_x86_init_ops { int (*cpu_has_kvm_support)(void); int (*disabled_by_bios)(void); int (*check_processor_compatibility)(void); int (*hardware_setup)(void); - unsigned int (*handle_intr)(void); + unsigned int (*handle_intr)(unsigned int vector); struct kvm_x86_ops *runtime_ops; struct kvm_pmu_ops *pmu_ops; diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index a1856b11467d..3622323d57c2 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -8146,7 +8146,7 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = { .vcpu_deliver_sipi_vector = kvm_vcpu_deliver_sipi_vector, }; -static unsigned int vmx_handle_intel_pt_intr(void) +static unsigned int vmx_handle_guest_intr(unsigned int vector) { struct kvm_vcpu *vcpu = kvm_get_running_vcpu(); @@ -8154,6 +8154,9 @@ static unsigned int vmx_handle_intel_pt_intr(void) if (!vcpu || !kvm_handling_nmi_from_guest(vcpu)) return 0; + if (vector >= GUEST_INVALID) + return 0; + kvm_make_request(KVM_REQ_PMI, vcpu); __set_bit(MSR_CORE_PERF_GLOBAL_OVF_CTRL_TRACE_TOPA_PMI_BIT, (unsigned long *)&vcpu->arch.pmu.global_status); @@ -8374,7 +8377,7 @@ static __init int hardware_setup(void) if (!enable_ept || !enable_pmu || !cpu_has_vmx_intel_pt()) pt_mode = PT_MODE_SYSTEM; if (pt_mode == PT_MODE_HOST_GUEST) - vmx_init_ops.handle_intr = vmx_handle_intel_pt_intr; + vmx_init_ops.handle_intr = vmx_handle_guest_intr; else vmx_init_ops.handle_intr = NULL; diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index f4519d3689e1..91f3752906c5 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -1555,7 +1555,7 @@ static inline bool kvm_arch_intc_initialized(struct kvm *kvm) #ifdef CONFIG_GUEST_PERF_EVENTS unsigned long kvm_arch_vcpu_get_ip(struct kvm_vcpu *vcpu); -void kvm_register_perf_callbacks(unsigned int (*pt_intr_handler)(void)); +void kvm_register_perf_callbacks(unsigned int (*handler)(unsigned int flag)); void kvm_unregister_perf_callbacks(void); #else static inline void kvm_register_perf_callbacks(void *ign) {} diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 6149a977bbd0..a8937d06ff7c 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -32,7 +32,7 @@ struct perf_guest_info_callbacks { unsigned int (*state)(void); unsigned long (*get_ip)(void); - unsigned int (*handle_intr)(void); + unsigned int (*handle_intr)(unsigned int flag); }; #ifdef CONFIG_HAVE_HW_BREAKPOINT @@ -1278,9 +1278,9 @@ static inline unsigned long perf_guest_get_ip(void) return static_call(__perf_guest_get_ip)(); } -static inline unsigned int perf_handle_guest_intr(void) +static inline unsigned int perf_handle_guest_intr(unsigned int vector) { - return static_call(__perf_handle_guest_intr)(); + return static_call(__perf_handle_guest_intr)(vector); } extern void perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *cbs); @@ -1288,7 +1288,7 @@ extern void perf_unregister_guest_info_callbacks(struct perf_guest_info_callback #else static inline unsigned int perf_guest_state(void) { return 0; } static inline unsigned long perf_guest_get_ip(void) { return 0; } -static inline unsigned int perf_handle_guest_intr(void) { return 0; } +static inline unsigned int perf_handle_guest_intr(unsigned int vector) { return 0; } #endif /* CONFIG_GUEST_PERF_EVENTS */ extern void perf_event_exec(void); diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 8190af3a12fa..cc46f13bd133 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -5788,7 +5788,7 @@ static struct perf_guest_info_callbacks kvm_guest_cbs = { .handle_intr = NULL, }; -void kvm_register_perf_callbacks(unsigned int (*handler)(void)) +void kvm_register_perf_callbacks(unsigned int (*handler)(unsigned int vector)) { kvm_guest_cbs.handle_intr = handler; perf_register_guest_info_callbacks(&kvm_guest_cbs); -- 2.37.3