Red Hat Training

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

第12章 PCI デバイスの割り当て

Red Hat Enterprise Linux 6 は、仮想マシンに 3 つのクラスのデバイスを公開します。
  • Emulated devices は、実際のハードウェアを模倣する純粋な仮想デバイスであり、未変更のゲストオペレーティングシステムは標準のインボックスドライバーを使用して動作できるようにします。
  • VirtIO devices は、仮想マシンで最適に動作するように設計された仮想デバイスです。VirtIO デバイスはエミュレートされたデバイスと似ていますが、Linux 以外の仮想マシンには、デフォルトで必要となるドライバーは含まれません。Virtual Machine Manager (virt-manager)や Red Hat Enterprise Virtualization Hypervisor などの仮想化管理ソフトウェアは、サポートされている Linux 以外のゲストオペレーティングシステム用にこれらのドライバーを自動的にインストールします。
  • 割り当てられたデバイス は、仮想マシンに公開される物理デバイスです。このメソッドは passthrough としても知られています。デバイスの割り当てにより、仮想マシンはさまざまなタスクで PCI デバイスに排他的にアクセスできるようになり、PCI デバイスがゲストオペレーティングシステムに物理的に接続されているかのように見え、動作します。
    デバイスの割り当ては、グラフィックカードを除く PCI Express デバイスでサポートされています。パラレル PCI デバイスは、割り当てられたデバイスとしてサポートされる場合がありますが、セキュリティーとシステム設定の競合のために厳しい制限があります。
Red Hat Enterprise Linux 6 は、仮想マシンごとに 32 個の PCI デバイススロットをサポートし、デバイススロットごとに 8 つの PCI 機能をサポートします。これにより、ゲストごとに理論上最大 256 個の設定可能な PCI 機能が提供されます。
ただし、この理論上の最大値は、以下の制限の対象となります。
  • 各仮想マシンは、割り当てられた最大 8 個のデバイス機能をサポートします。
  • PCI デバイススロットは、デフォルトで 5 つのエミュレートされたデバイスで設定されます(2 つのデバイスはスロット 1 にあります)。ただし、ゲストオペレーティングシステムが操作に必要ない場合、ユーザーはデフォルトで設定されるエミュレートされたデバイスの 2 つを明示的に削除できます(スロット 2 のビデオアダプターデバイス、および利用可能な最小スロット(通常はスロット 3)のメモリーバルーンドライバーデバイス)。これにより、サポートされる機能の最大値は、仮想マシンごとに 30 個の PCI デバイススロットになります。
Red Hat Enterprise Linux 6.0 以降では、割り当てられた PCI デバイスを仮想マシンにホットプラグできるようになりました。ただし、PCI デバイスのホットプラグはスロットレベルで動作するため、多機能 PCI デバイスはサポートされません。静的デバイス設定にのみ、多機能の PCI デバイスが推奨されます。
注記
Red Hat Enterprise Linux 6.0 では、デバイスの標準および拡張設定領域へのゲストオペレーティングシステムドライバーへのアクセスが制限されています。Red Hat Enterprise Linux 6.0 に存在する制限は、Red Hat Enterprise Linux 6.1 では大幅に削減され、はるかに大きな PCI Express デバイスセットを KVM ゲストに正常に割り当てることができました。
安全なデバイス割り当てには、割り込みの再マッピングのサポートも必要です。プラットフォームが割り込みの再マッピングをサポートしていない場合、デバイスの割り当ては失敗します。開発環境で割り込みの再マッピングのサポートなしでデバイスの割り当てを使用するには、allow_unsafe_assigned_interrupts KVM モジュールパラメーターを 1 に設定します。
PCI デバイスの割り当ては、Intel VT-d または AMD IOMMU のいずれかに対応するハードウェアプラットフォームでのみ利用できます。PCI デバイスの割り当てを機能させるには、この Intel VT-d または AMD IOMMU の仕様が BIOS で有効になっている必要があります。

