178 lines
5.1 KiB
Diff
178 lines
5.1 KiB
Diff
From: Paul Mackerras <paulus@samba.org>
|
|
Date: Mon, 30 Jun 2014 20:51:12 +1000
|
|
Subject: KVM: Move irq notifier implementation into eventfd.c
|
|
Origin: https://git.kernel.org/linus/e4d57e1ee1ab59f0cef0272800ac6c52e0ec814a
|
|
|
|
This moves the functions kvm_irq_has_notifier(), kvm_notify_acked_irq(),
|
|
kvm_register_irq_ack_notifier() and kvm_unregister_irq_ack_notifier()
|
|
from irqchip.c to eventfd.c. The reason for doing this is that those
|
|
functions are used in connection with IRQFDs, which are implemented in
|
|
eventfd.c. In future we will want to use IRQFDs on platforms that
|
|
don't implement the GSI routing implemented in irqchip.c, so we won't
|
|
be compiling in irqchip.c, but we still need the irq notifiers. The
|
|
implementation is unchanged.
|
|
|
|
Signed-off-by: Paul Mackerras <paulus@samba.org>
|
|
Tested-by: Eric Auger <eric.auger@linaro.org>
|
|
Tested-by: Cornelia Huck <cornelia.huck@de.ibm.com>
|
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
---
|
|
virt/kvm/eventfd.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
virt/kvm/irqchip.c | 61 --------------------------------------------------
|
|
2 files changed, 63 insertions(+), 61 deletions(-)
|
|
|
|
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
|
|
index f0075ff..99957df 100644
|
|
--- a/virt/kvm/eventfd.c
|
|
+++ b/virt/kvm/eventfd.c
|
|
@@ -34,7 +34,9 @@
|
|
#include <linux/srcu.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/seqlock.h>
|
|
+#include <trace/events/kvm.h>
|
|
|
|
+#include "irq.h"
|
|
#include "iodev.h"
|
|
|
|
#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING
|
|
@@ -865,3 +867,64 @@ kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
|
|
|
|
return kvm_assign_ioeventfd(kvm, args);
|
|
}
|
|
+
|
|
+bool kvm_irq_has_notifier(struct kvm *kvm, unsigned irqchip, unsigned pin)
|
|
+{
|
|
+ struct kvm_irq_ack_notifier *kian;
|
|
+ int gsi, idx;
|
|
+
|
|
+ idx = srcu_read_lock(&kvm->irq_srcu);
|
|
+ gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
|
|
+ if (gsi != -1)
|
|
+ hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list,
|
|
+ link)
|
|
+ if (kian->gsi == gsi) {
|
|
+ srcu_read_unlock(&kvm->irq_srcu, idx);
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ srcu_read_unlock(&kvm->irq_srcu, idx);
|
|
+
|
|
+ return false;
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(kvm_irq_has_notifier);
|
|
+
|
|
+void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin)
|
|
+{
|
|
+ struct kvm_irq_ack_notifier *kian;
|
|
+ int gsi, idx;
|
|
+
|
|
+ trace_kvm_ack_irq(irqchip, pin);
|
|
+
|
|
+ idx = srcu_read_lock(&kvm->irq_srcu);
|
|
+ gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
|
|
+ if (gsi != -1)
|
|
+ hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list,
|
|
+ link)
|
|
+ if (kian->gsi == gsi)
|
|
+ kian->irq_acked(kian);
|
|
+ srcu_read_unlock(&kvm->irq_srcu, idx);
|
|
+}
|
|
+
|
|
+void kvm_register_irq_ack_notifier(struct kvm *kvm,
|
|
+ struct kvm_irq_ack_notifier *kian)
|
|
+{
|
|
+ mutex_lock(&kvm->irq_lock);
|
|
+ hlist_add_head_rcu(&kian->link, &kvm->irq_ack_notifier_list);
|
|
+ mutex_unlock(&kvm->irq_lock);
|
|
+#ifdef __KVM_HAVE_IOAPIC
|
|
+ kvm_vcpu_request_scan_ioapic(kvm);
|
|
+#endif
|
|
+}
|
|
+
|
|
+void kvm_unregister_irq_ack_notifier(struct kvm *kvm,
|
|
+ struct kvm_irq_ack_notifier *kian)
|
|
+{
|
|
+ mutex_lock(&kvm->irq_lock);
|
|
+ hlist_del_init_rcu(&kian->link);
|
|
+ mutex_unlock(&kvm->irq_lock);
|
|
+ synchronize_srcu(&kvm->irq_srcu);
|
|
+#ifdef __KVM_HAVE_IOAPIC
|
|
+ kvm_vcpu_request_scan_ioapic(kvm);
|
|
+#endif
|
|
+}
|
|
diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c
|
|
index 04faac5..7f256f3 100644
|
|
--- a/virt/kvm/irqchip.c
|
|
+++ b/virt/kvm/irqchip.c
|
|
@@ -69,67 +69,6 @@ int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin)
|
|
return irq_rt->chip[irqchip][pin];
|
|
}
|
|
|
|
-bool kvm_irq_has_notifier(struct kvm *kvm, unsigned irqchip, unsigned pin)
|
|
-{
|
|
- struct kvm_irq_ack_notifier *kian;
|
|
- int gsi, idx;
|
|
-
|
|
- idx = srcu_read_lock(&kvm->irq_srcu);
|
|
- gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
|
|
- if (gsi != -1)
|
|
- hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list,
|
|
- link)
|
|
- if (kian->gsi == gsi) {
|
|
- srcu_read_unlock(&kvm->irq_srcu, idx);
|
|
- return true;
|
|
- }
|
|
-
|
|
- srcu_read_unlock(&kvm->irq_srcu, idx);
|
|
-
|
|
- return false;
|
|
-}
|
|
-EXPORT_SYMBOL_GPL(kvm_irq_has_notifier);
|
|
-
|
|
-void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin)
|
|
-{
|
|
- struct kvm_irq_ack_notifier *kian;
|
|
- int gsi, idx;
|
|
-
|
|
- trace_kvm_ack_irq(irqchip, pin);
|
|
-
|
|
- idx = srcu_read_lock(&kvm->irq_srcu);
|
|
- gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
|
|
- if (gsi != -1)
|
|
- hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list,
|
|
- link)
|
|
- if (kian->gsi == gsi)
|
|
- kian->irq_acked(kian);
|
|
- srcu_read_unlock(&kvm->irq_srcu, idx);
|
|
-}
|
|
-
|
|
-void kvm_register_irq_ack_notifier(struct kvm *kvm,
|
|
- struct kvm_irq_ack_notifier *kian)
|
|
-{
|
|
- mutex_lock(&kvm->irq_lock);
|
|
- hlist_add_head_rcu(&kian->link, &kvm->irq_ack_notifier_list);
|
|
- mutex_unlock(&kvm->irq_lock);
|
|
-#ifdef __KVM_HAVE_IOAPIC
|
|
- kvm_vcpu_request_scan_ioapic(kvm);
|
|
-#endif
|
|
-}
|
|
-
|
|
-void kvm_unregister_irq_ack_notifier(struct kvm *kvm,
|
|
- struct kvm_irq_ack_notifier *kian)
|
|
-{
|
|
- mutex_lock(&kvm->irq_lock);
|
|
- hlist_del_init_rcu(&kian->link);
|
|
- mutex_unlock(&kvm->irq_lock);
|
|
- synchronize_srcu(&kvm->irq_srcu);
|
|
-#ifdef __KVM_HAVE_IOAPIC
|
|
- kvm_vcpu_request_scan_ioapic(kvm);
|
|
-#endif
|
|
-}
|
|
-
|
|
int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi)
|
|
{
|
|
struct kvm_kernel_irq_routing_entry route;
|
|
--
|
|
1.7.10.4
|
|
|