aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/vfio
diff options
context:
space:
mode:
authorJason Gunthorpe <jgg@nvidia.com>2023-02-03 15:45:57 -0400
committerJason Gunthorpe <jgg@nvidia.com>2023-02-03 15:55:49 -0400
commitbed9e516f1183faa0e484479701cc669efd9049a (patch)
tree530effa39d2ff59766340cd7d8628cf1acb7164e /drivers/vfio
parentfd9f2a912255106d3b53163d816a4bd99ba29664 (diff)
parentc9a397cee9f5c93a7f48e18038b14057044db6ba (diff)
downloadlinux-bed9e516f1183faa0e484479701cc669efd9049a.tar.gz
Merge branch 'vfio-no-iommu' into iommufd.git for-next
Shared branch with VFIO for the no-iommu support. Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Diffstat (limited to 'drivers/vfio')
-rw-r--r--drivers/vfio/Kconfig2
-rw-r--r--drivers/vfio/container.c7
-rw-r--r--drivers/vfio/group.c7
-rw-r--r--drivers/vfio/iommufd.c19
-rw-r--r--drivers/vfio/vfio.h8
-rw-r--r--drivers/vfio/vfio_main.c7
6 files changed, 38 insertions, 12 deletions
diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig
index a8f5446294674..89e06c981e435 100644
--- a/drivers/vfio/Kconfig
+++ b/drivers/vfio/Kconfig
@@ -32,6 +32,7 @@ config VFIO_IOMMU_SPAPR_TCE
tristate
depends on SPAPR_TCE_IOMMU
default VFIO
+endif
config VFIO_NOIOMMU
bool "VFIO No-IOMMU support"
@@ -46,7 +47,6 @@ config VFIO_NOIOMMU
this mode since there is no IOMMU to provide DMA translation.
If you don't know what to do here, say N.
-endif
config VFIO_VIRQFD
bool
diff --git a/drivers/vfio/container.c b/drivers/vfio/container.c
index b7a9560ab25e4..89f10becf9625 100644
--- a/drivers/vfio/container.c
+++ b/drivers/vfio/container.c
@@ -29,13 +29,6 @@ static struct vfio {
struct mutex iommu_drivers_lock;
} vfio;
-#ifdef CONFIG_VFIO_NOIOMMU
-bool vfio_noiommu __read_mostly;
-module_param_named(enable_unsafe_noiommu_mode,
- vfio_noiommu, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(enable_unsafe_noiommu_mode, "Enable UNSAFE, no-IOMMU mode. This mode provides no device isolation, no DMA translation, no host kernel protection, cannot be used for device assignment to virtual machines, requires RAWIO permissions, and will taint the kernel. If you do not know what this is for, step away. (default: false)");
-#endif
-
static void *vfio_noiommu_open(unsigned long arg)
{
if (arg != VFIO_NOIOMMU_IOMMU)
diff --git a/drivers/vfio/group.c b/drivers/vfio/group.c
index bb24b2f0271e0..e166ad7ce6e75 100644
--- a/drivers/vfio/group.c
+++ b/drivers/vfio/group.c
@@ -133,9 +133,12 @@ static int vfio_group_ioctl_set_container(struct vfio_group *group,
iommufd = iommufd_ctx_from_file(f.file);
if (!IS_ERR(iommufd)) {
- u32 ioas_id;
+ if (IS_ENABLED(CONFIG_VFIO_NOIOMMU) &&
+ group->type == VFIO_NO_IOMMU)
+ ret = iommufd_vfio_compat_set_no_iommu(iommufd);
+ else
+ ret = iommufd_vfio_compat_ioas_create(iommufd);
- ret = iommufd_vfio_compat_ioas_id(iommufd, &ioas_id);
if (ret) {
iommufd_ctx_put(group->iommufd);
goto out_unlock;
diff --git a/drivers/vfio/iommufd.c b/drivers/vfio/iommufd.c
index 4f82a6fa7c6c7..db4efbd560425 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);
}
diff --git a/drivers/vfio/vfio.h b/drivers/vfio/vfio.h
index f8219a438bfbf..9e94abcf8ee1a 100644
--- a/drivers/vfio/vfio.h
+++ b/drivers/vfio/vfio.h
@@ -10,10 +10,10 @@
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/module.h>
+#include <linux/vfio.h>
struct iommufd_ctx;
struct iommu_group;
-struct vfio_device;
struct vfio_container;
void vfio_device_put_registration(struct vfio_device *device);
@@ -88,6 +88,12 @@ bool vfio_device_has_container(struct vfio_device *device);
int __init vfio_group_init(void);
void vfio_group_cleanup(void);
+static inline bool vfio_device_is_noiommu(struct vfio_device *vdev)
+{
+ return IS_ENABLED(CONFIG_VFIO_NOIOMMU) &&
+ vdev->group->type == VFIO_NO_IOMMU;
+}
+
#if IS_ENABLED(CONFIG_VFIO_CONTAINER)
/* events for the backend driver notify callback */
enum vfio_iommu_notify_type {
diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c
index 5177bb061b17b..90541fc949888 100644
--- a/drivers/vfio/vfio_main.c
+++ b/drivers/vfio/vfio_main.c
@@ -45,6 +45,13 @@ static struct vfio {
struct ida device_ida;
} vfio;
+#ifdef CONFIG_VFIO_NOIOMMU
+bool vfio_noiommu __read_mostly;
+module_param_named(enable_unsafe_noiommu_mode,
+ vfio_noiommu, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(enable_unsafe_noiommu_mode, "Enable UNSAFE, no-IOMMU mode. This mode provides no device isolation, no DMA translation, no host kernel protection, cannot be used for device assignment to virtual machines, requires RAWIO permissions, and will taint the kernel. If you do not know what this is for, step away. (default: false)");
+#endif
+
static DEFINE_XARRAY(vfio_device_set_xa);
int vfio_assign_device_set(struct vfio_device *device, void *set_id)