@@ -531,11 +531,11 @@ int vfio_device_assign_container(struct vfio_device *device)
void vfio_device_unassign_container(struct vfio_device *device)
{
- mutex_lock(&device->group->group_lock);
+ lockdep_assert_held_write(&device->group->group_lock);
+
WARN_ON(device->group->container_users <= 1);
device->group->container_users--;
fput(device->group->opened_file);
- mutex_unlock(&device->group->group_lock);
}
/*
@@ -749,18 +749,24 @@ static int vfio_device_first_open(struct vfio_device *device)
* during close_device.
*/
mutex_lock(&device->group->group_lock);
+ ret = vfio_device_assign_container(device);
+ if (ret)
+ goto err_module_put;
+
device->kvm = device->group->kvm;
if (device->ops->open_device) {
ret = device->ops->open_device(device);
if (ret)
- goto err_module_put;
+ goto err_container;
}
vfio_device_container_register(device);
mutex_unlock(&device->group->group_lock);
return 0;
-err_module_put:
+err_container:
device->kvm = NULL;
+ vfio_device_unassign_container(device);
+err_module_put:
mutex_unlock(&device->group->group_lock);
module_put(device->dev->driver->owner);
return ret;
@@ -775,6 +781,7 @@ static void vfio_device_last_close(struct vfio_device *device)
if (device->ops->close_device)
device->ops->close_device(device);
device->kvm = NULL;
+ vfio_device_unassign_container(device);
mutex_unlock(&device->group->group_lock);
module_put(device->dev->driver->owner);
}
@@ -784,18 +791,12 @@ static struct file *vfio_device_open(struct vfio_device *device)
struct file *filep;
int ret;
- mutex_lock(&device->group->group_lock);
- ret = vfio_device_assign_container(device);
- mutex_unlock(&device->group->group_lock);
- if (ret)
- return ERR_PTR(ret);
-
mutex_lock(&device->dev_set->lock);
device->open_count++;
if (device->open_count == 1) {
ret = vfio_device_first_open(device);
if (ret)
- goto err_unassign_container;
+ goto err_unlock;
}
mutex_unlock(&device->dev_set->lock);
@@ -830,10 +831,9 @@ static struct file *vfio_device_open(struct vfio_device *device)
mutex_lock(&device->dev_set->lock);
if (device->open_count == 1)
vfio_device_last_close(device);
-err_unassign_container:
+err_unlock:
device->open_count--;
mutex_unlock(&device->dev_set->lock);
- vfio_device_unassign_container(device);
return ERR_PTR(ret);
}
@@ -1040,8 +1040,6 @@ static int vfio_device_fops_release(struct inode *inode, struct file *filep)
device->open_count--;
mutex_unlock(&device->dev_set->lock);
- vfio_device_unassign_container(device);
-
vfio_device_put_registration(device);
return 0;