summaryrefslogtreecommitdiffstats
path: root/drivers/vfio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/vfio')
-rw-r--r--drivers/vfio/vfio_main.c33
1 files changed, 10 insertions, 23 deletions
diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c
index 6d51b700764e..f913d862a386 100644
--- a/drivers/vfio/vfio_main.c
+++ b/drivers/vfio/vfio_main.c
@@ -143,10 +143,12 @@ EXPORT_SYMBOL_GPL(vfio_device_set_open_count);
* Group objects - create, release, get, put, search
*/
static struct vfio_group *
-__vfio_group_get_from_iommu(struct iommu_group *iommu_group)
+vfio_group_get_from_iommu(struct iommu_group *iommu_group)
{
struct vfio_group *group;
+ lockdep_assert_held(&vfio.group_lock);
+
/*
* group->iommu_group from the vfio.group_list cannot be NULL
* under the vfio.group_lock.
@@ -160,17 +162,6 @@ __vfio_group_get_from_iommu(struct iommu_group *iommu_group)
return NULL;
}
-static struct vfio_group *
-vfio_group_get_from_iommu(struct iommu_group *iommu_group)
-{
- struct vfio_group *group;
-
- mutex_lock(&vfio.group_lock);
- group = __vfio_group_get_from_iommu(iommu_group);
- mutex_unlock(&vfio.group_lock);
- return group;
-}
-
static void vfio_group_release(struct device *dev)
{
struct vfio_group *group = container_of(dev, struct vfio_group, dev);
@@ -225,6 +216,8 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group,
struct vfio_group *ret;
int err;
+ lockdep_assert_held(&vfio.group_lock);
+
group = vfio_group_alloc(iommu_group, type);
if (IS_ERR(group))
return group;
@@ -237,26 +230,16 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group,
goto err_put;
}
- mutex_lock(&vfio.group_lock);
-
- /* Did we race creating this group? */
- ret = __vfio_group_get_from_iommu(iommu_group);
- if (ret)
- goto err_unlock;
-
err = cdev_device_add(&group->cdev, &group->dev);
if (err) {
ret = ERR_PTR(err);
- goto err_unlock;
+ goto err_put;
}
list_add(&group->vfio_next, &vfio.group_list);
- mutex_unlock(&vfio.group_lock);
return group;
-err_unlock:
- mutex_unlock(&vfio.group_lock);
err_put:
put_device(&group->dev);
return ret;
@@ -467,7 +450,9 @@ static struct vfio_group *vfio_noiommu_group_alloc(struct device *dev,
if (ret)
goto out_put_group;
+ mutex_lock(&vfio.group_lock);
group = vfio_create_group(iommu_group, type);
+ mutex_unlock(&vfio.group_lock);
if (IS_ERR(group)) {
ret = PTR_ERR(group);
goto out_remove_device;
@@ -516,9 +501,11 @@ static struct vfio_group *vfio_group_find_or_alloc(struct device *dev)
return ERR_PTR(-EINVAL);
}
+ mutex_lock(&vfio.group_lock);
group = vfio_group_get_from_iommu(iommu_group);
if (!group)
group = vfio_create_group(iommu_group, VFIO_IOMMU);
+ mutex_unlock(&vfio.group_lock);
/* The vfio_group holds a reference to the iommu_group */
iommu_group_put(iommu_group);