aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm/eventfd.c
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2014-06-30 06:51:12 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2014-08-05 08:26:24 -0400
commite4d57e1ee1ab59f0cef0272800ac6c52e0ec814a (patch)
tree9659cfbdb348479f17090704034e7f9e545ee122 /virt/kvm/eventfd.c
parent9957c86d659a4d5a2bed25ccbd3bfc9c3f25e658 (diff)
KVM: Move irq notifier implementation into eventfd.c
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>
Diffstat (limited to 'virt/kvm/eventfd.c')
-rw-r--r--virt/kvm/eventfd.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index f0075ffb0c35..99957df69cf2 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -34,7 +34,9 @@
34#include <linux/srcu.h> 34#include <linux/srcu.h>
35#include <linux/slab.h> 35#include <linux/slab.h>
36#include <linux/seqlock.h> 36#include <linux/seqlock.h>
37#include <trace/events/kvm.h>
37 38
39#include "irq.h"
38#include "iodev.h" 40#include "iodev.h"
39 41
40#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING 42#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING
@@ -865,3 +867,64 @@ kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
865 867
866 return kvm_assign_ioeventfd(kvm, args); 868 return kvm_assign_ioeventfd(kvm, args);
867} 869}
870
871bool kvm_irq_has_notifier(struct kvm *kvm, unsigned irqchip, unsigned pin)
872{
873 struct kvm_irq_ack_notifier *kian;
874 int gsi, idx;
875
876 idx = srcu_read_lock(&kvm->irq_srcu);
877 gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
878 if (gsi != -1)
879 hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list,
880 link)
881 if (kian->gsi == gsi) {
882 srcu_read_unlock(&kvm->irq_srcu, idx);
883 return true;
884 }
885
886 srcu_read_unlock(&kvm->irq_srcu, idx);
887
888 return false;
889}
890EXPORT_SYMBOL_GPL(kvm_irq_has_notifier);
891
892void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin)
893{
894 struct kvm_irq_ack_notifier *kian;
895 int gsi, idx;
896
897 trace_kvm_ack_irq(irqchip, pin);
898
899 idx = srcu_read_lock(&kvm->irq_srcu);
900 gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
901 if (gsi != -1)
902 hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list,
903 link)
904 if (kian->gsi == gsi)
905 kian->irq_acked(kian);
906 srcu_read_unlock(&kvm->irq_srcu, idx);
907}
908
909void kvm_register_irq_ack_notifier(struct kvm *kvm,
910 struct kvm_irq_ack_notifier *kian)
911{
912 mutex_lock(&kvm->irq_lock);
913 hlist_add_head_rcu(&kian->link, &kvm->irq_ack_notifier_list);
914 mutex_unlock(&kvm->irq_lock);
915#ifdef __KVM_HAVE_IOAPIC
916 kvm_vcpu_request_scan_ioapic(kvm);
917#endif
918}
919
920void kvm_unregister_irq_ack_notifier(struct kvm *kvm,
921 struct kvm_irq_ack_notifier *kian)
922{
923 mutex_lock(&kvm->irq_lock);
924 hlist_del_init_rcu(&kian->link);
925 mutex_unlock(&kvm->irq_lock);
926 synchronize_srcu(&kvm->irq_srcu);
927#ifdef __KVM_HAVE_IOAPIC
928 kvm_vcpu_request_scan_ioapic(kvm);
929#endif
930}