On Wed, Jan 30, 2019 at 06:02:27PM +0100, Paolo Bonzini wrote: > On 19/01/19 21:04, Luwei Kang wrote: > > static struct pt_pmu pt_pmu; > > > > @@ -1260,6 +1262,14 @@ void intel_pt_interrupt(void) > > struct pt_buffer *buf; > > struct perf_event *event = pt->handle.event; > > > > + if (pt->vcpu) { > > + /* Inject PMI to Guest */ > > + kvm_make_request(KVM_REQ_PMI, pt->vcpu); > > + __set_bit(MSR_CORE_PERF_GLOBAL_OVF_CTRL_TRACE_TOPA_PMI_BIT, > > + (unsigned long *)&pt->vcpu->arch.pmu.global_status); > > + return; > > + } > > + > > There is no need to touch struct pt and to know details of KVM in > arch/x86/events. Please add a function pointer > > void (*kvm_handle_pt_interrupt)(void); > > to some header, and in handle_pmi_common do > > if (unlikely(kvm_handle_intel_pt_interrupt)) > kvm_handle_intel_pt_interrupt(); > else > intel_pt_interrupt(); > > The function pointer can be assigned in > kvm_before_interrupt/kvm_after_interrupt just like you do now. > > This should be a simpler patch too. I know we do this in other places too; but it really is a very bad pattern. Exported function pointers are a fscking disaster waiting to happen. There is nothing that limits access to kvm.o, any random module can try and poke at it. How about we extend perf_guest_info_callback with an arch section and add: diff --git a/kernel/events/core.c b/kernel/events/core.c index 5aeb4c74fb99..76ce804e72c1 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -5835,6 +5835,9 @@ struct perf_guest_info_callbacks *perf_guest_cbs; int perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *cbs) { + if (WARN_ON_ONCE(perf_guest_cbs)) + return -EBUSY; + perf_guest_cbs = cbs; return 0; } @@ -5842,6 +5845,9 @@ EXPORT_SYMBOL_GPL(perf_register_guest_info_callbacks); int perf_unregister_guest_info_callbacks(struct perf_guest_info_callbacks *cbs) { + if (WARN_ON_ONCE(perf_guest_cbs != cbs)) + return -EINVAL; + perf_guest_cbs = NULL; return 0; }