vfio/pci: Use pci_try_reset_function() on initial open
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 <wencongyang2@huawei.com> Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
This commit is contained in:
parent
bb67b496c3
commit
9f47803503
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue