Merge tag 'vfio-v6.1-rc6' of https://github.com/awilliam/linux-vfio
Pull VFIO fixes from Alex Williamson: - Fixes for potential container registration leak for drivers not implementing a close callback, duplicate container de-registrations, and a regression in support for bus reset on last device close from a device set (Anthony DeRossi) * tag 'vfio-v6.1-rc6' of https://github.com/awilliam/linux-vfio: vfio/pci: Check the device set open count on reset vfio: Export the device set open count vfio: Fix container device registration life cycle
This commit is contained in:
@@ -2488,12 +2488,12 @@ static bool vfio_pci_dev_set_needs_reset(struct vfio_device_set *dev_set)
|
||||
struct vfio_pci_core_device *cur;
|
||||
bool needs_reset = false;
|
||||
|
||||
list_for_each_entry(cur, &dev_set->device_list, vdev.dev_set_list) {
|
||||
/* No VFIO device in the set can have an open device FD */
|
||||
if (cur->vdev.open_count)
|
||||
return false;
|
||||
/* No other VFIO device in the set can be open. */
|
||||
if (vfio_device_set_open_count(dev_set) > 1)
|
||||
return false;
|
||||
|
||||
list_for_each_entry(cur, &dev_set->device_list, vdev.dev_set_list)
|
||||
needs_reset |= cur->needs_reset;
|
||||
}
|
||||
return needs_reset;
|
||||
}
|
||||
|
||||
|
||||
@@ -125,6 +125,19 @@ static void vfio_release_device_set(struct vfio_device *device)
|
||||
xa_unlock(&vfio_device_set_xa);
|
||||
}
|
||||
|
||||
unsigned int vfio_device_set_open_count(struct vfio_device_set *dev_set)
|
||||
{
|
||||
struct vfio_device *cur;
|
||||
unsigned int open_count = 0;
|
||||
|
||||
lockdep_assert_held(&dev_set->lock);
|
||||
|
||||
list_for_each_entry(cur, &dev_set->device_list, dev_set_list)
|
||||
open_count += cur->open_count;
|
||||
return open_count;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vfio_device_set_open_count);
|
||||
|
||||
/*
|
||||
* Group objects - create, release, get, put, search
|
||||
*/
|
||||
@@ -801,8 +814,9 @@ static struct file *vfio_device_open(struct vfio_device *device)
|
||||
err_close_device:
|
||||
mutex_lock(&device->dev_set->lock);
|
||||
mutex_lock(&device->group->group_lock);
|
||||
if (device->open_count == 1 && device->ops->close_device) {
|
||||
device->ops->close_device(device);
|
||||
if (device->open_count == 1) {
|
||||
if (device->ops->close_device)
|
||||
device->ops->close_device(device);
|
||||
|
||||
vfio_device_container_unregister(device);
|
||||
}
|
||||
@@ -1017,10 +1031,12 @@ static int vfio_device_fops_release(struct inode *inode, struct file *filep)
|
||||
mutex_lock(&device->dev_set->lock);
|
||||
vfio_assert_device_open(device);
|
||||
mutex_lock(&device->group->group_lock);
|
||||
if (device->open_count == 1 && device->ops->close_device)
|
||||
device->ops->close_device(device);
|
||||
if (device->open_count == 1) {
|
||||
if (device->ops->close_device)
|
||||
device->ops->close_device(device);
|
||||
|
||||
vfio_device_container_unregister(device);
|
||||
vfio_device_container_unregister(device);
|
||||
}
|
||||
mutex_unlock(&device->group->group_lock);
|
||||
device->open_count--;
|
||||
if (device->open_count == 0)
|
||||
|
||||
@@ -189,6 +189,7 @@ int vfio_register_emulated_iommu_dev(struct vfio_device *device);
|
||||
void vfio_unregister_group_dev(struct vfio_device *device);
|
||||
|
||||
int vfio_assign_device_set(struct vfio_device *device, void *set_id);
|
||||
unsigned int vfio_device_set_open_count(struct vfio_device_set *dev_set);
|
||||
|
||||
int vfio_mig_get_next_state(struct vfio_device *device,
|
||||
enum vfio_device_mig_state cur_fsm,
|
||||
|
||||
Reference in New Issue
Block a user