vfio: misc fixes around overreacting to bus notifier events and a locking fix for a corner case blocked remove.
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.13 (GNU/Linux) iQIcBAABAgAGBQJR+AppAAoJECObm247sIsimnoQAJf2pQjh47ai+Wv5ezN8hSZy rg56lhg3RMOHjTjLrKbPfjMLbLxD7rwlRZwu8RHVlhnz4ICEKy4DG0ZpeJ6j06TZ AMa4F/rlTysF1ZebzSAnB/Agkss8OFXVUJshA62UE3IzsjyAQzXrwOn3nyAXsgCV JTUAAewOV3DivTP2d8V3rDh/rS64eXp4cKf5z8iyPnOfiBzCbSxWcz2SmHVOh1nX rMXIM8zvKLhKH0lzC+xm88/lC6rUKwJrnAHVR6TR+OJsnrqB14SDsfjg6wt4JP/4 e0NGD7YO9GHh20TjnIjF1VnUu2hG/Y7bpAuRhlterVDjDyKBhVIxIImF8GEMl+NB f9aNEx4KgotTr9lQFp96ixVsN/y/B9Slv35LGPZIcf014iWpG6pdV59xIXVC3Fsr oMyV9R7jaGoQ49k9wgxRG0eVXREFykKIAPW7dqijc6XrcZzyGcF/nBGaRLuCstcR VskjNMndQlnEBJVqiarFVHdsDr7Qo01oqIaSnAtappZNAMpPladeY/ebikbzDUKY VmrBqQjgDHhUoOws791IQaB8I0Ya31wCml7mHC2IfgJ2ZzzXS5Grlq3KjTW0zkTv 1cD7eB9tMQAvqDdZISUAdb73f1vGpBthDjFdO+UudtXkM8rPww5ShqovTeLWYdta 2d+5MVdbqMIyNxo7rK8t =yYAu -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
3df765fc65
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue