1a6546f89SThomas Gleixner.. SPDX-License-Identifier: GPL-2.0-only 2baa293e9SMauro Carvalho Chehab.. include:: <isonum.txt> 3baa293e9SMauro Carvalho Chehab 4baa293e9SMauro Carvalho Chehab===================== 5baa293e9SMauro Carvalho ChehabVFIO Mediated devices 6baa293e9SMauro Carvalho Chehab===================== 7baa293e9SMauro Carvalho Chehab 8baa293e9SMauro Carvalho Chehab:Copyright: |copy| 2016, NVIDIA CORPORATION. All rights reserved. 9baa293e9SMauro Carvalho Chehab:Author: Neo Jia <cjia@nvidia.com> 10baa293e9SMauro Carvalho Chehab:Author: Kirti Wankhede <kwankhede@nvidia.com> 11baa293e9SMauro Carvalho Chehab 12baa293e9SMauro Carvalho Chehab 13baa293e9SMauro Carvalho Chehab 14baa293e9SMauro Carvalho ChehabVirtual Function I/O (VFIO) Mediated devices[1] 15baa293e9SMauro Carvalho Chehab=============================================== 16baa293e9SMauro Carvalho Chehab 17baa293e9SMauro Carvalho ChehabThe number of use cases for virtualizing DMA devices that do not have built-in 18baa293e9SMauro Carvalho ChehabSR_IOV capability is increasing. Previously, to virtualize such devices, 19baa293e9SMauro Carvalho Chehabdevelopers had to create their own management interfaces and APIs, and then 20baa293e9SMauro Carvalho Chehabintegrate them with user space software. To simplify integration with user space 21baa293e9SMauro Carvalho Chehabsoftware, we have identified common requirements and a unified management 22baa293e9SMauro Carvalho Chehabinterface for such devices. 23baa293e9SMauro Carvalho Chehab 24baa293e9SMauro Carvalho ChehabThe VFIO driver framework provides unified APIs for direct device access. It is 25baa293e9SMauro Carvalho Chehaban IOMMU/device-agnostic framework for exposing direct device access to user 26baa293e9SMauro Carvalho Chehabspace in a secure, IOMMU-protected environment. This framework is used for 27baa293e9SMauro Carvalho Chehabmultiple devices, such as GPUs, network adapters, and compute accelerators. With 28baa293e9SMauro Carvalho Chehabdirect device access, virtual machines or user space applications have direct 29baa293e9SMauro Carvalho Chehabaccess to the physical device. This framework is reused for mediated devices. 30baa293e9SMauro Carvalho Chehab 31baa293e9SMauro Carvalho ChehabThe mediated core driver provides a common interface for mediated device 32baa293e9SMauro Carvalho Chehabmanagement that can be used by drivers of different devices. This module 33baa293e9SMauro Carvalho Chehabprovides a generic interface to perform these operations: 34baa293e9SMauro Carvalho Chehab 35baa293e9SMauro Carvalho Chehab* Create and destroy a mediated device 36baa293e9SMauro Carvalho Chehab* Add a mediated device to and remove it from a mediated bus driver 37baa293e9SMauro Carvalho Chehab* Add a mediated device to and remove it from an IOMMU group 38baa293e9SMauro Carvalho Chehab 39baa293e9SMauro Carvalho ChehabThe mediated core driver also provides an interface to register a bus driver. 40baa293e9SMauro Carvalho ChehabFor example, the mediated VFIO mdev driver is designed for mediated devices and 41baa293e9SMauro Carvalho Chehabsupports VFIO APIs. The mediated bus driver adds a mediated device to and 42baa293e9SMauro Carvalho Chehabremoves it from a VFIO group. 43baa293e9SMauro Carvalho Chehab 44baa293e9SMauro Carvalho ChehabThe following high-level block diagram shows the main components and interfaces 45baa293e9SMauro Carvalho Chehabin the VFIO mediated driver framework. The diagram shows NVIDIA, Intel, and IBM 46baa293e9SMauro Carvalho Chehabdevices as examples, as these devices are the first devices to use this module:: 47baa293e9SMauro Carvalho Chehab 48baa293e9SMauro Carvalho Chehab +---------------+ 49baa293e9SMauro Carvalho Chehab | | 50baa293e9SMauro Carvalho Chehab | +-----------+ | mdev_register_driver() +--------------+ 51baa293e9SMauro Carvalho Chehab | | | +<------------------------+ | 52baa293e9SMauro Carvalho Chehab | | mdev | | | | 53baa293e9SMauro Carvalho Chehab | | bus | +------------------------>+ vfio_mdev.ko |<-> VFIO user 54baa293e9SMauro Carvalho Chehab | | driver | | probe()/remove() | | APIs 55baa293e9SMauro Carvalho Chehab | | | | +--------------+ 56baa293e9SMauro Carvalho Chehab | +-----------+ | 57baa293e9SMauro Carvalho Chehab | | 58baa293e9SMauro Carvalho Chehab | MDEV CORE | 59baa293e9SMauro Carvalho Chehab | MODULE | 60baa293e9SMauro Carvalho Chehab | mdev.ko | 6189345d51SChristoph Hellwig | +-----------+ | mdev_register_parent() +--------------+ 62baa293e9SMauro Carvalho Chehab | | | +<------------------------+ | 63*32328681SChristoph Hellwig | | | | | ccw_device.ko|<-> physical 64baa293e9SMauro Carvalho Chehab | | | +------------------------>+ | device 65baa293e9SMauro Carvalho Chehab | | | | callbacks +--------------+ 66baa293e9SMauro Carvalho Chehab | | Physical | | 6789345d51SChristoph Hellwig | | device | | mdev_register_parent() +--------------+ 68baa293e9SMauro Carvalho Chehab | | interface | |<------------------------+ | 69baa293e9SMauro Carvalho Chehab | | | | | i915.ko |<-> physical 70baa293e9SMauro Carvalho Chehab | | | +------------------------>+ | device 71baa293e9SMauro Carvalho Chehab | | | | callbacks +--------------+ 72baa293e9SMauro Carvalho Chehab | +-----------+ | 73baa293e9SMauro Carvalho Chehab +---------------+ 74baa293e9SMauro Carvalho Chehab 75baa293e9SMauro Carvalho Chehab 76baa293e9SMauro Carvalho ChehabRegistration Interfaces 77baa293e9SMauro Carvalho Chehab======================= 78baa293e9SMauro Carvalho Chehab 79baa293e9SMauro Carvalho ChehabThe mediated core driver provides the following types of registration 80baa293e9SMauro Carvalho Chehabinterfaces: 81baa293e9SMauro Carvalho Chehab 82baa293e9SMauro Carvalho Chehab* Registration interface for a mediated bus driver 83baa293e9SMauro Carvalho Chehab* Physical device driver interface 84baa293e9SMauro Carvalho Chehab 85baa293e9SMauro Carvalho ChehabRegistration Interface for a Mediated Bus Driver 86baa293e9SMauro Carvalho Chehab------------------------------------------------ 87baa293e9SMauro Carvalho Chehab 8888a21f26SJason GunthorpeThe registration interface for a mediated device driver provides the following 89baa293e9SMauro Carvalho Chehabstructure to represent a mediated device's driver:: 90baa293e9SMauro Carvalho Chehab 91baa293e9SMauro Carvalho Chehab /* 92baa293e9SMauro Carvalho Chehab * struct mdev_driver [2] - Mediated device's driver 93baa293e9SMauro Carvalho Chehab * @probe: called when new device created 94baa293e9SMauro Carvalho Chehab * @remove: called when device removed 95baa293e9SMauro Carvalho Chehab * @driver: device driver structure 96baa293e9SMauro Carvalho Chehab */ 97baa293e9SMauro Carvalho Chehab struct mdev_driver { 982a3d15f2SJason Gunthorpe int (*probe) (struct mdev_device *dev); 992a3d15f2SJason Gunthorpe void (*remove) (struct mdev_device *dev); 100f2fbc72eSChristoph Hellwig unsigned int (*get_available)(struct mdev_type *mtype); 101685a1537SChristoph Hellwig ssize_t (*show_description)(struct mdev_type *mtype, char *buf); 102baa293e9SMauro Carvalho Chehab struct device_driver driver; 103baa293e9SMauro Carvalho Chehab }; 104baa293e9SMauro Carvalho Chehab 105baa293e9SMauro Carvalho ChehabA mediated bus driver for mdev should use this structure in the function calls 106baa293e9SMauro Carvalho Chehabto register and unregister itself with the core driver: 107baa293e9SMauro Carvalho Chehab 108baa293e9SMauro Carvalho Chehab* Register:: 109baa293e9SMauro Carvalho Chehab 110d1877e63SAlex Williamson int mdev_register_driver(struct mdev_driver *drv); 111baa293e9SMauro Carvalho Chehab 112baa293e9SMauro Carvalho Chehab* Unregister:: 113baa293e9SMauro Carvalho Chehab 114d1877e63SAlex Williamson void mdev_unregister_driver(struct mdev_driver *drv); 115baa293e9SMauro Carvalho Chehab 1166b42f491SJason GunthorpeThe mediated bus driver's probe function should create a vfio_device on top of 1176b42f491SJason Gunthorpethe mdev_device and connect it to an appropriate implementation of 1186b42f491SJason Gunthorpevfio_device_ops. 119baa293e9SMauro Carvalho Chehab 12088a21f26SJason GunthorpeWhen a driver wants to add the GUID creation sysfs to an existing device it has 12188a21f26SJason Gunthorpeprobe'd to then it should call:: 122baa293e9SMauro Carvalho Chehab 12389345d51SChristoph Hellwig int mdev_register_parent(struct mdev_parent *parent, struct device *dev, 1246b42f491SJason Gunthorpe struct mdev_driver *mdev_driver); 125baa293e9SMauro Carvalho Chehab 12688a21f26SJason GunthorpeThis will provide the 'mdev_supported_types/XX/create' files which can then be 12788a21f26SJason Gunthorpeused to trigger the creation of a mdev_device. The created mdev_device will be 12888a21f26SJason Gunthorpeattached to the specified driver. 12988a21f26SJason Gunthorpe 13088a21f26SJason GunthorpeWhen the driver needs to remove itself it calls:: 131baa293e9SMauro Carvalho Chehab 13289345d51SChristoph Hellwig void mdev_unregister_parent(struct mdev_parent *parent); 133baa293e9SMauro Carvalho Chehab 13488a21f26SJason GunthorpeWhich will unbind and destroy all the created mdevs and remove the sysfs files. 135baa293e9SMauro Carvalho Chehab 136baa293e9SMauro Carvalho ChehabMediated Device Management Interface Through sysfs 137baa293e9SMauro Carvalho Chehab================================================== 138baa293e9SMauro Carvalho Chehab 139baa293e9SMauro Carvalho ChehabThe management interface through sysfs enables user space software, such as 140baa293e9SMauro Carvalho Chehablibvirt, to query and configure mediated devices in a hardware-agnostic fashion. 141baa293e9SMauro Carvalho ChehabThis management interface provides flexibility to the underlying physical 142baa293e9SMauro Carvalho Chehabdevice's driver to support features such as: 143baa293e9SMauro Carvalho Chehab 144baa293e9SMauro Carvalho Chehab* Mediated device hot plug 145baa293e9SMauro Carvalho Chehab* Multiple mediated devices in a single virtual machine 146baa293e9SMauro Carvalho Chehab* Multiple mediated devices from different physical devices 147baa293e9SMauro Carvalho Chehab 148baa293e9SMauro Carvalho ChehabLinks in the mdev_bus Class Directory 149baa293e9SMauro Carvalho Chehab------------------------------------- 150baa293e9SMauro Carvalho ChehabThe /sys/class/mdev_bus/ directory contains links to devices that are registered 151baa293e9SMauro Carvalho Chehabwith the mdev core driver. 152baa293e9SMauro Carvalho Chehab 153baa293e9SMauro Carvalho ChehabDirectories and files under the sysfs for Each Physical Device 154baa293e9SMauro Carvalho Chehab-------------------------------------------------------------- 155baa293e9SMauro Carvalho Chehab 156baa293e9SMauro Carvalho Chehab:: 157baa293e9SMauro Carvalho Chehab 158baa293e9SMauro Carvalho Chehab |- [parent physical device] 159baa293e9SMauro Carvalho Chehab |--- Vendor-specific-attributes [optional] 160baa293e9SMauro Carvalho Chehab |--- [mdev_supported_types] 161baa293e9SMauro Carvalho Chehab | |--- [<type-id>] 162baa293e9SMauro Carvalho Chehab | | |--- create 163baa293e9SMauro Carvalho Chehab | | |--- name 164baa293e9SMauro Carvalho Chehab | | |--- available_instances 165baa293e9SMauro Carvalho Chehab | | |--- device_api 166baa293e9SMauro Carvalho Chehab | | |--- description 167baa293e9SMauro Carvalho Chehab | | |--- [devices] 168baa293e9SMauro Carvalho Chehab | |--- [<type-id>] 169baa293e9SMauro Carvalho Chehab | | |--- create 170baa293e9SMauro Carvalho Chehab | | |--- name 171baa293e9SMauro Carvalho Chehab | | |--- available_instances 172baa293e9SMauro Carvalho Chehab | | |--- device_api 173baa293e9SMauro Carvalho Chehab | | |--- description 174baa293e9SMauro Carvalho Chehab | | |--- [devices] 175baa293e9SMauro Carvalho Chehab | |--- [<type-id>] 176baa293e9SMauro Carvalho Chehab | |--- create 177baa293e9SMauro Carvalho Chehab | |--- name 178baa293e9SMauro Carvalho Chehab | |--- available_instances 179baa293e9SMauro Carvalho Chehab | |--- device_api 180baa293e9SMauro Carvalho Chehab | |--- description 181baa293e9SMauro Carvalho Chehab | |--- [devices] 182baa293e9SMauro Carvalho Chehab 183baa293e9SMauro Carvalho Chehab* [mdev_supported_types] 184baa293e9SMauro Carvalho Chehab 185baa293e9SMauro Carvalho Chehab The list of currently supported mediated device types and their details. 186baa293e9SMauro Carvalho Chehab 187baa293e9SMauro Carvalho Chehab [<type-id>], device_api, and available_instances are mandatory attributes 188baa293e9SMauro Carvalho Chehab that should be provided by vendor driver. 189baa293e9SMauro Carvalho Chehab 190baa293e9SMauro Carvalho Chehab* [<type-id>] 191baa293e9SMauro Carvalho Chehab 192baa293e9SMauro Carvalho Chehab The [<type-id>] name is created by adding the device driver string as a prefix 193baa293e9SMauro Carvalho Chehab to the string provided by the vendor driver. This format of this name is as 194baa293e9SMauro Carvalho Chehab follows:: 195baa293e9SMauro Carvalho Chehab 196baa293e9SMauro Carvalho Chehab sprintf(buf, "%s-%s", dev_driver_string(parent->dev), group->name); 197baa293e9SMauro Carvalho Chehab 198baa293e9SMauro Carvalho Chehab* device_api 199baa293e9SMauro Carvalho Chehab 200290aac5dSJason Gunthorpe This attribute shows which device API is being created, for example, 201baa293e9SMauro Carvalho Chehab "vfio-pci" for a PCI device. 202baa293e9SMauro Carvalho Chehab 203baa293e9SMauro Carvalho Chehab* available_instances 204baa293e9SMauro Carvalho Chehab 205f2fbc72eSChristoph Hellwig This attribute shows the number of devices of type <type-id> that can be 206baa293e9SMauro Carvalho Chehab created. 207baa293e9SMauro Carvalho Chehab 208baa293e9SMauro Carvalho Chehab* [device] 209baa293e9SMauro Carvalho Chehab 210baa293e9SMauro Carvalho Chehab This directory contains links to the devices of type <type-id> that have been 211baa293e9SMauro Carvalho Chehab created. 212baa293e9SMauro Carvalho Chehab 213baa293e9SMauro Carvalho Chehab* name 214baa293e9SMauro Carvalho Chehab 2150bc79069SChristoph Hellwig This attribute shows a human readable name. 216baa293e9SMauro Carvalho Chehab 217baa293e9SMauro Carvalho Chehab* description 218baa293e9SMauro Carvalho Chehab 219685a1537SChristoph Hellwig This attribute can show brief features/description of the type. This is an 220baa293e9SMauro Carvalho Chehab optional attribute. 221baa293e9SMauro Carvalho Chehab 222baa293e9SMauro Carvalho ChehabDirectories and Files Under the sysfs for Each mdev Device 223baa293e9SMauro Carvalho Chehab---------------------------------------------------------- 224baa293e9SMauro Carvalho Chehab 225baa293e9SMauro Carvalho Chehab:: 226baa293e9SMauro Carvalho Chehab 227baa293e9SMauro Carvalho Chehab |- [parent phy device] 228baa293e9SMauro Carvalho Chehab |--- [$MDEV_UUID] 229baa293e9SMauro Carvalho Chehab |--- remove 230baa293e9SMauro Carvalho Chehab |--- mdev_type {link to its type} 231baa293e9SMauro Carvalho Chehab |--- vendor-specific-attributes [optional] 232baa293e9SMauro Carvalho Chehab 233baa293e9SMauro Carvalho Chehab* remove (write only) 234baa293e9SMauro Carvalho Chehab 235baa293e9SMauro Carvalho ChehabWriting '1' to the 'remove' file destroys the mdev device. The vendor driver can 236baa293e9SMauro Carvalho Chehabfail the remove() callback if that device is active and the vendor driver 237baa293e9SMauro Carvalho Chehabdoesn't support hot unplug. 238baa293e9SMauro Carvalho Chehab 239baa293e9SMauro Carvalho ChehabExample:: 240baa293e9SMauro Carvalho Chehab 241baa293e9SMauro Carvalho Chehab # echo 1 > /sys/bus/mdev/devices/$mdev_UUID/remove 242baa293e9SMauro Carvalho Chehab 243baa293e9SMauro Carvalho ChehabMediated device Hot plug 244baa293e9SMauro Carvalho Chehab------------------------ 245baa293e9SMauro Carvalho Chehab 246baa293e9SMauro Carvalho ChehabMediated devices can be created and assigned at runtime. The procedure to hot 247baa293e9SMauro Carvalho Chehabplug a mediated device is the same as the procedure to hot plug a PCI device. 248baa293e9SMauro Carvalho Chehab 249baa293e9SMauro Carvalho ChehabTranslation APIs for Mediated Devices 250baa293e9SMauro Carvalho Chehab===================================== 251baa293e9SMauro Carvalho Chehab 252baa293e9SMauro Carvalho ChehabThe following APIs are provided for translating user pfn to host pfn in a VFIO 253baa293e9SMauro Carvalho Chehabdriver:: 254baa293e9SMauro Carvalho Chehab 25544abdd16SNicolin Chen int vfio_pin_pages(struct vfio_device *device, dma_addr_t iova, 25634a255e6SNicolin Chen int npage, int prot, struct page **pages); 257baa293e9SMauro Carvalho Chehab 25844abdd16SNicolin Chen void vfio_unpin_pages(struct vfio_device *device, dma_addr_t iova, 259baa293e9SMauro Carvalho Chehab int npage); 260baa293e9SMauro Carvalho Chehab 261baa293e9SMauro Carvalho ChehabThese functions call back into the back-end IOMMU module by using the pin_pages 262baa293e9SMauro Carvalho Chehaband unpin_pages callbacks of the struct vfio_iommu_driver_ops[4]. Currently 263baa293e9SMauro Carvalho Chehabthese callbacks are supported in the TYPE1 IOMMU module. To enable them for 264baa293e9SMauro Carvalho Chehabother IOMMU backend modules, such as PPC64 sPAPR module, they need to provide 265baa293e9SMauro Carvalho Chehabthese two callback functions. 266baa293e9SMauro Carvalho Chehab 267baa293e9SMauro Carvalho ChehabReferences 268baa293e9SMauro Carvalho Chehab========== 269baa293e9SMauro Carvalho Chehab 270baa293e9SMauro Carvalho Chehab1. See Documentation/driver-api/vfio.rst for more information on VFIO. 271baa293e9SMauro Carvalho Chehab2. struct mdev_driver in include/linux/mdev.h 272baa293e9SMauro Carvalho Chehab3. struct mdev_parent_ops in include/linux/mdev.h 273baa293e9SMauro Carvalho Chehab4. struct vfio_iommu_driver_ops in include/linux/vfio.h 274