struct virtio_pci_device *vp_dev = to_vp_device(vdev);
        int i;
 
-       if (vp_dev->intx_enabled)
+       if (vp_dev->intx_enabled) {
+               /*
+                * The below synchronize() guarantees that any
+                * interrupt for this line arriving after
+                * synchronize_irq() has completed is guaranteed to see
+                * intx_soft_enabled == false.
+                */
+               WRITE_ONCE(vp_dev->intx_soft_enabled, false);
                synchronize_irq(vp_dev->pci_dev->irq);
+       }
 
        for (i = 0; i < vp_dev->msix_vectors; ++i)
                disable_irq(pci_irq_vector(vp_dev->pci_dev, i));
        struct virtio_pci_device *vp_dev = to_vp_device(vdev);
        int i;
 
-       if (vp_dev->intx_enabled)
+       if (vp_dev->intx_enabled) {
+               disable_irq(vp_dev->pci_dev->irq);
+               /*
+                * The above disable_irq() provides TSO ordering and
+                * as such promotes the below store to store-release.
+                */
+               WRITE_ONCE(vp_dev->intx_soft_enabled, true);
+               enable_irq(vp_dev->pci_dev->irq);
                return;
+       }
 
        for (i = 0; i < vp_dev->msix_vectors; ++i)
                enable_irq(pci_irq_vector(vp_dev->pci_dev, i));
        struct virtio_pci_device *vp_dev = opaque;
        u8 isr;
 
+       if (!READ_ONCE(vp_dev->intx_soft_enabled))
+               return IRQ_NONE;
+
        /* reading the ISR has the effect of also clearing it so it's very
         * important to save off the value. */
        isr = ioread8(vp_dev->isr);