1 From 8b9efd00727523c56eb9d17ad42338b6090b4b8e Mon Sep 17 00:00:00 2001
2 From: Bharat Bhushan <Bharat.Bhushan@nxp.com>
3 Date: Fri, 12 May 2017 10:27:07 +0530
4 Subject: [PATCH] vfio/fsl-mc: Add VFIO framework skeleton for fsl-mc devices
6 This patch adds the infrastructure for VFIO support for fsl-mc
7 devices. Subsequent patches will add support for binding and secure
8 assigning these devices using VFIO.
10 FSL-MC is a new bus (driver/bus/fsl-mc/) which is different
11 from PCI and Platform bus.
13 Signed-off-by: Bharat Bhushan <Bharat.Bhushan@nxp.com>
14 Signed-off-by: Diana Craciun <diana.craciun@nxp.com>
16 drivers/vfio/Kconfig | 1 +
17 drivers/vfio/Makefile | 1 +
18 drivers/vfio/fsl-mc/Kconfig | 9 ++
19 drivers/vfio/fsl-mc/Makefile | 2 +
20 drivers/vfio/fsl-mc/vfio_fsl_mc.c | 162 ++++++++++++++++++++++++++++++
21 drivers/vfio/fsl-mc/vfio_fsl_mc_private.h | 14 +++
22 include/uapi/linux/vfio.h | 1 +
23 7 files changed, 190 insertions(+)
24 create mode 100644 drivers/vfio/fsl-mc/Kconfig
25 create mode 100644 drivers/vfio/fsl-mc/Makefile
26 create mode 100644 drivers/vfio/fsl-mc/vfio_fsl_mc.c
27 create mode 100644 drivers/vfio/fsl-mc/vfio_fsl_mc_private.h
29 --- a/drivers/vfio/Kconfig
30 +++ b/drivers/vfio/Kconfig
31 @@ -47,4 +47,5 @@ menuconfig VFIO_NOIOMMU
32 source "drivers/vfio/pci/Kconfig"
33 source "drivers/vfio/platform/Kconfig"
34 source "drivers/vfio/mdev/Kconfig"
35 +source "drivers/vfio/fsl-mc/Kconfig"
36 source "virt/lib/Kconfig"
37 --- a/drivers/vfio/Makefile
38 +++ b/drivers/vfio/Makefile
39 @@ -9,3 +9,4 @@ obj-$(CONFIG_VFIO_SPAPR_EEH) += vfio_spa
40 obj-$(CONFIG_VFIO_PCI) += pci/
41 obj-$(CONFIG_VFIO_PLATFORM) += platform/
42 obj-$(CONFIG_VFIO_MDEV) += mdev/
43 +obj-$(CONFIG_VFIO_FSL_MC) += fsl-mc/
45 +++ b/drivers/vfio/fsl-mc/Kconfig
48 + tristate "VFIO support for QorIQ DPAA2 fsl-mc bus devices"
49 + depends on VFIO && FSL_MC_BUS && EVENTFD
51 + Driver to enable support for the VFIO QorIQ DPAA2 fsl-mc
52 + (Management Complex) devices. This is required to passthrough
53 + fsl-mc bus devices using the VFIO framework.
55 + If you don't know what to do here, say N.
57 +++ b/drivers/vfio/fsl-mc/Makefile
59 +vfio-fsl_mc-y := vfio_fsl_mc.o
60 +obj-$(CONFIG_VFIO_FSL_MC) += vfio_fsl_mc.o
62 +++ b/drivers/vfio/fsl-mc/vfio_fsl_mc.c
64 +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
66 + * Copyright 2013-2016 Freescale Semiconductor Inc.
67 + * Copyright 2016-2017,2019 NXP
70 +#include <linux/device.h>
71 +#include <linux/iommu.h>
72 +#include <linux/module.h>
73 +#include <linux/mutex.h>
74 +#include <linux/slab.h>
75 +#include <linux/types.h>
76 +#include <linux/vfio.h>
77 +#include <linux/fsl/mc.h>
79 +#include "vfio_fsl_mc_private.h"
82 +static int vfio_fsl_mc_open(void *device_data)
84 + if (!try_module_get(THIS_MODULE))
90 +static void vfio_fsl_mc_release(void *device_data)
92 + module_put(THIS_MODULE);
95 +static long vfio_fsl_mc_ioctl(void *device_data, unsigned int cmd,
99 + case VFIO_DEVICE_GET_INFO:
103 + case VFIO_DEVICE_GET_REGION_INFO:
107 + case VFIO_DEVICE_GET_IRQ_INFO:
111 + case VFIO_DEVICE_SET_IRQS:
115 + case VFIO_DEVICE_RESET:
124 +static ssize_t vfio_fsl_mc_read(void *device_data, char __user *buf,
125 + size_t count, loff_t *ppos)
130 +static ssize_t vfio_fsl_mc_write(void *device_data, const char __user *buf,
131 + size_t count, loff_t *ppos)
136 +static int vfio_fsl_mc_mmap(void *device_data, struct vm_area_struct *vma)
141 +static const struct vfio_device_ops vfio_fsl_mc_ops = {
142 + .name = "vfio-fsl-mc",
143 + .open = vfio_fsl_mc_open,
144 + .release = vfio_fsl_mc_release,
145 + .ioctl = vfio_fsl_mc_ioctl,
146 + .read = vfio_fsl_mc_read,
147 + .write = vfio_fsl_mc_write,
148 + .mmap = vfio_fsl_mc_mmap,
151 +static int vfio_fsl_mc_probe(struct fsl_mc_device *mc_dev)
153 + struct iommu_group *group;
154 + struct vfio_fsl_mc_device *vdev;
155 + struct device *dev = &mc_dev->dev;
158 + group = vfio_iommu_group_get(dev);
160 + dev_err(dev, "%s: VFIO: No IOMMU group\n", __func__);
164 + vdev = devm_kzalloc(dev, sizeof(*vdev), GFP_KERNEL);
166 + vfio_iommu_group_put(group, dev);
170 + vdev->mc_dev = mc_dev;
172 + ret = vfio_add_group_dev(dev, &vfio_fsl_mc_ops, vdev);
174 + dev_err(dev, "%s: Failed to add to vfio group\n", __func__);
175 + vfio_iommu_group_put(group, dev);
182 +static int vfio_fsl_mc_remove(struct fsl_mc_device *mc_dev)
184 + struct vfio_fsl_mc_device *vdev;
185 + struct device *dev = &mc_dev->dev;
187 + vdev = vfio_del_group_dev(dev);
191 + vfio_iommu_group_put(mc_dev->dev.iommu_group, dev);
192 + devm_kfree(dev, vdev);
198 + * vfio-fsl_mc is a meta-driver, so use driver_override interface to
199 + * bind a fsl_mc container with this driver and match_id_table is NULL.
201 +static struct fsl_mc_driver vfio_fsl_mc_driver = {
202 + .probe = vfio_fsl_mc_probe,
203 + .remove = vfio_fsl_mc_remove,
204 + .match_id_table = NULL,
206 + .name = "vfio-fsl-mc",
207 + .owner = THIS_MODULE,
211 +static int __init vfio_fsl_mc_driver_init(void)
213 + return fsl_mc_driver_register(&vfio_fsl_mc_driver);
216 +static void __exit vfio_fsl_mc_driver_exit(void)
218 + fsl_mc_driver_unregister(&vfio_fsl_mc_driver);
221 +module_init(vfio_fsl_mc_driver_init);
222 +module_exit(vfio_fsl_mc_driver_exit);
224 +MODULE_LICENSE("GPL v2");
225 +MODULE_DESCRIPTION("VFIO for FSL-MC devices - User Level meta-driver");
227 +++ b/drivers/vfio/fsl-mc/vfio_fsl_mc_private.h
229 +/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
231 + * Copyright 2013-2016 Freescale Semiconductor Inc.
232 + * Copyright 2016,2019 NXP
235 +#ifndef VFIO_FSL_MC_PRIVATE_H
236 +#define VFIO_FSL_MC_PRIVATE_H
238 +struct vfio_fsl_mc_device {
239 + struct fsl_mc_device *mc_dev;
242 +#endif /* VFIO_PCI_PRIVATE_H */
243 --- a/include/uapi/linux/vfio.h
244 +++ b/include/uapi/linux/vfio.h
245 @@ -201,6 +201,7 @@ struct vfio_device_info {
246 #define VFIO_DEVICE_FLAGS_AMBA (1 << 3) /* vfio-amba device */
247 #define VFIO_DEVICE_FLAGS_CCW (1 << 4) /* vfio-ccw device */
248 #define VFIO_DEVICE_FLAGS_AP (1 << 5) /* vfio-ap device */
249 +#define VFIO_DEVICE_FLAGS_FSL_MC (1 << 6) /* vfio-fsl-mc device */
250 __u32 num_regions; /* Max region index + 1 */
251 __u32 num_irqs; /* Max IRQ index + 1 */