手順12.1 PCI デバイス割り当てのための Intel システムの準備

  1. Intel VT-d 仕様を有効にする

    Intel VT-d 仕様では、物理デバイスを仮想マシンに直接割り当てるハードウェアサポートが提供されます。この仕様は、Red Hat Enterprise Linux で PCI デバイスの割り当てを使用するために必要です。
    Intel VT-d 仕様は、BIOS で有効にする必要があります。システムの製造元によっては、この仕様をデフォルトで無効にしている場合があります。これらの仕様を表示するのに使用される用語はメーカーにより異なります。適切な用語は、システムの製造元のドキュメントを参照してください。
  2. カーネルで Intel VT-d をアクティブにします。

    /boot/grub/grub.conf ファイルのカーネル行に intel_iommu=on パラメーターを追加して、カーネルで Intel VT-d をアクティブにします。
    以下の例は、Intel VT-d がアクティブ化された変更された grub.conf ファイルです。
    default=0
    timeout=5
    splashimage=(hd0,0)/grub/splash.xpm.gz
    hiddenmenu
    title Red Hat Enterprise Linux Server (2.6.32-330.x86_645)
            root (hd0,0)
            kernel /vmlinuz-2.6.32-330.x86_64 ro root=/dev/VolGroup00/LogVol00 rhgb quiet intel_iommu=on
            initrd /initrd-2.6.32-330.x86_64.img
  3. 使用準備完了

    システムを再起動して、変更を有効にします。これで、システムで PCI デバイスの割り当てが可能になります。

手順12.2 PCI デバイス割り当て用の AMD システムの準備

  1. AMD IOMMU 仕様を有効にする

    Red Hat Enterprise Linux で PCI デバイスの割り当てを使用するには、AMD IOMMU の仕様が必要です。この仕様は、BIOS で有効にする必要があります。システムの製造元によっては、この仕様をデフォルトで無効にしている場合があります。
  2. IOMMU カーネルサポートの有効化

    システムの起動時に AMD IOMMU 仕様が有効になるように、amd_iommu=on/boot/grub/grub.conf のカーネルコマンドラインに追加します。
  3. 使用準備完了

    システムを再起動して、変更を有効にします。これで、システムで PCI デバイスの割り当てが可能になります。

12.1. virsh を使用した PCI デバイスの割り当て

この手順では、KVM ハイパーバイザーの仮想マシンに PCI デバイスを割り当てる方法を説明します。
この例では、PCI 識別子コード、pci_0000_01_00_0、および完全に仮想化されたゲストマシン guest1-rhel6-64 を持つ PCIe ネットワークコントローラーを使用します。

