Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

vfio/fsl-mc: Add VFIO framework skeleton for fsl-mc devices

DPAA2 (Data Path Acceleration Architecture) consists in
mechanisms for processing Ethernet packets, queue management,
accelerators, etc.

The Management Complex (mc) is a hardware entity that manages the DPAA2
hardware resources. It provides an object-based abstraction for software
drivers to use the DPAA2 hardware. The MC mediates operations such as
create, discover, destroy of DPAA2 objects.
The MC provides memory-mapped I/O command interfaces (MC portals) which
DPAA2 software drivers use to operate on DPAA2 objects.

A DPRC is a container object that holds other types of DPAA2 objects.
Each object in the DPRC is a Linux device and bound to a driver.
The MC-bus driver is a platform driver (different from PCI or platform
bus). The DPRC driver does runtime management of a bus instance. It
performs the initial scan of the DPRC and handles changes in the DPRC
configuration (adding/removing objects).

All objects inside a container share the same hardware isolation
context, meaning that only an entire DPRC can be assigned to
a virtual machine.
When a container is assigned to a virtual machine, all the objects
within that container are assigned to that virtual machine.
The DPRC container assigned to the virtual machine is not allowed
to change contents (add/remove objects) by the guest. The restriction
is set by the host and enforced by the mc hardware.

The DPAA2 objects can be directly assigned to the guest. However
the MC portals (the memory mapped command interface to the MC) need
to be emulated because there are commands that configure the
interrupts and the isolation IDs which are virtual in the guest.

Example:
echo vfio-fsl-mc > /sys/bus/fsl-mc/devices/dprc.2/driver_override
echo dprc.2 > /sys/bus/fsl-mc/drivers/vfio-fsl-mc/bind

The dprc.2 is bound to the VFIO driver and all the objects within
dprc.2 are going to be bound to the VFIO driver.

This patch adds the infrastructure for VFIO support for fsl-mc
devices. Subsequent patches will add support for binding and secure
assigning these devices using VFIO.

More details about the DPAA2 objects can be found here:
Documentation/networking/device_drivers/freescale/dpaa2/overview.rst

Signed-off-by: Bharat Bhushan <Bharat.Bhushan@nxp.com>
Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>

authored by

Bharat Bhushan and committed by
Alex Williamson
fb1ff4c1 ba4f184e

