Skip to content

Commit

Permalink
vfio/pci: Use pci_try_reset_function() on initial open
Browse files Browse the repository at this point in the history
Device lock bites again; if a device .remove() callback races a user
calling ioctl(VFIO_GROUP_GET_DEVICE_FD), the unbind request will hold
the device lock, but the user ioctl may have already taken a vfio_device
reference.  In the case of a PCI device, the initial open will attempt
to reset the device, which again attempts to get the device lock,
resulting in deadlock.  Use the trylock PCI reset interface and return
error on the open path if reset fails due to lock contention.

Link: https://lkml.org/lkml/2017/7/25/381
Reported-by: Wen Congyang <[email protected]>
Signed-off-by: Alex Williamson <[email protected]>
  • Loading branch information
awilliam committed Jul 26, 2017
1 parent bb67b49 commit 9f47803
Showing 1 changed file with 8 additions and 1 deletion.
9 changes: 8 additions & 1 deletion drivers/vfio/pci/vfio_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,14 @@ static int vfio_pci_enable(struct vfio_pci_device *vdev)
if (ret)
return ret;

vdev->reset_works = (pci_reset_function(pdev) == 0);
/* If reset fails because of the device lock, fail this path entirely */
ret = pci_try_reset_function(pdev);
if (ret == -EAGAIN) {
pci_disable_device(pdev);
return ret;
}

vdev->reset_works = !ret;
pci_save_state(pdev);
vdev->pci_saved_state = pci_store_saved_state(pdev);
if (!vdev->pci_saved_state)
Expand Down

0 comments on commit 9f47803

Please sign in to comment.