Commit 1e34cf96 authored by Marc Marí's avatar Marc Marí Committed by Kevin Wolf
Browse files

libqos: Solve bug in interrupt checking when using MSIX in virtio-pci.c



The MSIX interrupt was always acked without checking its value, which caused a
race condition. If the ISR was raised between the read and the acking, the ISR
was never detected and it timed out.

Signed-off-by: default avatarMarc Marí <marc.mari.barcelo@gmail.com>
Reviewed-by: default avatarJohn Snow <jsnow@redhat.com>
Tested-by: default avatarJohn Snow <jsnow@redhat.com>
Message-id: 1424795655-16952-1-git-send-email-marc.mari.barcelo@gmail.com
Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
parent 833a7cc3
Loading
Loading
Loading
Loading
+12 −4
Original line number Diff line number Diff line
@@ -142,8 +142,12 @@ static bool qvirtio_pci_get_queue_isr_status(QVirtioDevice *d, QVirtQueue *vq)
            return qpci_msix_pending(dev->pdev, vqpci->msix_entry);
        } else {
            data = readl(vqpci->msix_addr);
            if (data == vqpci->msix_data) {
                writel(vqpci->msix_addr, 0);
            return data == vqpci->msix_data;
                return true;
            } else {
                return false;
            }
        }
    } else {
        return qpci_io_readb(dev->pdev, dev->addr + QVIRTIO_PCI_ISR_STATUS) & 1;
@@ -162,8 +166,12 @@ static bool qvirtio_pci_get_config_isr_status(QVirtioDevice *d)
            return qpci_msix_pending(dev->pdev, dev->config_msix_entry);
        } else {
            data = readl(dev->config_msix_addr);
            if (data == dev->config_msix_data) {
                writel(dev->config_msix_addr, 0);
            return data == dev->config_msix_data;
                return true;
            } else {
                return false;
            }
        }
    } else {
        return qpci_io_readb(dev->pdev, dev->addr + QVIRTIO_PCI_ISR_STATUS) & 2;