Linux的pcie模拟网卡,Qemu虚拟机pci设备透传——网卡

在qemu虚拟机中为了提高网络的性能,将本地host端的多余网卡透传到虚拟机中使用。

设备的透传需要主机支持Intel(VT-d)或AMD (IOMMU)硬件虚拟化加速技术

Linux的pcie模拟网卡,Qemu虚拟机pci设备透传——网卡_第1张图片

查看是否开启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

参考

你可能感兴趣的:(Linux的pcie模拟网卡)