E.3. 如何识别和分配 IOMMU 组
本例演示如何识别和分配目标系统上存在的 PCI 设备。有关更多示例和信息,请参阅 第 16.7 节 “分配 GPU 设备”。
过程 E.1. IOMMU 组
列出设备
通过运行 virsh nodev-list device-type 命令确定系统中的设备。本例演示如何定位 PCI 设备。为简洁起见,输出已被截断。# virsh nodedev-list pci pci_0000_00_00_0 pci_0000_00_01_0 pci_0000_00_03_0 pci_0000_00_07_0 [...] pci_0000_00_1c_0 pci_0000_00_1c_4 [...] pci_0000_01_00_0 pci_0000_01_00_1 [...] pci_0000_03_00_0 pci_0000_03_00_1 pci_0000_04_00_0 pci_0000_05_00_0 pci_0000_06_0d_0
找到设备的 IOMMU 分组
对于列出的每个设备,可以使用 virsh nodedev-dumpxml name-of-device 命令找到有关设备(包括 IOMMU 分组)的每个设备的信息。例如,要查找名为 pci_0000_04_00_0(PCI 地址 0000:04:00.0)的 PCI 设备的 IOMMU 分组,请使用以下命令:# virsh nodedev-dumpxml pci_0000_04_00_0
这个命令会生成类似于显示的 XML 转储。图 E.1. IOMMU 组 XML
<device> <name>pci_0000_04_00_0</name> <path>/sys/devices/pci0000:00/0000:00:1c.0/0000:04:00.0</path> <parent>pci_0000_00_1c_0</parent> <capability type='pci'> <domain>0</domain> <bus>4</bus> <slot>0</slot> <function>0</function> <product id='0x10d3'>82574L Gigabit Network Connection</product> <vendor id='0x8086'>Intel Corporation</vendor> <iommuGroup number='8'> <!--This is the element block you will need to use--> <address domain='0x0000' bus='0x00' slot='0x1c' function='0x0'/> <address domain='0x0000' bus='0x00' slot='0x1c' function='0x4'/> <address domain='0x0000' bus='0x04' slot='0x00' function='0x0'/> <address domain='0x0000' bus='0x05' slot='0x00' function='0x0'/> </iommuGroup> <pci-express> <link validity='cap' port='0' speed='2.5' width='1'/> <link validity='sta' speed='2.5' width='1'/> </pci-express> </capability> </device>
查看 PCI 数据
在以上输出中,有一个有 4 个设备的 IOMMU 组。这是在没有 ACS 支持的多功能 PCIe root 端口的示例。插槽 0x1c 中的两个功能是 PCIe root 端口,可以通过运行 lspci 命令(来自 pciutils 软件包)来标识:# lspci -s 1c 00:1c.0 PCI bridge: Intel Corporation 82801JI (ICH10 Family) PCI Express Root Port 1 00:1c.4 PCI bridge: Intel Corporation 82801JI (ICH10 Family) PCI Express Root Port 5
在总线 0x04 和 0x05 上为两个 PCIe 设备重复此步骤,它们是端点设备。# lspci -s 4 04:00.0 Ethernet controller: Intel Corporation 82574L Gigabit Network Connection This is used in the next step and is called 04:00.0 # lspci -s 5 This is used in the next step and is called 05:00.0 05:00.0 Ethernet controller: Broadcom Corporation NetXtreme BCM5755 Gigabit Ethernet PCI Express (rev 02)
为客户机虚拟机分配端点
要为虚拟机分配其中一个端点(您目前没有分配的端点)必须与 VFIO 兼容驱动程序绑定,以便 IOMMU 组不在用户和主机驱动程序之间分割。例如,使用上面收到的输出时,您要使用 04:00.0 配置虚拟机,除非 05:00.0 断开与主机驱动程序分离,否则虚拟机将无法启动。要分离 05:00.0,以 root 用户身份运行 virsh nodedev-detach 命令:# virsh nodedev-detach pci_0000_05_00_0 Device pci_0000_05_00_0 detached
为虚拟机分配两个端点是解决此问题的另一种选择。请注意,当为<hostdev>
元素内的managed
属性使用 yes 值时,libvirt 将自动为附加设备执行此操作。例如:<hostdev mode='subsystem' type='pci' managed='yes'>
。如需更多信息,请参阅 注意。
注意
libvirt 有两种处理 PCI 设备的方法。它们可以是受管或非受管。这由提供给
<hostdev>
元素中的 managed
属性的值决定。当设备被管理时,libvirt 会自动从现有驱动程序中分离该设备,然后将其绑定到 vfio-pci on boot(用于虚拟机)来将其分配给虚拟机。当虚拟机关闭或删除时,或者 PCI 设备与虚拟机分离时,libvirt 不会绑定来自 vfio-pci 的设备,并将其重新绑定到原始驱动程序。如果设备是非受管设备,则 libvirt 不会自动这个过程,且必须在将设备分配给虚拟机之前确保所有这些管理方面完成,且在该设备不再被虚拟机使用后,您必须重新分配设备。在非受管设备中无法执行这些操作将导致虚拟机失败。因此,确保 libvirt 管理该设备可能更简单。