]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
iommufd: Allow iommufd to supply /dev/vfio/vfio
authorJason Gunthorpe <jgg@nvidia.com>
Tue, 29 Nov 2022 20:31:55 +0000 (16:31 -0400)
committerJason Gunthorpe <jgg@nvidia.com>
Fri, 2 Dec 2022 15:52:04 +0000 (11:52 -0400)
If the VFIO container is compiled out, give a kconfig option for iommufd
to provide the miscdev node with the same name and permissions as vfio
uses.

The compatibility node supports the same ioctls as VFIO and automatically
enables the VFIO compatible pinned page accounting mode.

Link: https://lore.kernel.org/r/10-v4-42cd2eb0e3eb+335a-vfio_iommufd_jgg@nvidia.com
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Yi Liu <yi.l.liu@intel.com>
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
Tested-by: Alex Williamson <alex.williamson@redhat.com>
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
Tested-by: Yi Liu <yi.l.liu@intel.com>
Tested-by: Lixiao Yang <lixiao.yang@intel.com>
Tested-by: Matthew Rosato <mjrosato@linux.ibm.com>
Tested-by: Yu He <yu.he@intel.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
drivers/iommu/iommufd/Kconfig
drivers/iommu/iommufd/main.c

index 871244f2443fbb01bf5429e17b561e466f0838f2..8306616b6d819802f1c8f8c1807d35506316bca6 100644 (file)
@@ -12,6 +12,26 @@ config IOMMUFD
          If you don't know what to do here, say N.
 
 if IOMMUFD
+config IOMMUFD_VFIO_CONTAINER
+       bool "IOMMUFD provides the VFIO container /dev/vfio/vfio"
+       depends on VFIO && !VFIO_CONTAINER
+       default VFIO && !VFIO_CONTAINER
+       help
+         IOMMUFD will provide /dev/vfio/vfio instead of VFIO. This relies on
+         IOMMUFD providing compatibility emulation to give the same ioctls.
+         It provides an option to build a kernel with legacy VFIO components
+         removed.
+
+         IOMMUFD VFIO container emulation is known to lack certain features
+         of the native VFIO container, such as no-IOMMU support, peer-to-peer
+         DMA mapping, PPC IOMMU support, as well as other potentially
+         undiscovered gaps.  This option is currently intended for the
+         purpose of testing IOMMUFD with unmodified userspace supporting VFIO
+         and making use of the Type1 VFIO IOMMU backend.  General purpose
+         enabling of this option is currently discouraged.
+
+         Unless testing IOMMUFD, say N here.
+
 config IOMMUFD_TEST
        bool "IOMMU Userspace API Test support"
        depends on DEBUG_KERNEL
index bcb463e581009c3bff155e80e1f916b2f500db2d..083e6fcbe10ad92b5214099da4e7e892734dd8aa 100644 (file)
@@ -18,6 +18,7 @@
 #include <uapi/linux/iommufd.h>
 #include <linux/iommufd.h>
 
+#include "io_pagetable.h"
 #include "iommufd_private.h"
 #include "iommufd_test.h"
 
@@ -25,6 +26,7 @@ struct iommufd_object_ops {
        void (*destroy)(struct iommufd_object *obj);
 };
 static const struct iommufd_object_ops iommufd_object_ops[];
+static struct miscdevice vfio_misc_dev;
 
 struct iommufd_object *_iommufd_object_alloc(struct iommufd_ctx *ictx,
                                             size_t size,
@@ -170,6 +172,16 @@ static int iommufd_fops_open(struct inode *inode, struct file *filp)
        if (!ictx)
                return -ENOMEM;
 
+       /*
+        * For compatibility with VFIO when /dev/vfio/vfio is opened we default
+        * to the same rlimit accounting as vfio uses.
+        */
+       if (IS_ENABLED(CONFIG_IOMMUFD_VFIO_CONTAINER) &&
+           filp->private_data == &vfio_misc_dev) {
+               ictx->account_mode = IOPT_PAGES_ACCOUNT_MM;
+               pr_info_once("IOMMUFD is providing /dev/vfio/vfio, not VFIO.\n");
+       }
+
        xa_init_flags(&ictx->objects, XA_FLAGS_ALLOC1 | XA_FLAGS_ACCOUNT);
        ictx->file = filp;
        filp->private_data = ictx;
@@ -400,6 +412,15 @@ static struct miscdevice iommu_misc_dev = {
        .mode = 0660,
 };
 
+
+static struct miscdevice vfio_misc_dev = {
+       .minor = VFIO_MINOR,
+       .name = "vfio",
+       .fops = &iommufd_fops,
+       .nodename = "vfio/vfio",
+       .mode = 0666,
+};
+
 static int __init iommufd_init(void)
 {
        int ret;
@@ -407,18 +428,33 @@ static int __init iommufd_init(void)
        ret = misc_register(&iommu_misc_dev);
        if (ret)
                return ret;
+
+       if (IS_ENABLED(CONFIG_IOMMUFD_VFIO_CONTAINER)) {
+               ret = misc_register(&vfio_misc_dev);
+               if (ret)
+                       goto err_misc;
+       }
        iommufd_test_init();
        return 0;
+err_misc:
+       misc_deregister(&iommu_misc_dev);
+       return ret;
 }
 
 static void __exit iommufd_exit(void)
 {
        iommufd_test_exit();
+       if (IS_ENABLED(CONFIG_IOMMUFD_VFIO_CONTAINER))
+               misc_deregister(&vfio_misc_dev);
        misc_deregister(&iommu_misc_dev);
 }
 
 module_init(iommufd_init);
 module_exit(iommufd_exit);
 
+#if IS_ENABLED(CONFIG_IOMMUFD_VFIO_CONTAINER)
+MODULE_ALIAS_MISCDEV(VFIO_MINOR);
+MODULE_ALIAS("devname:vfio/vfio");
+#endif
 MODULE_DESCRIPTION("I/O Address Space Management for passthrough devices");
 MODULE_LICENSE("GPL");