Qemu为virtio设备分配了专门的pci设备ID,device IDs (vendor ID 0x1AF4) from 0x1000 through 0x10FF,而pci子系统中的厂商ID和设备ID就成为了virtio类型和厂商域的组成,所以PCI驱动是不需要知道virtio设备类型的真正含义,对于Kernel来说只是注册了一个struct virtio_device,并挂载到了virtio bus类型总线上,并由virtio driver来驱动。
virtio设备对于Linux Kernel中的设备类型来说是作为pci设备被使用的,因此具有pci设备的所有属性,所以其也具备了PCI配置空间。
PCI配置空间域
Linux在PCI设备启动初始化过程中通过IO mapping方式对配置空间的访问地址进行了映射。如下宏定义了每一个配置寄存器相对于PIC配置io基址的偏移。
而通过对如下的相关配置域的配置实现通用的Guest特性、队列、中断等操作。
file: /include/uapi/linux, line: 45
1 | /* A 32-bit r/o bitmask of the features supported by the host */ |
Guest中的操作方式
Guest中virtio驱动通过iowrite/ioread等操作,比如:iowrite16(index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_SEL); 与virtio设备进行交互,而该io操作会被VMM截获,从而转移至Host中进行处理。
而在QEMU中为支持virtio设备的模拟提供了virtio_portio函数注册结构来响应guest的不同读写请求。
file:/hw/virtio-pci.c, line: 464
1 | static const MemoryRegionPortio virtio_portio[] = { |