在qemu虚拟机中为了提高网络的性能,将本地host端的多余网卡透传到虚拟机中使用。
设备的透传需要主机支持Intel(VT-d)或AMD (IOMMU)硬件虚拟化加速技术
查看是否开启IOMMU1dmesg | grep -e DMAR -e IOMMU
开启IOMMU功能操作系统:Centos7,cpu: Intel(R) Xeon(R)
编辑/boot/efi/EFI/centos/grub.cfg文件,在系统启动内核的选项linuxefi中追加intel_iommu=on1
2
3< linuxefi /vmlinuz-3.10.0-1127.18.2.el7.x86_64 root=/dev/mapper/centos-root ro crashkernel=auto spectre_v2=retpoline rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet LANG=en_US.UTF-8 intel_iommu=on
---
> linuxefi /vmlinuz-3.10.0-1127.18.2.el7.x86_64 root=/dev/mapper/centos-root ro crashkernel=auto spectre_v2=retpoline rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet LANG=en_US.UTF-8
系统重启后,查看支持IOMMU的设备:1
2
3
4#find /sys/kernel/iommu_groups/ -type l
/sys/kernel/iommu_groups/0/devices/0000:00:00.0
/sys/kernel/iommu_groups/1/devices/0000:00:04.0
...
查看BIOS是否开启intel-vt-x/vt-d1cat /proc/cpuinfo | grep vmx
如果没有开启需要在BOIS中使能intel-vt-x/vt-d
选择绑定网卡
通过ifconfig ethx down/up开关相应的网络节点,获取相应的pci地址,该地址可以通过dmesg查看判断1
2
3
4#dmesg -c
#ifconfig p1p1 down
#dmesg
[27244.804247] ixgbe 0000:3b:00.0: removed PHC on p1p1p1p1端口对应网卡的pci地址:0000:3b:00.0
加载vfio驱动1
2modprobe vfio
modprobe vfio-pci
网卡透传
Host端解绑网卡1echo "0000:3b:00.0" > /sys/bus/pci/devices/0000\:3b\:00.0/driver/unbind
注意在解绑网卡是需要将该网卡下的所有端口设备全部解绑,比如1
2ls /sys/bus/pci/devices/0000\:18\:00.0/iommu_group/devices/
0000:18:00.0 0000:18:00.1
需要将0000:18:00.0,0000:18:00.1全部进行解绑
生成vfio设备1
2
3#lspci -s 0000:3b:00.0 -n
3b:00.0 0200: 8086:154d (rev 01)
#echo "8086 154d" > /sys/bus/pci/drivers/vfio-pci/new_id在/dev/vfio/下面会有个以阿拉伯数字命名的文件,对应vfio设备组
绑定vfio总线驱动1echo "0000:3b:00.0" > /sys/bus/pci/drivers/vfio-pci/bind
虚拟机参数1-device vfio-pci,host=0000:3b:00.0在qemu的启动参数中添加上面参数,该物理网卡将被透传到虚拟机中。
问题
在进行网卡的透传过程中,出现以下错误:1
22020-09-23T10:16:51.707664Z qemu-system-x86_64: -device vfio-pci,host=0000:3b:00.0,id=hostdev0,bus=pci.0,addr=0xa: vfio 0000:3b:00.0: group 25 is not viable
Please ensure all devices within the iommu_group are bound to their vfio bus driver.
该错误的原因:在进行网卡透传时,以上提到的pci地址(0000:3b:00.0)其实为一张物理网卡的一个端口地址,一般的网卡都是两个端口,而此时只绑定了一个端口,需要将两个端口设备都进行解绑并绑定到vfio总线驱动上1
2#ls /sys/bus/pci/devices/0000\:18\:00.0/iommu_group/devices/
0000:18:00.0 0000:18:00.1
脚本处理
为了以后处理方便将host端的配置进行脚本处理1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34#/bin/bash
#set -x
PCI_ADDR="18:00.1"
modprobe vfio
modprobe vfio-pci
lsmod | grep vfio
lspci -s $PCI_ADDR -n #em2
device_id=`lspci -s $PCI_ADDR -n | awk '{print $3}'`
device_id=${device_id/:/ } #去除:号
echo "PCI: $PCI_ADDR, Device ID:$device_id"
#生成vfio设备
echo "$device_id" > /sys/bus/pci/drivers/vfio-pci/new_id
#pci设备绑定vfio总线驱动(解绑--绑定)
pci_device=/sys/bus/pci/devices/0000:$PCI_ADDR/iommu_group/devices/
pci_device=`echo $pci_device | sed 's/:/\\:/g'` #添加转移符,echo打印不出来
#ls $pci_device
for dev in `ls $pci_device`
do
echo "---dev:$dev"
_pci_dev_unbind="/sys/bus/pci/devices/$dev/driver/unbind"
_pci_dev_unbind=`echo $_pci_dev_unbind | sed 's/:/\\:/g'`
#ls $_pci_dev_unbind
echo "$dev" > $_pci_dev_unbind
echo "$dev" > /sys/bus/pci/drivers/vfio-pci/bind
lspci -s $dev -k
done
ls /dev/vfio/
virsh命令解除绑定Host端的设备解除绑定(就是不被host系统所管理使用)后,通过给guest系统使用前的必备操作列出设备ID1
2
3#virsh nodedev-list | grep pci | grep 18
pci_0000_18_00_0
pci_0000_18_00_1
查询当前使用的驱动程序1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#virsh nodedev-dumpxml pci_0000_18_00_0
pci_0000_18_00_0
/sys/devices/pci0000:17/0000:17:03.0/0000:18:00.0
pci_0000_17_03_0
vfio-pci
0
24
0
0
NetXtreme BCM5720 2-port Gigabit Ethernet PCIe
Broadcom Inc. and subsidiaries
这是设备手动解除绑定后dump出的详细信息,如果没有解除绑定数据可能不同解绑当前设备1
2#virsh nodedev-detach pci_0000_18_00_0
#virsh nodedev-detach pci_0000_18_00_1
参考