blob: c752b963a8881ef2c7e098c2ee2258b06cb77e5a [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001From 8b9efd00727523c56eb9d17ad42338b6090b4b8e Mon Sep 17 00:00:00 2001
2From: Bharat Bhushan <Bharat.Bhushan@nxp.com>
3Date: Fri, 12 May 2017 10:27:07 +0530
4Subject: [PATCH] vfio/fsl-mc: Add VFIO framework skeleton for fsl-mc devices
5
6This patch adds the infrastructure for VFIO support for fsl-mc
7devices. Subsequent patches will add support for binding and secure
8assigning these devices using VFIO.
9
10FSL-MC is a new bus (driver/bus/fsl-mc/) which is different
11from PCI and Platform bus.
12
13Signed-off-by: Bharat Bhushan <Bharat.Bhushan@nxp.com>
14Signed-off-by: Diana Craciun <diana.craciun@nxp.com>
15---
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
28
29--- a/drivers/vfio/Kconfig
30+++ b/drivers/vfio/Kconfig
31@@ -47,4 +47,5 @@ config 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/
44--- /dev/null
45+++ b/drivers/vfio/fsl-mc/Kconfig
46@@ -0,0 +1,9 @@
47+config VFIO_FSL_MC
48+ tristate "VFIO support for QorIQ DPAA2 fsl-mc bus devices"
49+ depends on VFIO && FSL_MC_BUS && EVENTFD
50+ help
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.
54+
55+ If you don't know what to do here, say N.
56--- /dev/null
57+++ b/drivers/vfio/fsl-mc/Makefile
58@@ -0,0 +1,2 @@
59+vfio-fsl_mc-y := vfio_fsl_mc.o
60+obj-$(CONFIG_VFIO_FSL_MC) += vfio_fsl_mc.o
61--- /dev/null
62+++ b/drivers/vfio/fsl-mc/vfio_fsl_mc.c
63@@ -0,0 +1,162 @@
64+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
65+/*
66+ * Copyright 2013-2016 Freescale Semiconductor Inc.
67+ * Copyright 2016-2017,2019 NXP
68+ */
69+
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>
78+
79+#include "vfio_fsl_mc_private.h"
80+
81+
82+static int vfio_fsl_mc_open(void *device_data)
83+{
84+ if (!try_module_get(THIS_MODULE))
85+ return -ENODEV;
86+
87+ return 0;
88+}
89+
90+static void vfio_fsl_mc_release(void *device_data)
91+{
92+ module_put(THIS_MODULE);
93+}
94+
95+static long vfio_fsl_mc_ioctl(void *device_data, unsigned int cmd,
96+ unsigned long arg)
97+{
98+ switch (cmd) {
99+ case VFIO_DEVICE_GET_INFO:
100+ {
101+ return -EINVAL;
102+ }
103+ case VFIO_DEVICE_GET_REGION_INFO:
104+ {
105+ return -EINVAL;
106+ }
107+ case VFIO_DEVICE_GET_IRQ_INFO:
108+ {
109+ return -EINVAL;
110+ }
111+ case VFIO_DEVICE_SET_IRQS:
112+ {
113+ return -EINVAL;
114+ }
115+ case VFIO_DEVICE_RESET:
116+ {
117+ return -EINVAL;
118+ }
119+ default:
120+ return -EINVAL;
121+ }
122+}
123+
124+static ssize_t vfio_fsl_mc_read(void *device_data, char __user *buf,
125+ size_t count, loff_t *ppos)
126+{
127+ return -EINVAL;
128+}
129+
130+static ssize_t vfio_fsl_mc_write(void *device_data, const char __user *buf,
131+ size_t count, loff_t *ppos)
132+{
133+ return -EINVAL;
134+}
135+
136+static int vfio_fsl_mc_mmap(void *device_data, struct vm_area_struct *vma)
137+{
138+ return -EINVAL;
139+}
140+
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,
149+};
150+
151+static int vfio_fsl_mc_probe(struct fsl_mc_device *mc_dev)
152+{
153+ struct iommu_group *group;
154+ struct vfio_fsl_mc_device *vdev;
155+ struct device *dev = &mc_dev->dev;
156+ int ret;
157+
158+ group = vfio_iommu_group_get(dev);
159+ if (!group) {
160+ dev_err(dev, "%s: VFIO: No IOMMU group\n", __func__);
161+ return -EINVAL;
162+ }
163+
164+ vdev = devm_kzalloc(dev, sizeof(*vdev), GFP_KERNEL);
165+ if (!vdev) {
166+ vfio_iommu_group_put(group, dev);
167+ return -ENOMEM;
168+ }
169+
170+ vdev->mc_dev = mc_dev;
171+
172+ ret = vfio_add_group_dev(dev, &vfio_fsl_mc_ops, vdev);
173+ if (ret) {
174+ dev_err(dev, "%s: Failed to add to vfio group\n", __func__);
175+ vfio_iommu_group_put(group, dev);
176+ return ret;
177+ }
178+
179+ return ret;
180+}
181+
182+static int vfio_fsl_mc_remove(struct fsl_mc_device *mc_dev)
183+{
184+ struct vfio_fsl_mc_device *vdev;
185+ struct device *dev = &mc_dev->dev;
186+
187+ vdev = vfio_del_group_dev(dev);
188+ if (!vdev)
189+ return -EINVAL;
190+
191+ vfio_iommu_group_put(mc_dev->dev.iommu_group, dev);
192+ devm_kfree(dev, vdev);
193+
194+ return 0;
195+}
196+
197+/*
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.
200+ */
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,
205+ .driver = {
206+ .name = "vfio-fsl-mc",
207+ .owner = THIS_MODULE,
208+ },
209+};
210+
211+static int __init vfio_fsl_mc_driver_init(void)
212+{
213+ return fsl_mc_driver_register(&vfio_fsl_mc_driver);
214+}
215+
216+static void __exit vfio_fsl_mc_driver_exit(void)
217+{
218+ fsl_mc_driver_unregister(&vfio_fsl_mc_driver);
219+}
220+
221+module_init(vfio_fsl_mc_driver_init);
222+module_exit(vfio_fsl_mc_driver_exit);
223+
224+MODULE_LICENSE("GPL v2");
225+MODULE_DESCRIPTION("VFIO for FSL-MC devices - User Level meta-driver");
226--- /dev/null
227+++ b/drivers/vfio/fsl-mc/vfio_fsl_mc_private.h
228@@ -0,0 +1,14 @@
229+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
230+/*
231+ * Copyright 2013-2016 Freescale Semiconductor Inc.
232+ * Copyright 2016,2019 NXP
233+ */
234+
235+#ifndef VFIO_FSL_MC_PRIVATE_H
236+#define VFIO_FSL_MC_PRIVATE_H
237+
238+struct vfio_fsl_mc_device {
239+ struct fsl_mc_device *mc_dev;
240+};
241+
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 */
252 };