From 6a340611dcaacc984fb82a265f0a53a28aed80e0 Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Wed, 22 Dec 2021 21:48:18 -0800 Subject: [PATCH] vfio: Add iommufd VFIO compat support to group_fd IOMMUFD has VFIO compatibility so user space can open /dev/iommu to reuse existing VFIO IOMMU ioctls. However, the group_fd used for VFIO_GROUP_SET/UNSET_CONTAINER is still a VFIO thing and is not supported using new IOMMUFD ioctls, which go for an approach of attaching and dettaching a VFIO device directly instead of a VFIO group. In order to fill this gap, IOMMUFD provides a pair of helpers to VFIO to call, so as to bind/unbind all devices in the VFIO group to/from the iommufd and to attach/detach them to/from the ioas. So this patch simply calls those two helpers in cases where user space uses VFIO ioctls on top of /dev/iommu and wants to connect group_fd to that. Signed-off-by: Nicolin Chen Signed-off-by: Liu Yi L --- drivers/vfio/vfio.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index 3b2e87df2e427..a156cbbad52dd 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -84,6 +84,7 @@ struct vfio_group { unsigned int dev_counter; struct kvm *kvm; struct blocking_notifier_head notifier; + void *iommufd; }; #ifdef CONFIG_VFIO_NOIOMMU @@ -1079,6 +1080,12 @@ static void __vfio_group_unset_container(struct vfio_group *group) struct vfio_container *container = group->container; struct vfio_iommu_driver *driver; + if (group->iommufd) { + vfio_group_unset_iommufd(group->iommufd, &group->device_list); + group->iommufd = NULL; + return; + } + down_write(&container->group_lock); driver = container->iommu_driver; @@ -1150,6 +1157,13 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd) if (group->type == VFIO_NO_IOMMU && !capable(CAP_SYS_RAWIO)) return -EPERM; + group->iommufd = vfio_group_set_iommufd(container_fd, + &group->device_list); + if (group->iommufd) { + atomic_inc(&group->container_users); + return ret; + } + f = fdget(container_fd); if (!f.file) return -EBADF; @@ -1261,7 +1275,8 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf) int ret = 0; if (0 == atomic_read(&group->container_users) || - !group->container->iommu_driver) + (group->container && !group->container->iommu_driver) || + (!group->container && !group->iommufd)) return -EINVAL; if (group->type == VFIO_NO_IOMMU && !capable(CAP_SYS_RAWIO))