xref: /OK3568_Linux_fs/kernel/Documentation/driver-api/vfio-mediated-device.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun.. include:: <isonum.txt>
2*4882a593Smuzhiyun
3*4882a593Smuzhiyun=====================
4*4882a593SmuzhiyunVFIO Mediated devices
5*4882a593Smuzhiyun=====================
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun:Copyright: |copy| 2016, NVIDIA CORPORATION. All rights reserved.
8*4882a593Smuzhiyun:Author: Neo Jia <cjia@nvidia.com>
9*4882a593Smuzhiyun:Author: Kirti Wankhede <kwankhede@nvidia.com>
10*4882a593Smuzhiyun
11*4882a593SmuzhiyunThis program is free software; you can redistribute it and/or modify
12*4882a593Smuzhiyunit under the terms of the GNU General Public License version 2 as
13*4882a593Smuzhiyunpublished by the Free Software Foundation.
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun
16*4882a593SmuzhiyunVirtual Function I/O (VFIO) Mediated devices[1]
17*4882a593Smuzhiyun===============================================
18*4882a593Smuzhiyun
19*4882a593SmuzhiyunThe number of use cases for virtualizing DMA devices that do not have built-in
20*4882a593SmuzhiyunSR_IOV capability is increasing. Previously, to virtualize such devices,
21*4882a593Smuzhiyundevelopers had to create their own management interfaces and APIs, and then
22*4882a593Smuzhiyunintegrate them with user space software. To simplify integration with user space
23*4882a593Smuzhiyunsoftware, we have identified common requirements and a unified management
24*4882a593Smuzhiyuninterface for such devices.
25*4882a593Smuzhiyun
26*4882a593SmuzhiyunThe VFIO driver framework provides unified APIs for direct device access. It is
27*4882a593Smuzhiyunan IOMMU/device-agnostic framework for exposing direct device access to user
28*4882a593Smuzhiyunspace in a secure, IOMMU-protected environment. This framework is used for
29*4882a593Smuzhiyunmultiple devices, such as GPUs, network adapters, and compute accelerators. With
30*4882a593Smuzhiyundirect device access, virtual machines or user space applications have direct
31*4882a593Smuzhiyunaccess to the physical device. This framework is reused for mediated devices.
32*4882a593Smuzhiyun
33*4882a593SmuzhiyunThe mediated core driver provides a common interface for mediated device
34*4882a593Smuzhiyunmanagement that can be used by drivers of different devices. This module
35*4882a593Smuzhiyunprovides a generic interface to perform these operations:
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun* Create and destroy a mediated device
38*4882a593Smuzhiyun* Add a mediated device to and remove it from a mediated bus driver
39*4882a593Smuzhiyun* Add a mediated device to and remove it from an IOMMU group
40*4882a593Smuzhiyun
41*4882a593SmuzhiyunThe mediated core driver also provides an interface to register a bus driver.
42*4882a593SmuzhiyunFor example, the mediated VFIO mdev driver is designed for mediated devices and
43*4882a593Smuzhiyunsupports VFIO APIs. The mediated bus driver adds a mediated device to and
44*4882a593Smuzhiyunremoves it from a VFIO group.
45*4882a593Smuzhiyun
46*4882a593SmuzhiyunThe following high-level block diagram shows the main components and interfaces
47*4882a593Smuzhiyunin the VFIO mediated driver framework. The diagram shows NVIDIA, Intel, and IBM
48*4882a593Smuzhiyundevices as examples, as these devices are the first devices to use this module::
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun     +---------------+
51*4882a593Smuzhiyun     |               |
52*4882a593Smuzhiyun     | +-----------+ |  mdev_register_driver() +--------------+
53*4882a593Smuzhiyun     | |           | +<------------------------+              |
54*4882a593Smuzhiyun     | |  mdev     | |                         |              |
55*4882a593Smuzhiyun     | |  bus      | +------------------------>+ vfio_mdev.ko |<-> VFIO user
56*4882a593Smuzhiyun     | |  driver   | |     probe()/remove()    |              |    APIs
57*4882a593Smuzhiyun     | |           | |                         +--------------+
58*4882a593Smuzhiyun     | +-----------+ |
59*4882a593Smuzhiyun     |               |
60*4882a593Smuzhiyun     |  MDEV CORE    |
61*4882a593Smuzhiyun     |   MODULE      |
62*4882a593Smuzhiyun     |   mdev.ko     |
63*4882a593Smuzhiyun     | +-----------+ |  mdev_register_device() +--------------+
64*4882a593Smuzhiyun     | |           | +<------------------------+              |
65*4882a593Smuzhiyun     | |           | |                         |  nvidia.ko   |<-> physical
66*4882a593Smuzhiyun     | |           | +------------------------>+              |    device
67*4882a593Smuzhiyun     | |           | |        callbacks        +--------------+
68*4882a593Smuzhiyun     | | Physical  | |
69*4882a593Smuzhiyun     | |  device   | |  mdev_register_device() +--------------+
70*4882a593Smuzhiyun     | | interface | |<------------------------+              |
71*4882a593Smuzhiyun     | |           | |                         |  i915.ko     |<-> physical
72*4882a593Smuzhiyun     | |           | +------------------------>+              |    device
73*4882a593Smuzhiyun     | |           | |        callbacks        +--------------+
74*4882a593Smuzhiyun     | |           | |
75*4882a593Smuzhiyun     | |           | |  mdev_register_device() +--------------+
76*4882a593Smuzhiyun     | |           | +<------------------------+              |
77*4882a593Smuzhiyun     | |           | |                         | ccw_device.ko|<-> physical
78*4882a593Smuzhiyun     | |           | +------------------------>+              |    device
79*4882a593Smuzhiyun     | |           | |        callbacks        +--------------+
80*4882a593Smuzhiyun     | +-----------+ |
81*4882a593Smuzhiyun     +---------------+
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun
84*4882a593SmuzhiyunRegistration Interfaces
85*4882a593Smuzhiyun=======================
86*4882a593Smuzhiyun
87*4882a593SmuzhiyunThe mediated core driver provides the following types of registration
88*4882a593Smuzhiyuninterfaces:
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun* Registration interface for a mediated bus driver
91*4882a593Smuzhiyun* Physical device driver interface
92*4882a593Smuzhiyun
93*4882a593SmuzhiyunRegistration Interface for a Mediated Bus Driver
94*4882a593Smuzhiyun------------------------------------------------
95*4882a593Smuzhiyun
96*4882a593SmuzhiyunThe registration interface for a mediated bus driver provides the following
97*4882a593Smuzhiyunstructure to represent a mediated device's driver::
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun     /*
100*4882a593Smuzhiyun      * struct mdev_driver [2] - Mediated device's driver
101*4882a593Smuzhiyun      * @name: driver name
102*4882a593Smuzhiyun      * @probe: called when new device created
103*4882a593Smuzhiyun      * @remove: called when device removed
104*4882a593Smuzhiyun      * @driver: device driver structure
105*4882a593Smuzhiyun      */
106*4882a593Smuzhiyun     struct mdev_driver {
107*4882a593Smuzhiyun	     const char *name;
108*4882a593Smuzhiyun	     int  (*probe)  (struct device *dev);
109*4882a593Smuzhiyun	     void (*remove) (struct device *dev);
110*4882a593Smuzhiyun	     struct device_driver    driver;
111*4882a593Smuzhiyun     };
112*4882a593Smuzhiyun
113*4882a593SmuzhiyunA mediated bus driver for mdev should use this structure in the function calls
114*4882a593Smuzhiyunto register and unregister itself with the core driver:
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun* Register::
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun    extern int  mdev_register_driver(struct mdev_driver *drv,
119*4882a593Smuzhiyun				   struct module *owner);
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun* Unregister::
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun    extern void mdev_unregister_driver(struct mdev_driver *drv);
124*4882a593Smuzhiyun
125*4882a593SmuzhiyunThe mediated bus driver is responsible for adding mediated devices to the VFIO
126*4882a593Smuzhiyungroup when devices are bound to the driver and removing mediated devices from
127*4882a593Smuzhiyunthe VFIO when devices are unbound from the driver.
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun
130*4882a593SmuzhiyunPhysical Device Driver Interface
131*4882a593Smuzhiyun--------------------------------
132*4882a593Smuzhiyun
133*4882a593SmuzhiyunThe physical device driver interface provides the mdev_parent_ops[3] structure
134*4882a593Smuzhiyunto define the APIs to manage work in the mediated core driver that is related
135*4882a593Smuzhiyunto the physical device.
136*4882a593Smuzhiyun
137*4882a593SmuzhiyunThe structures in the mdev_parent_ops structure are as follows:
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun* dev_attr_groups: attributes of the parent device
140*4882a593Smuzhiyun* mdev_attr_groups: attributes of the mediated device
141*4882a593Smuzhiyun* supported_config: attributes to define supported configurations
142*4882a593Smuzhiyun
143*4882a593SmuzhiyunThe functions in the mdev_parent_ops structure are as follows:
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun* create: allocate basic resources in a driver for a mediated device
146*4882a593Smuzhiyun* remove: free resources in a driver when a mediated device is destroyed
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun(Note that mdev-core provides no implicit serialization of create/remove
149*4882a593Smuzhiyuncallbacks per mdev parent device, per mdev type, or any other categorization.
150*4882a593SmuzhiyunVendor drivers are expected to be fully asynchronous in this respect or
151*4882a593Smuzhiyunprovide their own internal resource protection.)
152*4882a593Smuzhiyun
153*4882a593SmuzhiyunThe callbacks in the mdev_parent_ops structure are as follows:
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun* open: open callback of mediated device
156*4882a593Smuzhiyun* close: close callback of mediated device
157*4882a593Smuzhiyun* ioctl: ioctl callback of mediated device
158*4882a593Smuzhiyun* read : read emulation callback
159*4882a593Smuzhiyun* write: write emulation callback
160*4882a593Smuzhiyun* mmap: mmap emulation callback
161*4882a593Smuzhiyun
162*4882a593SmuzhiyunA driver should use the mdev_parent_ops structure in the function call to
163*4882a593Smuzhiyunregister itself with the mdev core driver::
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun	extern int  mdev_register_device(struct device *dev,
166*4882a593Smuzhiyun	                                 const struct mdev_parent_ops *ops);
167*4882a593Smuzhiyun
168*4882a593SmuzhiyunHowever, the mdev_parent_ops structure is not required in the function call
169*4882a593Smuzhiyunthat a driver should use to unregister itself with the mdev core driver::
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun	extern void mdev_unregister_device(struct device *dev);
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun
174*4882a593SmuzhiyunMediated Device Management Interface Through sysfs
175*4882a593Smuzhiyun==================================================
176*4882a593Smuzhiyun
177*4882a593SmuzhiyunThe management interface through sysfs enables user space software, such as
178*4882a593Smuzhiyunlibvirt, to query and configure mediated devices in a hardware-agnostic fashion.
179*4882a593SmuzhiyunThis management interface provides flexibility to the underlying physical
180*4882a593Smuzhiyundevice's driver to support features such as:
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun* Mediated device hot plug
183*4882a593Smuzhiyun* Multiple mediated devices in a single virtual machine
184*4882a593Smuzhiyun* Multiple mediated devices from different physical devices
185*4882a593Smuzhiyun
186*4882a593SmuzhiyunLinks in the mdev_bus Class Directory
187*4882a593Smuzhiyun-------------------------------------
188*4882a593SmuzhiyunThe /sys/class/mdev_bus/ directory contains links to devices that are registered
189*4882a593Smuzhiyunwith the mdev core driver.
190*4882a593Smuzhiyun
191*4882a593SmuzhiyunDirectories and files under the sysfs for Each Physical Device
192*4882a593Smuzhiyun--------------------------------------------------------------
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun::
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun  |- [parent physical device]
197*4882a593Smuzhiyun  |--- Vendor-specific-attributes [optional]
198*4882a593Smuzhiyun  |--- [mdev_supported_types]
199*4882a593Smuzhiyun  |     |--- [<type-id>]
200*4882a593Smuzhiyun  |     |   |--- create
201*4882a593Smuzhiyun  |     |   |--- name
202*4882a593Smuzhiyun  |     |   |--- available_instances
203*4882a593Smuzhiyun  |     |   |--- device_api
204*4882a593Smuzhiyun  |     |   |--- description
205*4882a593Smuzhiyun  |     |   |--- [devices]
206*4882a593Smuzhiyun  |     |--- [<type-id>]
207*4882a593Smuzhiyun  |     |   |--- create
208*4882a593Smuzhiyun  |     |   |--- name
209*4882a593Smuzhiyun  |     |   |--- available_instances
210*4882a593Smuzhiyun  |     |   |--- device_api
211*4882a593Smuzhiyun  |     |   |--- description
212*4882a593Smuzhiyun  |     |   |--- [devices]
213*4882a593Smuzhiyun  |     |--- [<type-id>]
214*4882a593Smuzhiyun  |          |--- create
215*4882a593Smuzhiyun  |          |--- name
216*4882a593Smuzhiyun  |          |--- available_instances
217*4882a593Smuzhiyun  |          |--- device_api
218*4882a593Smuzhiyun  |          |--- description
219*4882a593Smuzhiyun  |          |--- [devices]
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun* [mdev_supported_types]
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun  The list of currently supported mediated device types and their details.
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun  [<type-id>], device_api, and available_instances are mandatory attributes
226*4882a593Smuzhiyun  that should be provided by vendor driver.
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun* [<type-id>]
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun  The [<type-id>] name is created by adding the device driver string as a prefix
231*4882a593Smuzhiyun  to the string provided by the vendor driver. This format of this name is as
232*4882a593Smuzhiyun  follows::
233*4882a593Smuzhiyun
234*4882a593Smuzhiyun	sprintf(buf, "%s-%s", dev_driver_string(parent->dev), group->name);
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun  (or using mdev_parent_dev(mdev) to arrive at the parent device outside
237*4882a593Smuzhiyun  of the core mdev code)
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun* device_api
240*4882a593Smuzhiyun
241*4882a593Smuzhiyun  This attribute should show which device API is being created, for example,
242*4882a593Smuzhiyun  "vfio-pci" for a PCI device.
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun* available_instances
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun  This attribute should show the number of devices of type <type-id> that can be
247*4882a593Smuzhiyun  created.
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun* [device]
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun  This directory contains links to the devices of type <type-id> that have been
252*4882a593Smuzhiyun  created.
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun* name
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun  This attribute should show human readable name. This is optional attribute.
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun* description
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun  This attribute should show brief features/description of the type. This is
261*4882a593Smuzhiyun  optional attribute.
262*4882a593Smuzhiyun
263*4882a593SmuzhiyunDirectories and Files Under the sysfs for Each mdev Device
264*4882a593Smuzhiyun----------------------------------------------------------
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun::
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun  |- [parent phy device]
269*4882a593Smuzhiyun  |--- [$MDEV_UUID]
270*4882a593Smuzhiyun         |--- remove
271*4882a593Smuzhiyun         |--- mdev_type {link to its type}
272*4882a593Smuzhiyun         |--- vendor-specific-attributes [optional]
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun* remove (write only)
275*4882a593Smuzhiyun
276*4882a593SmuzhiyunWriting '1' to the 'remove' file destroys the mdev device. The vendor driver can
277*4882a593Smuzhiyunfail the remove() callback if that device is active and the vendor driver
278*4882a593Smuzhiyundoesn't support hot unplug.
279*4882a593Smuzhiyun
280*4882a593SmuzhiyunExample::
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun	# echo 1 > /sys/bus/mdev/devices/$mdev_UUID/remove
283*4882a593Smuzhiyun
284*4882a593SmuzhiyunMediated device Hot plug
285*4882a593Smuzhiyun------------------------
286*4882a593Smuzhiyun
287*4882a593SmuzhiyunMediated devices can be created and assigned at runtime. The procedure to hot
288*4882a593Smuzhiyunplug a mediated device is the same as the procedure to hot plug a PCI device.
289*4882a593Smuzhiyun
290*4882a593SmuzhiyunTranslation APIs for Mediated Devices
291*4882a593Smuzhiyun=====================================
292*4882a593Smuzhiyun
293*4882a593SmuzhiyunThe following APIs are provided for translating user pfn to host pfn in a VFIO
294*4882a593Smuzhiyundriver::
295*4882a593Smuzhiyun
296*4882a593Smuzhiyun	extern int vfio_pin_pages(struct device *dev, unsigned long *user_pfn,
297*4882a593Smuzhiyun				  int npage, int prot, unsigned long *phys_pfn);
298*4882a593Smuzhiyun
299*4882a593Smuzhiyun	extern int vfio_unpin_pages(struct device *dev, unsigned long *user_pfn,
300*4882a593Smuzhiyun				    int npage);
301*4882a593Smuzhiyun
302*4882a593SmuzhiyunThese functions call back into the back-end IOMMU module by using the pin_pages
303*4882a593Smuzhiyunand unpin_pages callbacks of the struct vfio_iommu_driver_ops[4]. Currently
304*4882a593Smuzhiyunthese callbacks are supported in the TYPE1 IOMMU module. To enable them for
305*4882a593Smuzhiyunother IOMMU backend modules, such as PPC64 sPAPR module, they need to provide
306*4882a593Smuzhiyunthese two callback functions.
307*4882a593Smuzhiyun
308*4882a593SmuzhiyunUsing the Sample Code
309*4882a593Smuzhiyun=====================
310*4882a593Smuzhiyun
311*4882a593Smuzhiyunmtty.c in samples/vfio-mdev/ directory is a sample driver program to
312*4882a593Smuzhiyundemonstrate how to use the mediated device framework.
313*4882a593Smuzhiyun
314*4882a593SmuzhiyunThe sample driver creates an mdev device that simulates a serial port over a PCI
315*4882a593Smuzhiyuncard.
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun1. Build and load the mtty.ko module.
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun   This step creates a dummy device, /sys/devices/virtual/mtty/mtty/
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun   Files in this device directory in sysfs are similar to the following::
322*4882a593Smuzhiyun
323*4882a593Smuzhiyun     # tree /sys/devices/virtual/mtty/mtty/
324*4882a593Smuzhiyun        /sys/devices/virtual/mtty/mtty/
325*4882a593Smuzhiyun        |-- mdev_supported_types
326*4882a593Smuzhiyun        |   |-- mtty-1
327*4882a593Smuzhiyun        |   |   |-- available_instances
328*4882a593Smuzhiyun        |   |   |-- create
329*4882a593Smuzhiyun        |   |   |-- device_api
330*4882a593Smuzhiyun        |   |   |-- devices
331*4882a593Smuzhiyun        |   |   `-- name
332*4882a593Smuzhiyun        |   `-- mtty-2
333*4882a593Smuzhiyun        |       |-- available_instances
334*4882a593Smuzhiyun        |       |-- create
335*4882a593Smuzhiyun        |       |-- device_api
336*4882a593Smuzhiyun        |       |-- devices
337*4882a593Smuzhiyun        |       `-- name
338*4882a593Smuzhiyun        |-- mtty_dev
339*4882a593Smuzhiyun        |   `-- sample_mtty_dev
340*4882a593Smuzhiyun        |-- power
341*4882a593Smuzhiyun        |   |-- autosuspend_delay_ms
342*4882a593Smuzhiyun        |   |-- control
343*4882a593Smuzhiyun        |   |-- runtime_active_time
344*4882a593Smuzhiyun        |   |-- runtime_status
345*4882a593Smuzhiyun        |   `-- runtime_suspended_time
346*4882a593Smuzhiyun        |-- subsystem -> ../../../../class/mtty
347*4882a593Smuzhiyun        `-- uevent
348*4882a593Smuzhiyun
349*4882a593Smuzhiyun2. Create a mediated device by using the dummy device that you created in the
350*4882a593Smuzhiyun   previous step::
351*4882a593Smuzhiyun
352*4882a593Smuzhiyun     # echo "83b8f4f2-509f-382f-3c1e-e6bfe0fa1001" >	\
353*4882a593Smuzhiyun              /sys/devices/virtual/mtty/mtty/mdev_supported_types/mtty-2/create
354*4882a593Smuzhiyun
355*4882a593Smuzhiyun3. Add parameters to qemu-kvm::
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun     -device vfio-pci,\
358*4882a593Smuzhiyun      sysfsdev=/sys/bus/mdev/devices/83b8f4f2-509f-382f-3c1e-e6bfe0fa1001
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun4. Boot the VM.
361*4882a593Smuzhiyun
362*4882a593Smuzhiyun   In the Linux guest VM, with no hardware on the host, the device appears
363*4882a593Smuzhiyun   as  follows::
364*4882a593Smuzhiyun
365*4882a593Smuzhiyun     # lspci -s 00:05.0 -xxvv
366*4882a593Smuzhiyun     00:05.0 Serial controller: Device 4348:3253 (rev 10) (prog-if 02 [16550])
367*4882a593Smuzhiyun             Subsystem: Device 4348:3253
368*4882a593Smuzhiyun             Physical Slot: 5
369*4882a593Smuzhiyun             Control: I/O+ Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr-
370*4882a593Smuzhiyun     Stepping- SERR- FastB2B- DisINTx-
371*4882a593Smuzhiyun             Status: Cap- 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort-
372*4882a593Smuzhiyun     <TAbort- <MAbort- >SERR- <PERR- INTx-
373*4882a593Smuzhiyun             Interrupt: pin A routed to IRQ 10
374*4882a593Smuzhiyun             Region 0: I/O ports at c150 [size=8]
375*4882a593Smuzhiyun             Region 1: I/O ports at c158 [size=8]
376*4882a593Smuzhiyun             Kernel driver in use: serial
377*4882a593Smuzhiyun     00: 48 43 53 32 01 00 00 02 10 02 00 07 00 00 00 00
378*4882a593Smuzhiyun     10: 51 c1 00 00 59 c1 00 00 00 00 00 00 00 00 00 00
379*4882a593Smuzhiyun     20: 00 00 00 00 00 00 00 00 00 00 00 00 48 43 53 32
380*4882a593Smuzhiyun     30: 00 00 00 00 00 00 00 00 00 00 00 00 0a 01 00 00
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun     In the Linux guest VM, dmesg output for the device is as follows:
383*4882a593Smuzhiyun
384*4882a593Smuzhiyun     serial 0000:00:05.0: PCI INT A -> Link[LNKA] -> GSI 10 (level, high) -> IRQ 10
385*4882a593Smuzhiyun     0000:00:05.0: ttyS1 at I/O 0xc150 (irq = 10) is a 16550A
386*4882a593Smuzhiyun     0000:00:05.0: ttyS2 at I/O 0xc158 (irq = 10) is a 16550A
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun
389*4882a593Smuzhiyun5. In the Linux guest VM, check the serial ports::
390*4882a593Smuzhiyun
391*4882a593Smuzhiyun     # setserial -g /dev/ttyS*
392*4882a593Smuzhiyun     /dev/ttyS0, UART: 16550A, Port: 0x03f8, IRQ: 4
393*4882a593Smuzhiyun     /dev/ttyS1, UART: 16550A, Port: 0xc150, IRQ: 10
394*4882a593Smuzhiyun     /dev/ttyS2, UART: 16550A, Port: 0xc158, IRQ: 10
395*4882a593Smuzhiyun
396*4882a593Smuzhiyun6. Using minicom or any terminal emulation program, open port /dev/ttyS1 or
397*4882a593Smuzhiyun   /dev/ttyS2 with hardware flow control disabled.
398*4882a593Smuzhiyun
399*4882a593Smuzhiyun7. Type data on the minicom terminal or send data to the terminal emulation
400*4882a593Smuzhiyun   program and read the data.
401*4882a593Smuzhiyun
402*4882a593Smuzhiyun   Data is loop backed from hosts mtty driver.
403*4882a593Smuzhiyun
404*4882a593Smuzhiyun8. Destroy the mediated device that you created::
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun     # echo 1 > /sys/bus/mdev/devices/83b8f4f2-509f-382f-3c1e-e6bfe0fa1001/remove
407*4882a593Smuzhiyun
408*4882a593SmuzhiyunReferences
409*4882a593Smuzhiyun==========
410*4882a593Smuzhiyun
411*4882a593Smuzhiyun1. See Documentation/driver-api/vfio.rst for more information on VFIO.
412*4882a593Smuzhiyun2. struct mdev_driver in include/linux/mdev.h
413*4882a593Smuzhiyun3. struct mdev_parent_ops in include/linux/mdev.h
414*4882a593Smuzhiyun4. struct vfio_iommu_driver_ops in include/linux/vfio.h
415