+193
+6
MAINTAINERS
··· 18260 18260 F: include/linux/vfio.h 18261 18261 F: include/uapi/linux/vfio.h 18262 18262 18263 + VFIO FSL-MC DRIVER 18264 + M: Diana Craciun <diana.craciun@oss.nxp.com> 18265 + L: kvm@vger.kernel.org 18266 + S: Maintained 18267 + F: drivers/vfio/fsl-mc/ 18268 + 18263 18269 VFIO MEDIATED DEVICE DRIVERS 18264 18270 M: Kirti Wankhede <kwankhede@nvidia.com> 18265 18271 L: kvm@vger.kernel.org
+1
drivers/vfio/Kconfig
··· 47 47 source "drivers/vfio/pci/Kconfig" 48 48 source "drivers/vfio/platform/Kconfig" 49 49 source "drivers/vfio/mdev/Kconfig" 50 + source "drivers/vfio/fsl-mc/Kconfig" 50 51 source "virt/lib/Kconfig"
+1
drivers/vfio/Makefile
··· 9 9 obj-$(CONFIG_VFIO_PCI) += pci/ 10 10 obj-$(CONFIG_VFIO_PLATFORM) += platform/ 11 11 obj-$(CONFIG_VFIO_MDEV) += mdev/ 12 + obj-$(CONFIG_VFIO_FSL_MC) += fsl-mc/
+9
drivers/vfio/fsl-mc/Kconfig
··· 1 + config VFIO_FSL_MC 2 + tristate "VFIO support for QorIQ DPAA2 fsl-mc bus devices" 3 + depends on VFIO && FSL_MC_BUS && EVENTFD 4 + help 5 + Driver to enable support for the VFIO QorIQ DPAA2 fsl-mc 6 + (Management Complex) devices. This is required to passthrough 7 + fsl-mc bus devices using the VFIO framework. 8 + 9 + If you don't know what to do here, say N.
+4
drivers/vfio/fsl-mc/Makefile
··· 1 + # SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 2 + 3 + vfio-fsl-mc-y := vfio_fsl_mc.o 4 + obj-$(CONFIG_VFIO_FSL_MC) += vfio-fsl-mc.o
+157
drivers/vfio/fsl-mc/vfio_fsl_mc.c
··· 1 + // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 2 + /* 3 + * Copyright 2013-2016 Freescale Semiconductor Inc. 4 + * Copyright 2016-2017,2019-2020 NXP 5 + */ 6 + 7 + #include <linux/device.h> 8 + #include <linux/iommu.h> 9 + #include <linux/module.h> 10 + #include <linux/mutex.h> 11 + #include <linux/slab.h> 12 + #include <linux/types.h> 13 + #include <linux/vfio.h> 14 + #include <linux/fsl/mc.h> 15 + 16 + #include "vfio_fsl_mc_private.h" 17 + 18 + static int vfio_fsl_mc_open(void *device_data) 19 + { 20 + if (!try_module_get(THIS_MODULE)) 21 + return -ENODEV; 22 + 23 + return 0; 24 + } 25 + 26 + static void vfio_fsl_mc_release(void *device_data) 27 + { 28 + module_put(THIS_MODULE); 29 + } 30 + 31 + static long vfio_fsl_mc_ioctl(void *device_data, unsigned int cmd, 32 + unsigned long arg) 33 + { 34 + switch (cmd) { 35 + case VFIO_DEVICE_GET_INFO: 36 + { 37 + return -ENOTTY; 38 + } 39 + case VFIO_DEVICE_GET_REGION_INFO: 40 + { 41 + return -ENOTTY; 42 + } 43 + case VFIO_DEVICE_GET_IRQ_INFO: 44 + { 45 + return -ENOTTY; 46 + } 47 + case VFIO_DEVICE_SET_IRQS: 48 + { 49 + return -ENOTTY; 50 + } 51 + case VFIO_DEVICE_RESET: 52 + { 53 + return -ENOTTY; 54 + } 55 + default: 56 + return -ENOTTY; 57 + } 58 + } 59 + 60 + static ssize_t vfio_fsl_mc_read(void *device_data, char __user *buf, 61 + size_t count, loff_t *ppos) 62 + { 63 + return -EINVAL; 64 + } 65 + 66 + static ssize_t vfio_fsl_mc_write(void *device_data, const char __user *buf, 67 + size_t count, loff_t *ppos) 68 + { 69 + return -EINVAL; 70 + } 71 + 72 + static int vfio_fsl_mc_mmap(void *device_data, struct vm_area_struct *vma) 73 + { 74 + return -EINVAL; 75 + } 76 + 77 + static const struct vfio_device_ops vfio_fsl_mc_ops = { 78 + .name = "vfio-fsl-mc", 79 + .open = vfio_fsl_mc_open, 80 + .release = vfio_fsl_mc_release, 81 + .ioctl = vfio_fsl_mc_ioctl, 82 + .read = vfio_fsl_mc_read, 83 + .write = vfio_fsl_mc_write, 84 + .mmap = vfio_fsl_mc_mmap, 85 + }; 86 + 87 + static int vfio_fsl_mc_probe(struct fsl_mc_device *mc_dev) 88 + { 89 + struct iommu_group *group; 90 + struct vfio_fsl_mc_device *vdev; 91 + struct device *dev = &mc_dev->dev; 92 + int ret; 93 + 94 + group = vfio_iommu_group_get(dev); 95 + if (!group) { 96 + dev_err(dev, "VFIO_FSL_MC: No IOMMU group\n"); 97 + return -EINVAL; 98 + } 99 + 100 + vdev = devm_kzalloc(dev, sizeof(*vdev), GFP_KERNEL); 101 + if (!vdev) { 102 + ret = -ENOMEM; 103 + goto out_group_put; 104 + } 105 + 106 + vdev->mc_dev = mc_dev; 107 + 108 + ret = vfio_add_group_dev(dev, &vfio_fsl_mc_ops, vdev); 109 + if (ret) { 110 + dev_err(dev, "VFIO_FSL_MC: Failed to add to vfio group\n"); 111 + goto out_group_put; 112 + } 113 + return 0; 114 + 115 + out_group_put: 116 + vfio_iommu_group_put(group, dev); 117 + return ret; 118 + } 119 + 120 + static int vfio_fsl_mc_remove(struct fsl_mc_device *mc_dev) 121 + { 122 + struct vfio_fsl_mc_device *vdev; 123 + struct device *dev = &mc_dev->dev; 124 + 125 + vdev = vfio_del_group_dev(dev); 126 + if (!vdev) 127 + return -EINVAL; 128 + 129 + vfio_iommu_group_put(mc_dev->dev.iommu_group, dev); 130 + 131 + return 0; 132 + } 133 + 134 + static struct fsl_mc_driver vfio_fsl_mc_driver = { 135 + .probe = vfio_fsl_mc_probe, 136 + .remove = vfio_fsl_mc_remove, 137 + .driver = { 138 + .name = "vfio-fsl-mc", 139 + .owner = THIS_MODULE, 140 + }, 141 + }; 142 + 143 + static int __init vfio_fsl_mc_driver_init(void) 144 + { 145 + return fsl_mc_driver_register(&vfio_fsl_mc_driver); 146 + } 147 + 148 + static void __exit vfio_fsl_mc_driver_exit(void) 149 + { 150 + fsl_mc_driver_unregister(&vfio_fsl_mc_driver); 151 + } 152 + 153 + module_init(vfio_fsl_mc_driver_init); 154 + module_exit(vfio_fsl_mc_driver_exit); 155 + 156 + MODULE_LICENSE("Dual BSD/GPL"); 157 + MODULE_DESCRIPTION("VFIO for FSL-MC devices - User Level meta-driver");
+14
drivers/vfio/fsl-mc/vfio_fsl_mc_private.h
··· 1 + /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ 2 + /* 3 + * Copyright 2013-2016 Freescale Semiconductor Inc. 4 + * Copyright 2016,2019-2020 NXP 5 + */ 6 + 7 + #ifndef VFIO_FSL_MC_PRIVATE_H 8 + #define VFIO_FSL_MC_PRIVATE_H 9 + 10 + struct vfio_fsl_mc_device { 11 + struct fsl_mc_device *mc_dev; 12 + }; 13 + 14 + #endif /* VFIO_FSL_MC_PRIVATE_H */
+1
include/uapi/linux/vfio.h
··· 201 201 #define VFIO_DEVICE_FLAGS_AMBA (1 << 3) /* vfio-amba device */ 202 202 #define VFIO_DEVICE_FLAGS_CCW (1 << 4) /* vfio-ccw device */ 203 203 #define VFIO_DEVICE_FLAGS_AP (1 << 5) /* vfio-ap device */ 204 + #define VFIO_DEVICE_FLAGS_FSL_MC (1 << 6) /* vfio-fsl-mc device */ 204 205 __u32 num_regions; /* Max region index + 1 */ 205 206 __u32 num_irqs; /* Max IRQ index + 1 */ 206 207 };