KVM: fix ack not being delivered when msi present
authorMichael S. Tsirkin <mst@redhat.com>
Sun, 26 Jul 2009 14:10:01 +0000 (17:10 +0300)
committerAvi Kivity <avi@redhat.com>
Wed, 5 Aug 2009 11:03:43 +0000 (14:03 +0300)
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>
include/linux/kvm_host.h
virt/kvm/irq_comm.c

index 16713dc..3060bdc 100644 (file)
@@ -110,6 +110,7 @@ struct kvm_memory_slot {
 
 struct kvm_kernel_irq_routing_entry {
        u32 gsi;
 
 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 {
        int (*set)(struct kvm_kernel_irq_routing_entry *e,
                    struct kvm *kvm, int level);
        union {
index a8bd466..ddc17f0 100644 (file)
@@ -160,7 +160,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)
        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;
                    e->irqchip.pin == pin) {
                        gsi = e->gsi;
                        break;
@@ -259,6 +260,7 @@ static int setup_routing_entry(struct kvm_kernel_irq_routing_entry *e,
        int delta;
 
        e->gsi = ue->gsi;
        int delta;
 
        e->gsi = ue->gsi;
+       e->type = ue->type;
        switch (ue->type) {
        case KVM_IRQ_ROUTING_IRQCHIP:
                delta = 0;
        switch (ue->type) {
        case KVM_IRQ_ROUTING_IRQCHIP:
                delta = 0;