diff options
Diffstat (limited to 'drivers/vfio/pci/vfio_pci_intrs.c')
| -rw-r--r-- | drivers/vfio/pci/vfio_pci_intrs.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c index d8dedc7d3910..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; |
| @@ -400,25 +411,26 @@ static int vfio_intx_set_signal(struct vfio_pci_device *vdev, int fd) | |||
| 400 | return PTR_ERR(trigger); | 411 | return PTR_ERR(trigger); |
| 401 | } | 412 | } |
| 402 | 413 | ||
| 414 | vdev->ctx[0].trigger = trigger; | ||
| 415 | |||
| 403 | if (!vdev->pci_2_3) | 416 | if (!vdev->pci_2_3) |
| 404 | irqflags = 0; | 417 | irqflags = 0; |
| 405 | 418 | ||
| 406 | ret = request_irq(pdev->irq, vfio_intx_handler, | 419 | ret = request_irq(pdev->irq, vfio_intx_handler, |
| 407 | irqflags, vdev->ctx[0].name, vdev); | 420 | irqflags, vdev->ctx[0].name, vdev); |
| 408 | if (ret) { | 421 | if (ret) { |
| 422 | vdev->ctx[0].trigger = NULL; | ||
| 409 | kfree(vdev->ctx[0].name); | 423 | kfree(vdev->ctx[0].name); |
| 410 | eventfd_ctx_put(trigger); | 424 | eventfd_ctx_put(trigger); |
| 411 | return ret; | 425 | return ret; |
| 412 | } | 426 | } |
| 413 | 427 | ||
| 414 | vdev->ctx[0].trigger = trigger; | ||
| 415 | |||
| 416 | /* | 428 | /* |
| 417 | * INTx disable will stick across the new irq setup, | 429 | * INTx disable will stick across the new irq setup, |
| 418 | * disable_irq won't. | 430 | * disable_irq won't. |
| 419 | */ | 431 | */ |
| 420 | spin_lock_irqsave(&vdev->irqlock, flags); | 432 | spin_lock_irqsave(&vdev->irqlock, flags); |
| 421 | if (!vdev->pci_2_3 && (vdev->ctx[0].masked || vdev->virq_disabled)) | 433 | if (!vdev->pci_2_3 && vdev->ctx[0].masked) |
| 422 | disable_irq_nosync(pdev->irq); | 434 | disable_irq_nosync(pdev->irq); |
| 423 | spin_unlock_irqrestore(&vdev->irqlock, flags); | 435 | spin_unlock_irqrestore(&vdev->irqlock, flags); |
| 424 | 436 | ||
