提交 3df765fc 编写于 作者: L 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
......@@ -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);
}
......
......@@ -494,27 +494,6 @@ static int vfio_group_nb_add_dev(struct vfio_group *group, struct device *dev)
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)
{
/* 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,
struct device *dev = data;
/*
* Need to go through a group_lock lookup to get a reference or
* we risk racing a group being removed. Leave a WARN_ON for
* debuging, but if the group no longer exists, a spurious notify
* is harmless.
* Need to go through a group_lock lookup to get a reference or we
* risk racing a group being removed. Ignore spurious notifies.
*/
group = vfio_group_try_get(group);
if (WARN_ON(!group))
if (!group)
return NOTIFY_OK;
switch (action) {
......@@ -545,7 +522,13 @@ static int vfio_iommu_group_notifier(struct notifier_block *nb,
vfio_group_nb_add_dev(group, dev);
break;
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;
case IOMMU_GROUP_NOTIFY_BIND_DRIVER:
pr_debug("%s: Device %s, group %d binding to driver\n",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册