aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/vfio
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@redhat.com>2012-10-10 11:10:32 -0400
committerAlex Williamson <alex.williamson@redhat.com>2012-10-10 11:10:32 -0400
commit899649b7d4ead76c19e39251ca886eebe3f811a8 (patch)
treea86eae8128cf6f271ada3b4c4e4eb43238f56233 /drivers/vfio
parent9dbdfd23b7638d054f3b0e70c64dfb9f297f2a9f (diff)
vfio: Fix PCI INTx disable consistency
The virq_disabled flag tracks the userspace view of INTx masking across interrupt mode changes, but we're not consistently applying this to the interrupt and masking handler notion of the device. Currently if the user sets DisINTx while in MSI or MSIX mode, then returns to INTx mode (ex. rebooting a qemu guest), the hardware has DisINTx+, but the management of INTx thinks it's enabled, making it impossible to actually clear DisINTx. Fix this by updating the handler state when INTx is re-enabled. Cc: stable@vger.kernel.org Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Diffstat (limited to 'drivers/vfio')
-rw-r--r--drivers/vfio/pci/vfio_pci_intrs.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c
index c8139a598f84..3639371fa697 100644
--- a/drivers/vfio/pci/vfio_pci_intrs.c
+++ b/drivers/vfio/pci/vfio_pci_intrs.c
@@ -366,6 +366,17 @@ static int vfio_intx_enable(struct vfio_pci_device *vdev)
366 return -ENOMEM; 366 return -ENOMEM;
367 367
368 vdev->num_ctx = 1; 368 vdev->num_ctx = 1;
369
370 /*
371 * If the virtual interrupt is masked, restore it. Devices
372 * supporting DisINTx can be masked at the hardware level
373 * here, non-PCI-2.3 devices will have to wait until the
374 * interrupt is enabled.
375 */
376 vdev->ctx[0].masked = vdev->virq_disabled;
377 if (vdev->pci_2_3)
378 pci_intx(vdev->pdev, !vdev->ctx[0].masked);
379
369 vdev->irq_type = VFIO_PCI_INTX_IRQ_INDEX; 380 vdev->irq_type = VFIO_PCI_INTX_IRQ_INDEX;
370 381
371 return 0; 382 return 0;
@@ -419,7 +430,7 @@ static int vfio_intx_set_signal(struct vfio_pci_device *vdev, int fd)
419 * disable_irq won't. 430 * disable_irq won't.
420 */ 431 */
421 spin_lock_irqsave(&vdev->irqlock, flags); 432 spin_lock_irqsave(&vdev->irqlock, flags);
422 if (!vdev->pci_2_3 && (vdev->ctx[0].masked || vdev->virq_disabled)) 433 if (!vdev->pci_2_3 && vdev->ctx[0].masked)
423 disable_irq_nosync(pdev->irq); 434 disable_irq_nosync(pdev->irq);
424 spin_unlock_irqrestore(&vdev->irqlock, flags); 435 spin_unlock_irqrestore(&vdev->irqlock, flags);
425 436