E.3. IOMMU グループの特定および割り当て方法

この例では、ターゲットシステムにある PCI デバイスを特定し、割り当てる方法を示しています。追加の例および情報については 「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 グループの特定

    IOMMU グループなど、一覧表示された各デバイスの詳細を確認するには virsh nodedev-dumpxml name-of-device コマンドを使用します。たとえば、pci_0000_04_00_0 という名前の PCI デバイス (PCI アドレス 0000:04:00.0) の IOMMU グループを確認するには、以下のコマンドを使用します。
    # virsh nodedev-dumpxml pci_0000_04_00_0
    このコマンドは、以下に示すのと同様の 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>

    図E.1 IOMMU グループ XML

  3. PCI データの表示

    上記で取得した出力では、4 つのデバイスを持つ 1 つの IOMMU グループがあります。これは、ACS サポートのない多機能 PCIe ルートポートの例です。スロット 0x1c の 2 つの機能は PCIe ルートポートであり、これらは pciutilsパッケージから lspci コマンドを実行すると特定できます。
    # 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 の 2 つの PCIe デバイスについてこの手順を繰り返します。
    # lspci -s 4
    04:00.0 Ethernet controller: Intel Corporation 82574L Gigabit Network Connection これは次のステップで使用され、04:00.0 と呼ばれます。
    # lspci -s 5 これは次のステップで使用され、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 デバイスを処理するための方法が 2 つあります。それらは管理対象にも非管理対象にもなります。これは、<hostdev> 要素内の managed 属性に指定される値によって決まります。デバイスが管理対象である場合、libvirt は既存のドライバーからデバイスの割り当てを自動的に解除し、起動時にこれを vfio-pci にバインドしてこれを仮想マシンに割り当てます (仮想マシンの場合)。仮想マシンがシャットダウンされるか、または削除される場合、または PCI デバイスの割り当てが仮想マシンから解除される場合、libvirt はデバイスを vfio-pci のバインドから解除し、これを元のドライバーに再びバインドします。デバイスが非管理対象の場合、libvirt はこのプロセスを自動化しません。デバイスを仮想マシンに割り当てる前に、ここで説明する管理内容すべてが完了していることを確認する必要があります。また、デバイスが仮想マシンで使用されなくなったら、デバイスを再度割り当てる必要があります。非管理対象デバイスでこれらの処理をおこたると、仮想マシンは正しく動作しません。そのため、libvirt がデバイスを管理した方が簡単であると言えます。