Skip to content

Commit 3df765f

Browse files
committed
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
2 parents 19788a9 + d24cdbf commit 3df765f

2 files changed

Lines changed: 31 additions & 29 deletions

File tree

drivers/vfio/pci/vfio_pci.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,27 @@ static void vfio_pci_disable(struct vfio_pci_device *vdev)
137137
*/
138138
pci_write_config_word(pdev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE);
139139

140-
if (vdev->reset_works)
141-
__pci_reset_function(pdev);
140+
/*
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+
}
142161

143162
pci_restore_state(pdev);
144163
}

drivers/vfio/vfio.c

Lines changed: 10 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -494,27 +494,6 @@ static int vfio_group_nb_add_dev(struct vfio_group *group, struct device *dev)
494494
return 0;
495495
}
496496

497-
static int vfio_group_nb_del_dev(struct vfio_group *group, struct device *dev)
498-
{
499-
struct vfio_device *device;
500-
501-
/*
502-
* Expect to fall out here. If a device was in use, it would
503-
* have been bound to a vfio sub-driver, which would have blocked
504-
* in .remove at vfio_del_group_dev. Sanity check that we no
505-
* longer track the device, so it's safe to remove.
506-
*/
507-
device = vfio_group_get_device(group, dev);
508-
if (likely(!device))
509-
return 0;
510-
511-
WARN("Device %s removed from live group %d!\n", dev_name(dev),
512-
iommu_group_id(group->iommu_group));
513-
514-
vfio_device_put(device);
515-
return 0;
516-
}
517-
518497
static int vfio_group_nb_verify(struct vfio_group *group, struct device *dev)
519498
{
520499
/* We don't care what happens when the group isn't in use */
@@ -531,21 +510,25 @@ static int vfio_iommu_group_notifier(struct notifier_block *nb,
531510
struct device *dev = data;
532511

533512
/*
534-
* Need to go through a group_lock lookup to get a reference or
535-
* we risk racing a group being removed. Leave a WARN_ON for
536-
* debuging, but if the group no longer exists, a spurious notify
537-
* is harmless.
513+
* Need to go through a group_lock lookup to get a reference or we
514+
* risk racing a group being removed. Ignore spurious notifies.
538515
*/
539516
group = vfio_group_try_get(group);
540-
if (WARN_ON(!group))
517+
if (!group)
541518
return NOTIFY_OK;
542519

543520
switch (action) {
544521
case IOMMU_GROUP_NOTIFY_ADD_DEVICE:
545522
vfio_group_nb_add_dev(group, dev);
546523
break;
547524
case IOMMU_GROUP_NOTIFY_DEL_DEVICE:
548-
vfio_group_nb_del_dev(group, dev);
525+
/*
526+
* Nothing to do here. If the device is in use, then the
527+
* vfio sub-driver should block the remove callback until
528+
* it is unused. If the device is unused or attached to a
529+
* stub driver, then it should be released and we don't
530+
* care that it will be going away.
531+
*/
549532
break;
550533
case IOMMU_GROUP_NOTIFY_BIND_DRIVER:
551534
pr_debug("%s: Device %s, group %d binding to driver\n",

0 commit comments

Comments
 (0)