VFIO 介绍

发布时间: 更新时间: 总字数:988 阅读时间:2m 作者: IP上海 分享 网址

VFIO(Virtual Function IO) 把设备通过 IOMMU 映射的 DMA 物理内存地址映射到 用户态 中,让 用户态程序 可以自行操纵数据的传输,还可以自行注册中断处理函数,从而在 用户态 下实现设备的驱动程序。

介绍

  • 要使用 VFIO 驱动,则必须开启 IOMMU 支持
  • VFIO 是一套完整的 用户态驱动(userspace driver) 方案,因为它可以安全地把设备 I/O中断DMA 等能力呈现给用户空间
  • IOMMUIOMMU_GROUP 代表一组被隔离的设备的集合
  • VFIO Container:在 IOMMU_GROUP 的基础上,VFIO封装了一层Container Class,Container的作用是,当我们想在不同的IOMMU_GROUP之间共享TLB和page tables(用于地址翻译的页表)时,就将这些group放到同一个container中,因此Container可以看做是IOMMU_GROUP的集合
  • 特点:使用 VFIO 可以实现安全的,非特权的,用户空间驱动程序

示例

环境

VM 有两块网卡

  • ens33 172.20.0.132/24 用于 SSH 连接(在VM存放目录文件,修改 <name>.vmwarevm/<name>.vmxethernet0.virtualDev = "e1000"ethernet0.virtualDev = "vmxnet3",可以将该网卡与其默认网卡绑在不同的 pci 设备上)
  • ens36 192.168.2.129/24 用于 VFIO 验证
# ens36 设备
$ lspci
02:04.0 Ethernet controller: Intel Corporation 82545EM Gigabit Ethernet Controller (Copper) (rev 01)
...
$ lspci -vvv -s 02:04.0
02:04.0 Ethernet controller: Intel Corporation 82545EM Gigabit Ethernet Controller (Copper) (rev 01)
	DeviceName: Ethernet1
	Subsystem: VMware PRO/1000 MT Single Port Adapter
	Physical Slot: 36
	Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx-
	Status: Cap+ 66MHz+ UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
	Latency: 0 (63750ns min), Cache Line Size: 64 bytes
	Interrupt: pin A routed to IRQ 18
	Region 0: Memory at fc020000 (64-bit, non-prefetchable) [size=128K]
	Region 2: Memory at fc050000 (64-bit, non-prefetchable) [size=64K]
	Region 4: I/O ports at 1000 [size=64]
	Expansion ROM at fc080000 [disabled] [size=64K]
	Capabilities: [dc] Power Management version 2
		Flags: PMEClk- DSI+ D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
		Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=1 PME-
	Capabilities: [e4] PCI-X non-bridge device
		Command: DPERE- ERO+ RBC=512 OST=1
		Status: Dev=ff:1f.0 64bit+ 133MHz+ SCD- USC- DC=simple DMMRBC=2048 DMOST=1 DMCRS=16 RSCEM- 266MHz- 533MHz-
	Kernel driver in use: e1000
	Kernel modules: e1000

VMware 虚拟机 默认的网卡是 Intel Corporation 82545EM

配置步骤

  • 启用 IOMMU
  • 确认 kernel 是否包含 vfio
$ cat /lib/modules/$(uname -r)/modules.builtin | grep vfio
kernel/drivers/vfio/vfio.ko
kernel/drivers/vfio/vfio_virqfd.ko
kernel/drivers/vfio/vfio_iommu_type1.ko
kernel/drivers/vfio/pci/vfio-pci.ko
  • 加载VFIO-PCI module,默认在 builtin 已经加载
modprobe vfio-pci
  • 查看是加载
$ dmesg | grep -i VFIO
[    3.121466] VFIO - User Level meta-driver version: 0.3
  • 查看网卡所在的 IOMMU Group
$ readlink /sys/bus/pci/devices/0000:02:04.0/iommu_group
../../../../kernel/iommu_groups/5

iommu_group 的 group id 为 5

  • 查看iommu_group 5 的所有设备
$ ls /sys/bus/pci/devices/0000:02:04.0/iommu_group/devices
0000:00:11.0  0000:02:01.0  0000:02:03.0  0000:02:04.0
  • 将上述设备与对应的驱动解绑

为了将设备透传到虚拟机中,需要将设备所在的iommu_group的所有设备与其对应的驱动解绑,这样该设备才可以使用VFIO的驱动

$ echo 0000:00:11.0 | sudo tee /sys/bus/pci/devices/0000:00:11.0/driver/unbind
0000:00:11.0
$ echo 0000:02:01.0 | sudo tee /sys/bus/pci/devices/0000:02:01.0/driver/unbind
0000:02:01.0
$ echo 0000:02:03.0 | sudo tee /sys/bus/pci/devices/0000:02:03.0/driver/unbind
0000:02:03.0
$ echo 0000:02:04.0 | sudo tee /sys/bus/pci/devices/0000:02:04.0/driver/unbind
  • 查看设备的 VendorDeviceID
$ lspci -n -s 02:04.0
02:04.0 0200: 8086:100f (rev 01)

网卡的Vendor为 8086DeviceID100f

  • 将设备绑定到 vfio-pci module
$ echo 8086 100f | sudo tee /sys/bus/pci/drivers/vfio-pci/new_id
8086 100f
  • 启动 VM
$ qemu-system-x86_64 -m 1024 -vnc :0 -hda cirros-0.5.2-x86_64-disk.img -enable-kvm -cpu host -device vfio-pci,host=02:04.0
  • 进入 VM 查看
$ lspci
00:04.0 Class 0200: 8086:100f

虚拟机 中网卡和宿主机上的信息一样,证明宿主机网卡透传到 虚拟机 成功

Home Archives Categories Tags Statistics
本文总阅读量 次 本站总访问量 次 本站总访客数