手順12.3 virsh を使用した PCI デバイスのゲスト仮想マシンへの割り当て

  1. デバイスの識別

    まず、仮想マシンへのデバイス割り当てに指定されている PCI デバイスを特定します。使用可能な PCI デバイスの一覧を表示する場合は、lspci コマンドを実行します。grep を使用して、lspci の出力を絞り込むことができます。
    この例では、以下の出力で強調表示されているイーサネットコントローラーを使用します。
    # lspci | grep Ethernet
    00:19.0 Ethernet controller: Intel Corporation 82567LM-2 Gigabit Network Connection
    01:00.0 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01)
    01:00.1 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01)
    このイーサネットコントローラーは、短い識別子 00:19.0 で表示されます。この PCI デバイスを仮想マシンに割り当てるには、virsh が使用する完全な ID を確認する必要があります。
    これを行うには、virsh nodedev-list コマンドを grep コマンドと組み合わせて、ホストマシンに接続されている特定タイプ(pci)のデバイスをすべて一覧表示します。次に、使用するデバイスの短い識別子にマップする文字列の出力を調べます。
    この例では、短い識別子 00:19.0 を使用して、イーサネットコントローラーにマップする文字列を示しています。: 文字および . 文字は、完全識別子の下線に置き換えられることに注意してください。
    # virsh nodedev-list --cap pci
    pci_0000_00_00_0
    pci_0000_00_01_0
    pci_0000_00_03_0
    pci_0000_00_07_0
    pci_0000_00_10_0
    pci_0000_00_10_1
    pci_0000_00_14_0
    pci_0000_00_14_1
    pci_0000_00_14_2
    pci_0000_00_14_3
    pci_0000_00_19_0
    pci_0000_00_1a_0
    pci_0000_00_1a_1
    pci_0000_00_1a_2
    pci_0000_00_1a_7
    pci_0000_00_1b_0
    pci_0000_00_1c_0
    pci_0000_00_1c_1
    pci_0000_00_1c_4
    pci_0000_00_1d_0
    pci_0000_00_1d_1
    pci_0000_00_1d_2
    pci_0000_00_1d_7
    pci_0000_00_1e_0
    pci_0000_00_1f_0
    pci_0000_00_1f_2
    pci_0000_00_1f_3
    pci_0000_01_00_0
    pci_0000_01_00_1
    pci_0000_02_00_0
    pci_0000_02_00_1
    pci_0000_06_00_0
    pci_0000_07_02_0
    pci_0000_07_03_0
    使用するデバイスにマップする PCI デバイス番号を記録します。これは別の手順で必要になります。
  2. デバイス情報の確認

    ドメイン、バス、および機能の情報は、virsh nodedev-dumpxml コマンドの出力から取得できます。
    virsh nodedev-dumpxml pci_0000_00_19_0
    <device>
      <name>pci_0000_00_19_0</name>
      <parent>computer</parent>
      <driver>
        <name>e1000e</name>
      </driver>
      <capability type='pci'>
        <domain>0</domain>
        <bus>0</bus>
        <slot>25</slot>
        <function>0</function>
        <product id='0x1502'>82579LM Gigabit Network Connection</product>
        <vendor id='0x8086'>Intel Corporation</vendor>
        <capability type='virt_functions'>
        </capability>
      </capability>
    </device>
  3. 必要な設定の詳細を決定する

    設定ファイルに必要な値は、virsh nodedev-dumpxml pci_0000_00_19_0 コマンドの出力を参照してください。
    必要に応じて、slot および function の値を 16 進数から(10 進数から)変換し、PCI バスアドレスを取得します。出力の先頭に 0x を追加して、値が 16 進数であることをコンピューターに指示します。
    この例のデバイスは、bus = 0、slot = 25、および function = 0 の値を持ちます。10 進数の設定では、この 3 つの値が使用されます。
    bus='0'
    slot='25'
    function='0'
    16 進数の値に変換したい場合は、以下の例のように printf ユーティリティーを使用して 10 進数の値から変換できます。
    $ printf %x 0
    0
    $ printf %x 25
    19
    $ printf %x 0
    0
    このサンプルデバイスは、設定ファイルで以下の 16 進数値を使用します。
    bus='0x0'
    slot='0x19'
    function='0x0'
  4. 設定の詳細の追加

    virsh edit を実行し、仮想マシン名を指定し、<source> セクションにデバイスエントリーを追加して、PCI デバイスをゲスト仮想マシンに割り当てます。
    # virsh edit guest1-rhel6-64
    <hostdev mode='subsystem' type='pci' managed='yes'>
      <source>
         <address domain='0x0' bus='0x0' slot='0x19' function='0x0'/>
      </source>
    </hostdev>
    または、virsh attach-device を実行して、仮想マシンの名前とゲストの XML ファイルを指定します。
    virsh attach-device guest1-rhel6-64 file.xml
  5. デバイス管理を許可する

    仮想マシンから PCI デバイスを管理できるようにするには、SELinux ブール値を設定します。
    # setsebool -P virt_use_sysfs 1
  6. 仮想マシンの起動

    # virsh start guest1-rhel6-64
これにより、PCI デバイスが仮想マシンに正常に割り当てられ、ゲストオペレーティングシステムにアクセスできるようになります。