diff options
Diffstat (limited to 'drivers/vfio/pci/vfio_pci.c')
-rw-r--r-- | drivers/vfio/pci/vfio_pci.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index c5179e269df6..cef6002acbd4 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) | |||
137 | */ | 137 | */ |
138 | pci_write_config_word(pdev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE); | 138 | pci_write_config_word(pdev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE); |
139 | 139 | ||
140 | if (vdev->reset_works) | 140 | /* |
141 | __pci_reset_function(pdev); | 141 | * Careful, device_lock may already be held. This is the case if |
142 | * a driver unbind is blocked. Try to get the locks ourselves to | ||
143 | * prevent a deadlock. | ||
144 | */ | ||
145 | if (vdev->reset_works) { | ||
146 | bool reset_done = false; | ||
147 | |||
148 | if (pci_cfg_access_trylock(pdev)) { | ||
149 | if (device_trylock(&pdev->dev)) { | ||
150 | __pci_reset_function_locked(pdev); | ||
151 | reset_done = true; | ||
152 | device_unlock(&pdev->dev); | ||
153 | } | ||
154 | pci_cfg_access_unlock(pdev); | ||
155 | } | ||
156 | |||
157 | if (!reset_done) | ||
158 | pr_warn("%s: Unable to acquire locks for reset of %s\n", | ||
159 | __func__, dev_name(&pdev->dev)); | ||
160 | } | ||
142 | 161 | ||
143 | pci_restore_state(pdev); | 162 | pci_restore_state(pdev); |
144 | } | 163 | } |