Discovering and connecting VIRTIO devices
Several methods are available for connecting a device driver in a guest to its corresponding hypervisor host device.
A device driver running in a guest can use one of the following methods to connect to a VIRTIO vdev in the host:
The method you use will depend on how your guest is configured, and how easy or difficult you want to make changing the device location. For example, in a production system, direct memory mapping (where you write in your configurations the locations in memory of your devices) may be acceptable or even preferable, but you may require a more flexible approach during your project's development phase and therefore may want to use PCI discovery.
PCI discovery
The PCI discovery method is most common in guests designed for x86 platforms, but it can also be used by guests on ARM platforms. PCI hardware isn't required to support this discovery mechanism, because in a hypervisor, guest PCI is completely virtual.
The following steps explain how PCI mapping can be used to enable a driver in a guest to discover and connect to a VIRTIO device. The example uses the virtio-blk vdev, but could also use other VIRTIO vdevs such as virtio-console or virtio-net.
Using virtio-blk and a QNX guest, PCI discovery can be done as follows:
- In the hypervisor host, start the driver for the AHCI SATA interfaces (devb-ahci).
- Configure the VM hosting the guest to map the location of the AHCI SATA
driver (located at /dev/hd1t178) through VIRTIO
to the guest; for example:
vdev virtio-blk hostdev /dev/hd1t178 name virtio-blk_qvm178
See vdev virtio-blk for more information about configuring this vdev in the VM.
- Start the QNX guest.
- In the guest, run pci-server (see pci-server in the
Utilities Reference); for example:
pci-server –bus-scan-limit=8
- In the QNX guest, use pci-tool to query
the PCI device (see pci-tool in the
Utilities Reference); for example:
[x86 guest QNX 8.0]% pci-tool -v B000:D00:F00 @ idx 0 vid/did: 1c05/0002 BlackBerry QNX, n/a QVM PCI host bridge class/subclass/reg: 06/00/00 Host-to-PCI Bridge Device B000:D01:F00 @ idx 1 vid/did: 1af4/1042 <vendor id - unknown>, <device id - unknown> class/subclass/reg: 01/80/00 Other Mass Storage Controller B000:D02:F00 @ idx 2 vid/did: 1af4/1041 <vendor id - unknown>, <device id - unknown> class/subclass/reg: 02/80/00 Other Network Controller B000:D03:F00 @ idx 3 vid/did: 1c05/0001 BlackBerry QNX, n/a QVM guest shared memory factory class/subclass/reg: 05/80/00 Other Memory Controller B000:D04:F00 @ idx 4 vid/did: 1af4/1043 <vendor id - unknown>, <device id - unknown> class/subclass/reg: 07/80/00 Other Simple Communications Controller
Note that the disk controller appears with a VID/DID (vendor ID/device ID) of
1af4/1042
; this is the VIRTIO standard reference for a mass storage device. Other devices such as memory devices or network devices will also show up as PCI devices.In a Linux guest, you can use lspci. You may see the VID/DID as
1c05/0042
; this is the BlackBerry VIRTIO vendor ID. The Linux kernel module understands that this is a block device. - In the QNX guest, start the VIRTIO driver for block devices
(devb-virtio); for example:
The driver will scan the PCI space to find the device with thedevb-virtio
1af4/1042
vendor ID/device ID and mount it as a block volume; for instance, the above command will create /dev/hd0 in the guest. - If the block volume is already formatted as a QNX6 power-safe
filesystem, you can mount it; for example:
mount -tqnx6 /dev/hd0 /mydisk
Direct memory mapping
The following steps explain how a device can be mapped in the host, then the mapping passed on to a driver in a guest. The example uses the virtio-blk vdev, but could also use other VIRTIO vdevs such as virtio-console or virtio-net.
Using virtio-blk and a QNX guest, memory mapping can be done as follows:
- In the hypervisor host, start the driver for the appropriate interfaces (e.g., devb-ahci).
Configure the VM with the path of the host file to use for the contents of the device (see vdev virtio-blk in the
Virtual Device Reference
chapter).Use a location in guest-physical memory that isn't used by any other driver in the guest, and an interrupt that isn't used by any other driver or service in the guest. In this example we use0x1c0d0000
and41
:vdev virtio-blk loc 0x1c0d0000 intr gic:41 hostdev /dev/hd1t178 name virtio-blk_qvm178
- Start the QNX guest. No PCI server is needed.
- Start the VIRTIO block device driver
(devb-virtio) in the guest,
using the driver's startup options to map in the
memory and interrupt you specified in the virtio-blk
vdev configuration; in our example the options would
be as follows:
devb-virtio virtio smem=0x1c0d0000,irq=41
The guest driver should now find the device in the host through the VIRTIO device.
You can use FDTs to expand direct mapping to support dynamic discovery of devices. For example, on an ARM platform you can define an FDT overlay to provide the guest with information about virtual devices.
For more information about using FDTs in a QNX hypervisor system, see
ACPI tables and FDTs
in
the Configuration
chapter.