Commit 169dd5c9 authored by Jason Gunthorpe's avatar Jason Gunthorpe
Browse files

Merge patch series "Connect VFIO to IOMMUFD"

Jason Gunthorpe <jgg@nvidia.com> says:

==================
This series provides an alternative container layer for VFIO implemented
using iommufd. This is optional, if CONFIG_IOMMUFD is not set then it will
not be compiled in.

At this point iommufd can be injected by passing in a iommfd FD to
VFIO_GROUP_SET_CONTAINER which will use the VFIO compat layer in iommufd
to obtain the compat IOAS and then connect up all the VFIO drivers as
appropriate.

This is temporary stopping point, a following series will provide a way to
directly open a VFIO device FD and directly connect it to IOMMUFD using
native ioctls that can expose the IOMMUFD features like hwpt, future
vPASID and dynamic attachment.

This series, in compat mode, has passed all the qemu tests we have
available, including the test suites for the Intel GVT mdev. Aside from
the temporary limitation with P2P memory this is belived to be fully
compatible with VFIO.

This is on github: https://github.com/jgunthorpe/linux/commits/vfio_iommufd

It requires the iommufd series:

https://lore.kernel.org/r/0-v6-a196d26f289e+11787-iommufd_jgg@nvidia.com
==================

Link: https://lore.kernel.org/r/0-v4-42cd2eb0e3eb+335a-vfio_iommufd_jgg@nvidia.com


Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
parents 2a54e347 01f70cbb
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -1484,6 +1484,9 @@ static const struct vfio_device_ops intel_vgpu_dev_ops = {
	.mmap		= intel_vgpu_mmap,
	.ioctl		= intel_vgpu_ioctl,
	.dma_unmap	= intel_vgpu_dma_unmap,
	.bind_iommufd	= vfio_iommufd_emulated_bind,
	.unbind_iommufd = vfio_iommufd_emulated_unbind,
	.attach_ioas	= vfio_iommufd_emulated_attach_ioas,
};

static int intel_vgpu_probe(struct mdev_device *mdev)
+20 −0
Original line number Diff line number Diff line
@@ -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
+36 −0
Original line number Diff line number Diff line
@@ -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");
+3 −0
Original line number Diff line number Diff line
@@ -588,6 +588,9 @@ static const struct vfio_device_ops vfio_ccw_dev_ops = {
	.ioctl = vfio_ccw_mdev_ioctl,
	.request = vfio_ccw_mdev_request,
	.dma_unmap = vfio_ccw_dma_unmap,
	.bind_iommufd = vfio_iommufd_emulated_bind,
	.unbind_iommufd = vfio_iommufd_emulated_unbind,
	.attach_ioas = vfio_iommufd_emulated_attach_ioas,
};

struct mdev_driver vfio_ccw_mdev_driver = {
+3 −0
Original line number Diff line number Diff line
@@ -1805,6 +1805,9 @@ static const struct vfio_device_ops vfio_ap_matrix_dev_ops = {
	.close_device = vfio_ap_mdev_close_device,
	.ioctl = vfio_ap_mdev_ioctl,
	.dma_unmap = vfio_ap_mdev_dma_unmap,
	.bind_iommufd = vfio_iommufd_emulated_bind,
	.unbind_iommufd = vfio_iommufd_emulated_unbind,
	.attach_ioas = vfio_iommufd_emulated_attach_ioas,
};

static struct mdev_driver vfio_ap_matrix_driver = {
Loading