Red Hat Training

A Red Hat training course is available for Red Hat Enterprise Linux

E.3. 如何识别和分配 IOMMU 组

本例演示如何识别和分配目标系统上存在的 PCI 设备。有关更多示例和信息,请参阅 第 16.7 节 “分配 GPU 设备”

过程 E.1. IOMMU 组

  1. 列出设备

    通过运行 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
    
  2. 找到设备的 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>
  3. 查看 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)
    
  4. 为客户机虚拟机分配端点

    要为虚拟机分配其中一个端点(您目前没有分配的端点)必须与 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 管理该设备可能更简单。