Skip to content

Commit

Permalink
Merge tag 'vfio-v6.1-rc6' of https://github.com/awilliam/linux-vfio
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Linus Torvalds committed Nov 14, 2022
2 parents 9584987 + e806e22 commit e01d50c
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 10 deletions.
10 changes: 5 additions & 5 deletions drivers/vfio/pci/vfio_pci_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
26 changes: 21 additions & 5 deletions drivers/vfio/vfio_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions include/linux/vfio.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit e01d50c

Please sign in to comment.