Commit e01d50cb authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
parents 9584987f e806e223
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -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)
	/* 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;
}

+21 −5
Original line number Diff line number Diff line
@@ -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,7 +814,8 @@ 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) {
	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)
	if (device->open_count == 1) {
		if (device->ops->close_device)
			device->ops->close_device(device);

		vfio_device_container_unregister(device);
	}
	mutex_unlock(&device->group->group_lock);
	device->open_count--;
	if (device->open_count == 0)
+1 −0
Original line number Diff line number Diff line
@@ -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,