]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - virt/kvm/irq_comm.c
x86, apicv: add virtual interrupt delivery support
[mirror_ubuntu-artful-kernel.git] / virt / kvm / irq_comm.c
index 656fa455e154abedceba3883cf865adfa73f873b..ff6d40e2c06d6b11e4a5d2bc26606d5baeee96bb 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/kvm_host.h>
 #include <linux/slab.h>
+#include <linux/export.h>
 #include <trace/events/kvm.h>
 
 #include <asm/msidef.h>
@@ -237,6 +238,28 @@ int kvm_set_irq_inatomic(struct kvm *kvm, int irq_source_id, u32 irq, int level)
        return ret;
 }
 
+bool kvm_irq_has_notifier(struct kvm *kvm, unsigned irqchip, unsigned pin)
+{
+       struct kvm_irq_ack_notifier *kian;
+       struct hlist_node *n;
+       int gsi;
+
+       rcu_read_lock();
+       gsi = rcu_dereference(kvm->irq_routing)->chip[irqchip][pin];
+       if (gsi != -1)
+               hlist_for_each_entry_rcu(kian, n, &kvm->irq_ack_notifier_list,
+                                        link)
+                       if (kian->gsi == gsi) {
+                               rcu_read_unlock();
+                               return true;
+                       }
+
+       rcu_read_unlock();
+
+       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;
@@ -261,6 +284,7 @@ void kvm_register_irq_ack_notifier(struct kvm *kvm,
        mutex_lock(&kvm->irq_lock);
        hlist_add_head_rcu(&kian->link, &kvm->irq_ack_notifier_list);
        mutex_unlock(&kvm->irq_lock);
+       kvm_ioapic_make_eoibitmap_request(kvm);
 }
 
 void kvm_unregister_irq_ack_notifier(struct kvm *kvm,
@@ -270,6 +294,7 @@ void kvm_unregister_irq_ack_notifier(struct kvm *kvm,
        hlist_del_init_rcu(&kian->link);
        mutex_unlock(&kvm->irq_lock);
        synchronize_rcu();
+       kvm_ioapic_make_eoibitmap_request(kvm);
 }
 
 int kvm_request_irq_source_id(struct kvm *kvm)