@@ -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>
@@ -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();
}
@@ -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;
@@ -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;
@@ -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) {}
@@ -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);
@@ -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);