Commit 3df765fc authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'vfio-v3.11-rc4' of git://github.com/awilliam/linux-vfio

Pull vfio fixes from Alex Williamson:
 "misc fixes around overreacting to bus notifier events and a locking
  fix for a corner case blocked remove"

* tag 'vfio-v3.11-rc4' of git://github.com/awilliam/linux-vfio:
  vfio-pci: Avoid deadlock on remove
  vfio: Ignore sprurious notifies
  vfio: Don't overreact to DEL_DEVICE
parents 19788a90 d24cdbfd
...@@ -137,8 +137,27 @@ static void vfio_pci_disable(struct vfio_pci_device *vdev) ...@@ -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); 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); pci_restore_state(pdev);
} }
......
...@@ -494,27 +494,6 @@ static int vfio_group_nb_add_dev(struct vfio_group *group, struct device *dev) ...@@ -494,27 +494,6 @@ static int vfio_group_nb_add_dev(struct vfio_group *group, struct device *dev)
return 0; return 0;
} }
static int vfio_group_nb_del_dev(struct vfio_group *group, struct device *dev)
{
struct vfio_device *device;
/*
* Expect to fall out here. If a device was in use, it would
* have been bound to a vfio sub-driver, which would have blocked
* in .remove at vfio_del_group_dev. Sanity check that we no
* longer track the device, so it's safe to remove.
*/
device = vfio_group_get_device(group, dev);
if (likely(!device))
return 0;
WARN("Device %s removed from live group %d!\n", dev_name(dev),
iommu_group_id(group->iommu_group));
vfio_device_put(device);
return 0;
}
static int vfio_group_nb_verify(struct vfio_group *group, struct device *dev) static int vfio_group_nb_verify(struct vfio_group *group, struct device *dev)
{ {
/* We don't care what happens when the group isn't in use */ /* We don't care what happens when the group isn't in use */
...@@ -531,13 +510,11 @@ static int vfio_iommu_group_notifier(struct notifier_block *nb, ...@@ -531,13 +510,11 @@ static int vfio_iommu_group_notifier(struct notifier_block *nb,
struct device *dev = data; struct device *dev = data;
/* /*
* Need to go through a group_lock lookup to get a reference or * Need to go through a group_lock lookup to get a reference or we
* we risk racing a group being removed. Leave a WARN_ON for * risk racing a group being removed. Ignore spurious notifies.
* debuging, but if the group no longer exists, a spurious notify
* is harmless.
*/ */
group = vfio_group_try_get(group); group = vfio_group_try_get(group);
if (WARN_ON(!group)) if (!group)
return NOTIFY_OK; return NOTIFY_OK;
switch (action) { switch (action) {
...@@ -545,7 +522,13 @@ static int vfio_iommu_group_notifier(struct notifier_block *nb, ...@@ -545,7 +522,13 @@ static int vfio_iommu_group_notifier(struct notifier_block *nb,
vfio_group_nb_add_dev(group, dev); vfio_group_nb_add_dev(group, dev);
break; break;
case IOMMU_GROUP_NOTIFY_DEL_DEVICE: case IOMMU_GROUP_NOTIFY_DEL_DEVICE:
vfio_group_nb_del_dev(group, dev); /*
* Nothing to do here. If the device is in use, then the
* vfio sub-driver should block the remove callback until
* it is unused. If the device is unused or attached to a
* stub driver, then it should be released and we don't
* care that it will be going away.
*/
break; break;
case IOMMU_GROUP_NOTIFY_BIND_DRIVER: case IOMMU_GROUP_NOTIFY_BIND_DRIVER:
pr_debug("%s: Device %s, group %d binding to driver\n", pr_debug("%s: Device %s, group %d binding to driver\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment