]> git.hungrycats.org Git - linux/commitdiff
KVM: fix ack not being delivered when msi present
authorMichael S. Tsirkin <mst@redhat.com>
Tue, 1 Sep 2009 15:15:14 +0000 (12:15 -0300)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 9 Sep 2009 03:33:37 +0000 (20:33 -0700)
(cherry picked from commit 5116d8f6b977970ebefc1932c0f313163a6ec91f)

kvm_notify_acked_irq does not check irq type, so that it sometimes
interprets msi vector as irq.  As a result, ack notifiers are not
called, which typially hangs the guest.  The fix is to track and
check irq type.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
include/linux/kvm_host.h
virt/kvm/irq_comm.c

index 5eed8fa02c041d77c8f133febc4573237515d871..340e909dfefcb3b836b7e876af0a3cb603040e28 100644 (file)
@@ -110,6 +110,7 @@ struct kvm_memory_slot {
 
 struct kvm_kernel_irq_routing_entry {
        u32 gsi;
+       u32 type;
        int (*set)(struct kvm_kernel_irq_routing_entry *e,
                    struct kvm *kvm, int level);
        union {
index 864ac5483baade3fce7085c3c51f23e493426914..8f2018a03bda2528d3c7a00ec91e77c2a1a7d39c 100644 (file)
@@ -141,7 +141,8 @@ void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin)
        unsigned gsi = pin;
 
        list_for_each_entry(e, &kvm->irq_routing, link)
-               if (e->irqchip.irqchip == irqchip &&
+               if (e->type == KVM_IRQ_ROUTING_IRQCHIP &&
+                   e->irqchip.irqchip == irqchip &&
                    e->irqchip.pin == pin) {
                        gsi = e->gsi;
                        break;
@@ -240,6 +241,7 @@ static int setup_routing_entry(struct kvm_kernel_irq_routing_entry *e,
        int delta;
 
        e->gsi = ue->gsi;
+       e->type = ue->type;
        switch (ue->type) {
        case KVM_IRQ_ROUTING_IRQCHIP:
                delta = 0;