Skip to content

Commit

Permalink
vfio: Add iommufd VFIO compat support to group_fd
Browse files Browse the repository at this point in the history
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 <nicolinc@nvidia.com>
Signed-off-by: Yi Liu <yi.l.liu@intel.com>
  • Loading branch information
nicolinc authored and yiliu1765 committed Mar 17, 2022
1 parent 8a8452c commit a7d1827
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 3 deletions.
3 changes: 2 additions & 1 deletion drivers/iommu/iommufd/vfio_compat.c
Expand Up @@ -153,7 +153,7 @@ static int iommufd_vfio_unmap_dma(struct iommufd_ctx *ictx, unsigned int cmd,
return rc;
}

static int iommufd_vfio_check_extension(unsigned long type)
int iommufd_vfio_check_extension(unsigned long type)
{
switch (type) {
case VFIO_TYPE1v2_IOMMU:
Expand Down Expand Up @@ -205,6 +205,7 @@ static int iommufd_vfio_check_extension(unsigned long type)
* review along side HW drivers implementing it.
*/
}
EXPORT_SYMBOL_GPL(iommufd_vfio_check_extension);

static int iommufd_vfio_set_iommu(struct iommufd_ctx *ictx, unsigned long type)
{
Expand Down
1 change: 1 addition & 0 deletions drivers/vfio/Kconfig
Expand Up @@ -2,6 +2,7 @@
menuconfig VFIO
tristate "VFIO Non-Privileged userspace driver framework"
select IOMMU_API
select IOMMUFD if MMU && (X86 || S390 || ARM || ARM64)
select VFIO_IOMMU_TYPE1 if MMU && (X86 || S390 || ARM || ARM64)
help
VFIO provides a framework for secure userspace device drivers.
Expand Down
22 changes: 20 additions & 2 deletions drivers/vfio/vfio.c
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -1210,7 +1224,7 @@ static int vfio_group_add_container_user(struct vfio_group *group)
atomic_dec(&group->container_users);
return -EPERM;
}
if (!group->container->iommu_driver) {
if ((group->container && !group->container->iommu_driver) || !group->iommufd) {
atomic_dec(&group->container_users);
return -EINVAL;
}
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -1775,6 +1790,9 @@ EXPORT_SYMBOL_GPL(vfio_external_user_iommu_id);

long vfio_external_check_extension(struct vfio_group *group, unsigned long arg)
{
if (group->iommufd)
return iommufd_vfio_check_extension(arg);

return vfio_ioctl_check_extension(group->container, arg);
}
EXPORT_SYMBOL_GPL(vfio_external_check_extension);
Expand Down
6 changes: 6 additions & 0 deletions include/linux/iommufd.h
Expand Up @@ -31,6 +31,7 @@ void iommufd_device_detach(struct iommufd_device *idev);

struct iommufd_ctx *vfio_group_set_iommufd(int fd, struct list_head *device_list);
void vfio_group_unset_iommufd(void *iommufd, struct list_head *device_list);
int iommufd_vfio_check_extension(unsigned long type);
#else /* !CONFIG_IOMMUFD */
static inline struct iommufd_device *
iommufd_bind_pci_device(int fd, struct pci_dev *pdev, u32 *id)
Expand Down Expand Up @@ -62,5 +63,10 @@ static inline void vfio_group_unset_iommufd(void *iommufd,
struct list_head *device_list)
{
}

static int iommufd_vfio_check_extension(unsigned long type)
{
return -EOPNOTSUPP;
}
#endif /* CONFIG_IOMMUFD */
#endif

0 comments on commit a7d1827

Please sign in to comment.