diff options
author | Sage Weil <sage@inktank.com> | 2013-08-15 11:11:45 -0700 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-08-15 11:11:45 -0700 |
commit | ee3e542fec6e69bc9fb668698889a37d93950ddf (patch) | |
tree | e74ee766a4764769ef1d3d45d266b4dea64101d3 /drivers/vfio/pci/vfio_pci.c | |
parent | fe2a801b50c0bb8039d627e5ae1fec249d10ff39 (diff) | |
parent | f1d6e17f540af37bb1891480143669ba7636c4cf (diff) |
Merge remote-tracking branch 'linus/master' into testing
Diffstat (limited to 'drivers/vfio/pci/vfio_pci.c')
-rw-r--r-- | drivers/vfio/pci/vfio_pci.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index ac3725440d6..cef6002acbd 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -137,8 +137,27 @@ static void vfio_pci_disable(struct vfio_pci_device *vdev) */ pci_write_config_word(pdev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE); - if (vdev->reset_works) - __pci_reset_function(pdev); + /* + * Careful, device_lock may already be held. This is the case if + * a driver unbind is blocked. Try to get the locks ourselves to + * prevent a deadlock. + */ + if (vdev->reset_works) { + bool reset_done = false; + + if (pci_cfg_access_trylock(pdev)) { + if (device_trylock(&pdev->dev)) { + __pci_reset_function_locked(pdev); + reset_done = true; + device_unlock(&pdev->dev); + } + pci_cfg_access_unlock(pdev); + } + + if (!reset_done) + pr_warn("%s: Unable to acquire locks for reset of %s\n", + __func__, dev_name(&pdev->dev)); + } pci_restore_state(pdev); } @@ -499,7 +518,6 @@ static int vfio_pci_mmap(void *device_data, struct vm_area_struct *vma) } vma->vm_private_data = vdev; - vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP; vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); vma->vm_pgoff = (pci_resource_start(pdev, index) >> PAGE_SHIFT) + pgoff; |