diff options
| author | Jason Gunthorpe <jgg@nvidia.com> | 2023-01-18 13:50:28 -0400 |
|---|---|---|
| committer | Jason Gunthorpe <jgg@nvidia.com> | 2023-02-03 15:45:23 -0400 |
| commit | c9a397cee9f5c93a7f48e18038b14057044db6ba (patch) | |
| tree | 8b7e0c201d5e50562c6fc0c553da53fd37dfd980 /drivers/vfio/iommufd.c | |
| parent | b7bfaa761d760e72a969d116517eaa12e404c262 (diff) | |
vfio: Support VFIO_NOIOMMU with iommufd
Add a small amount of emulation to vfio_compat to accept the SET_IOMMU to
VFIO_NOIOMMU_IOMMU and have vfio just ignore iommufd if it is working on a
no-iommu enabled device.
Move the enable_unsafe_noiommu_mode module out of container.c into
vfio_main.c so that it is always available even if VFIO_CONTAINER=n.
This passes Alex's mini-test:
https://github.com/awilliam/tests/blob/master/vfio-noiommu-pci-device-open.c
Link: https://lore.kernel.org/r/0-v3-480cd64a16f7+1ad0-iommufd_noiommu_jgg@nvidia.com
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Acked-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Diffstat (limited to 'drivers/vfio/iommufd.c')
| -rw-r--r-- | drivers/vfio/iommufd.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/vfio/iommufd.c b/drivers/vfio/iommufd.c index 4f82a6fa7c6c..db4efbd56042 100644 --- a/drivers/vfio/iommufd.c +++ b/drivers/vfio/iommufd.c @@ -18,6 +18,20 @@ int vfio_iommufd_bind(struct vfio_device *vdev, struct iommufd_ctx *ictx) lockdep_assert_held(&vdev->dev_set->lock); + if (vfio_device_is_noiommu(vdev)) { + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; + + /* + * Require no compat ioas to be assigned to proceed. The basic + * statement is that the user cannot have done something that + * implies they expected translation to exist + */ + if (!iommufd_vfio_compat_ioas_get_id(ictx, &ioas_id)) + return -EPERM; + return 0; + } + /* * If the driver doesn't provide this op then it means the device does * not do DMA at all. So nothing to do. @@ -29,7 +43,7 @@ int vfio_iommufd_bind(struct vfio_device *vdev, struct iommufd_ctx *ictx) if (ret) return ret; - ret = iommufd_vfio_compat_ioas_id(ictx, &ioas_id); + ret = iommufd_vfio_compat_ioas_get_id(ictx, &ioas_id); if (ret) goto err_unbind; ret = vdev->ops->attach_ioas(vdev, &ioas_id); @@ -52,6 +66,9 @@ void vfio_iommufd_unbind(struct vfio_device *vdev) { lockdep_assert_held(&vdev->dev_set->lock); + if (vfio_device_is_noiommu(vdev)) + return; + if (vdev->ops->unbind_iommufd) vdev->ops->unbind_iommufd(vdev); } |