struct vfio_container *container = group->container;
        struct vfio_iommu_driver *driver;
 
+       lockdep_assert_held_write(&group->group_rwsem);
+
        down_write(&container->group_lock);
 
        driver = container->iommu_driver;
 {
        int users = atomic_cmpxchg(&group->container_users, 1, 0);
 
+       lockdep_assert_held_write(&group->group_rwsem);
+
        if (!users)
                return -EINVAL;
        if (users != 1)
  */
 static void vfio_group_try_dissolve_container(struct vfio_group *group)
 {
+       down_write(&group->group_rwsem);
        if (0 == atomic_dec_if_positive(&group->container_users))
                __vfio_group_unset_container(group);
+       up_write(&group->group_rwsem);
 }
 
 static int vfio_group_set_container(struct vfio_group *group, int container_fd)
        struct vfio_iommu_driver *driver;
        int ret = 0;
 
+       lockdep_assert_held_write(&group->group_rwsem);
+
        if (atomic_read(&group->container_users))
                return -EINVAL;
 
        return ret;
 }
 
-static int vfio_group_add_container_user(struct vfio_group *group)
-{
-       if (!atomic_inc_not_zero(&group->container_users))
-               return -EINVAL;
-
-       if (group->type == VFIO_NO_IOMMU) {
-               atomic_dec(&group->container_users);
-               return -EPERM;
-       }
-       if (!group->container->iommu_driver) {
-               atomic_dec(&group->container_users);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
 static const struct file_operations vfio_device_fops;
 
 /* true if the vfio_device has open_device() called but not close_device() */
 {
        struct vfio_group *group = device->group;
 
+       lockdep_assert_held_write(&group->group_rwsem);
+
        if (0 == atomic_read(&group->container_users) ||
            !group->container->iommu_driver)
                return -EINVAL;
        struct file *filep;
        int ret;
 
+       down_write(&device->group->group_rwsem);
        ret = vfio_device_assign_container(device);
+       up_write(&device->group->group_rwsem);
        if (ret)
                return ERR_PTR(ret);
 
 
                status.flags = 0;
 
+               down_read(&group->group_rwsem);
                if (group->container)
                        status.flags |= VFIO_GROUP_FLAGS_CONTAINER_SET |
                                        VFIO_GROUP_FLAGS_VIABLE;
                else if (!iommu_group_dma_owner_claimed(group->iommu_group))
                        status.flags |= VFIO_GROUP_FLAGS_VIABLE;
+               up_read(&group->group_rwsem);
 
                if (copy_to_user((void __user *)arg, &status, minsz))
                        return -EFAULT;
                if (fd < 0)
                        return -EINVAL;
 
+               down_write(&group->group_rwsem);
                ret = vfio_group_set_container(group, fd);
+               up_write(&group->group_rwsem);
                break;
        }
        case VFIO_GROUP_UNSET_CONTAINER:
+               down_write(&group->group_rwsem);
                ret = vfio_group_unset_container(group);
+               up_write(&group->group_rwsem);
                break;
        case VFIO_GROUP_GET_DEVICE_FD:
        {
        if (file->f_op != &vfio_group_fops)
                return true;
 
-       /*
-        * Since the coherency state is determined only once a container is
-        * attached the user must do so before they can prove they have
-        * permission.
-        */
-       if (vfio_group_add_container_user(group))
-               return true;
-       ret = vfio_ioctl_check_extension(group->container, VFIO_DMA_CC_IOMMU);
-       vfio_group_try_dissolve_container(group);
+       down_read(&group->group_rwsem);
+       if (group->container) {
+               ret = vfio_ioctl_check_extension(group->container,
+                                                VFIO_DMA_CC_IOMMU);
+       } else {
+               /*
+                * Since the coherency state is determined only once a container
+                * is attached the user must do so before they can prove they
+                * have permission.
+                */
+               ret = true;
+       }
+       up_read(&group->group_rwsem);
        return ret;
 }
 EXPORT_SYMBOL_GPL(vfio_file_enforced_coherent);
        if (group->dev_counter > 1)
                return -EINVAL;
 
+       /* group->container cannot change while a vfio device is open */
        container = group->container;
        driver = container->iommu_driver;
        if (likely(driver && driver->ops->pin_pages))
        if (npage > VFIO_PIN_PAGES_MAX_ENTRIES)
                return -E2BIG;
 
+       /* group->container cannot change while a vfio device is open */
        container = device->group->container;
        driver = container->iommu_driver;
        if (likely(driver && driver->ops->unpin_pages))
        if (!data || len <= 0 || !vfio_assert_device_open(device))
                return -EINVAL;
 
+       /* group->container cannot change while a vfio device is open */
        container = device->group->container;
        driver = container->iommu_driver;
 
        struct vfio_iommu_driver *driver;
        int ret;
 
+       down_read(&group->group_rwsem);
        container = group->container;
        driver = container->iommu_driver;
        if (likely(driver && driver->ops->register_notifier))
                                                     events, nb);
        else
                ret = -ENOTTY;
+       up_read(&group->group_rwsem);
+
        return ret;
 }
 
        struct vfio_iommu_driver *driver;
        int ret;
 
+       down_read(&group->group_rwsem);
        container = group->container;
        driver = container->iommu_driver;
        if (likely(driver && driver->ops->unregister_notifier))
                                                       nb);
        else
                ret = -ENOTTY;
+       up_read(&group->group_rwsem);
+
        return ret;
 }