Red Hat Training

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

第16章 ゲスト仮想マシンデバイスの設定

Red Hat Enterprise Linux 7 は、ゲスト仮想マシンの 3 つのクラスのデバイスをサポートします。
  • エミュレートされたデバイスは、真理的なハードウェアを模倣した仮想デバイスで、標準のインボックスドライバーを使用して、ゲストオペレーティングシステムでそれらと連携できるようにします。
  • VirtIO デバイス (準仮想化とも呼ばれる)は、仮想マシンで最適に機能するように設計された仮想デバイスです。virtio デバイスはエミュレートされたデバイスと似ていますが、Linux 以外の仮想マシンにはデフォルトで必要なドライバーが含まれません。仮想マシンマネージャー(virt-manager)や Red Hat Virtualization Hypervisor などの仮想化管理ソフトウェアは、Linux 以外のゲストオペレーティングシステム用に自動的にこれらのドライバーをインストールします。Red Hat Enterprise Linux 7 は、最大 216 virtio デバイスに対応します。詳細はを参照してください 5章KVM 準仮想化(virtio)ドライバー
  • 割り当てられるデバイスは、仮想マシンに公開される物理デバイスです。この方法は passthrough としても知られています。デバイス割り当てにより、仮想マシンはさまざまなタスクの PCI デバイスへの排他的にアクセスすることができ、PCI デバイスがゲストオペレーティングシステムに物理的に接続されているかのように表示および動作します。Red Hat Enterprise Linux 7 は、仮想マシンごとに割り当てられるデバイスを最大 32 個までサポートします。
    デバイスの割り当ては、一部の グラフィックデバイスを含む PCIe デバイスでサポートされます。並列 PCI デバイスが割り当てられるデバイスとしてサポートされている場合もありますが、セキュリティーおよびシステム設定の競合により、重大な制限があります。
Red Hat Enterprise Linux 7 は、仮想マシンに単一機能スロットとして公開されるデバイスの PCI ホットプラグをサポートします。シングル機能ホストデバイスと多機能ホストデバイスの個々の機能を有効にするよう設定できます。マルチ機能 PCI スロットを仮想マシンに公開する設定は、スナップショット以外のアプリケーションのみに推奨されます。
注記
デバイスが割り当てられたゲストをホストから完全に分離するには、プラットフォームが割り込みの再マッピングをサポートしている必要があります。このようなサポートがないと、ホストは悪意のあるゲストからの割り込み注入攻撃に対して脆弱となる可能性があります。ゲストが信頼できる環境では、管理者は vfio_iommu_type1 モジュールに allow_unsafe_interrupts オプションを使用して引き続き PCI デバイスの割り当てを許可することを選択できます。これは、.conf ファイル(例: local.conf)を、以下の内容を含む /etc/modprobe.d に追加して永続的に実行できます。
options vfio_iommu_type1 allow_unsafe_interrupts=1
または、sysfs エントリーを使用して動的に実行するか、同じ処理を行います。
# echo 1 > /sys/module/vfio_iommu_type1/parameters/allow_unsafe_interrupts

16.1. PCI デバイス

PCI デバイスの割り当ては、Intel VT-d または AMD IOMMU のいずれかをサポートするハードウェアプラットフォームでのみ利用できます。PCI デバイス割り当てが機能するには、これらの Intel VT-d または AMD IOMMU 仕様をホスト BIOS で有効にする必要があります。

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

  1. Intel VT-d 仕様の有効化

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

    /etc/sysconfig/grub ファイルの GRUB_CMDLINX_LINUX 行の最後に intel_iommu=on および iommu=pt パラメーターを追加して、カーネルで Intel VT-d をアクティブ化します。
    以下の例は、Intel VT-d をアクティブにした grub ファイルです。
    GRUB_CMDLINE_LINUX="rd.lvm.lv=vg_VolGroup00/LogVol01
    vconsole.font=latarcyrheb-sun16 rd.lvm.lv=vg_VolGroup_1/root
    vconsole.keymap=us $([ -x /usr/sbin/rhcrashkernel-param ] && /usr/sbin/
    rhcrashkernel-param || :) rhgb quiet intel_iommu=on iommu=pt"
  3. 設定ファイルを再生成します。

    以下を実行して /etc/grub2.cfg を再生成します。
    grub2-mkconfig -o /etc/grub2.cfg
    UEFI ベースのホストを使用している場合は、ターゲットファイルは /etc/grub2-efi.cfg である必要があることに注意してください。
  4. 使用準備が整っています

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

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

  1. AMD IOMMU 仕様の有効化

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

    AMD IOMMU 仕様が起動時に有効にされるように、/etc/sysconfig/grub の GRUB_CMDLINX_LINUX 行の末尾に iommu=pt を追加します。
  3. 設定ファイルを再生成します。

    以下を実行して /etc/grub2.cfg を再生成します。
    grub2-mkconfig -o /etc/grub2.cfg
    UEFI ベースのホストを使用している場合は、ターゲットファイルは /etc/grub2-efi.cfg である必要があることに注意してください。
  4. 使用準備が整っています

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

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

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

手順16.3 virsh でゲスト仮想マシンへの PCI デバイスの割り当て

  1. デバイスの特定

    まず、仮想マシンへのデバイスの割り当て用に指定された PCI デバイスを特定します。lspci コマンドを使用して、利用可能な PCI デバイスを一覧表示します。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 で使用される全識別子を検出する必要があります。
    これには、virsh nodedev-list コマンドを使用して、ホストマシンに接続されている特定のタイプ(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 コマンドの出力から利用できます。

    図16.1 ダンプの内容

    
    # 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>
        <iommuGroup number='7'>
          <address domain='0x0000' bus='0x00' slot='0x19' function='0x0'/>
        </iommuGroup>
      </capability>
    </device>
    
    注記
    IOMMU グループは、IOMMU の観点からデバイスの可視性および分離に基づいて決定されます。各 IOMMU グループには 1 つ以上のデバイスが含まれることがあります。複数のデバイスが存在する場合、IOMMU グループ内のすべてのエンドポイントは、ゲストに割り当てるグループ内のデバイスについて要求する必要があります。これは、追加のエンドポイントをゲストに割り当てるか、virsh nodedev-detach を使用してホストドライバーからデタッチして実行できます。1 つのグループに含まれるデバイスは、複数のゲスト間で分割したり、ホストとゲストに分割したりすることはできません。PCIe ルートポート、スイッチポート、ブリッジなどの非エンドポイントデバイスは、ホストドライバーから切り離してはならず、エンドポイントの割り当てを干渉しません。
    IOMMU グループ内のデバイスは、virsh nodedev-dumpxml 出力の iommuGroup セクションを使用して判断できます。グループの各メンバーは、別個の "address" フィールドで提供されます。この情報は、次の使用による sysfs にも記載されています。
    $ ls /sys/bus/pci/devices/0000:01:00.0/iommu_group/devices/
    以下のような出力があります。
    0000:01:00.0  0000:01:00.1
    ゲストに 0000.01.00.0 のみを割り当てるには、ゲストを起動する前に未使用のエンドポイントをホストからデタッチする必要があります。
    $ virsh nodedev-detach pci_0000_01_00_1
  3. 必要な設定情報の確認

    設定ファイルに必要な値は、virsh nodedev-dumpxml pci_0000_00_19_0 コマンドの出力を参照してください。
    デバイスの例の値は bus = 0, slot = 25 および function = 0 です。10 進数設定では、以下の 3 つの値を使用します。
    bus='0'
    slot='25'
    function='0'
  4. 設定の詳細の追加

    virsh edit を実行して仮想マシン名を指定し、<devices> セクションにデバイスエントリーを追加します。PCI デバイスをゲスト仮想マシンに割り当てます。以下に例を示します。
    # virsh edit guest1-rhel7-64

    図16.2 PCI デバイスの追加

    
    <devices>
    	[...]
     <hostdev mode='subsystem' type='pci' managed='yes'>
       <source>
          <address domain='0' bus='0' slot='25' function='0'/>
       </source>
     </hostdev>
     [...]
    </devices>
    
    または、virsh attach-device を実行して、仮想マシン名とゲストの XML ファイルを指定します。
    virsh attach-device guest1-rhel7-64 file.xml
    注記
    PCI デバイスには、オプションの読み取り専用メモリー(ROM)モジュール (オプション ROM または拡張 ROM とも呼ばれる)が含まれており、デバイスのファームウェアやブートドライバー(PXE など)を配信することができます。通常、PCI デバイスの割り当てを使用して物理 PCI デバイスを仮想マシンに割り当てる際に、このオプション ROM も仮想化環境で機能します。
    ただし、オプション ROM は不要な場合があり、これにより仮想マシンが起動速度が遅くなったり、デバイスが提供するブート前のドライバーが仮想化と互換性のない可能性があります。これにより、ゲスト OS の起動が失敗する可能性があります。このような場合、Red Hat は、仮想マシンから ROM オプションをマスクさせることを推奨します。これを行うには、以下の手順を実施します。
    1. ホストで、割り当てるデバイスに BAR(拡張 ROM ベースアドレスレジスター)があることを確認します。これには、デバイスの lspci -v コマンドを使用して、以下を含む行の出力を確認します。
      Expansion ROM at
    2. <rom bar='off'/> 要素をゲストの XML 設定の <hostdev> 要素の子として追加します。
      <hostdev mode='subsystem' type='pci' managed='yes'>
        <source>
           <address domain='0' bus='0' slot='25' function='0'/>
        </source>
        <rom bar='off'/>
      </hostdev>
      
  5. 仮想マシンの起動

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

16.1.2. virt-manager を使用した PCI デバイスの割り当て

グラフィカルの virt-manager ツールを使用して、PCI デバイスをゲスト仮想マシンに追加できます。以下の手順では、ギガビットイーサネットコントローラーをゲスト仮想マシンに追加します。

手順16.4 virt-manager でゲスト仮想マシンへの PCI デバイスの割り当て

  1. ハードウェア設定を開く

    ゲスト仮想マシンを開き、ハードウェアの追加 ボタンをクリックして、新しいデバイスを仮想マシンに追加します。

    図16.3 仮想マシンのハードウェア情報ウィンドウ

    トップタスクバーと Overview の左側にあるメニューで選択した情報ボタンのある仮想マシンのハードウェアウィンドウ。
  2. PCI デバイスの選択

    左側のハードウェア一覧から PCI Host Device を選択します。
    未使用の PCI デバイスを選択します。別のゲストから現在使用されている PCI デバイスを選択すると、エラーが発生することに注意してください。この例では、予備のオーディオコントローラーを使用しています。Finish をクリックして設定を完了します。

    図16.4 Add new virtual hardware ウィザード

    左側のメニューペインで PCI Host Device を持つ Add new virtual hardware ウィザードを選択し、右側のメニューペインに選択したホストデバイスの一覧が表示されます。
  3. 新規デバイスの追加

    設定が完了し、ゲスト仮想マシンが PCI デバイスに直接アクセスできるようになりました。

    図16.5 仮想マシンのハードウェア情報ウィンドウ

    左側のメニューペインで選択した上位タスクバーと概要で情報ボタンが選択した仮想マシンのハードウェアウィンドウが表示され、左側のメニューペインの仮想マシンデバイスの一覧に新しい追加した PCI デバイスが表示されます。
注記
デバイスの割り当てに失敗する場合、ホストにアタッチされている同じ IOMMU グループ内に他のエンドポイントが存在する可能性があります。virt-manager を使用してグループ情報を取得する方法はありませんが、virsh コマンドを使用して IOMMU グループの境界を分析できます。また、必要に応じて、squester デバイスを使用します。
IOMMU グループおよび virsh 注記 「virsh を使用した PCI デバイスの割り当て」 を参照してください。

16.1.3. virt-install を使用した PCI デバイスの割り当て

virt-install コマンドを使用してゲストをインストールする場合は、PCI デバイスを割り当てることができます。これには、--host-device パラメーターを使用します。

手順16.5 virt-install で PCI デバイスの仮想マシンへの割り当て

  1. デバイスの特定

    ゲスト仮想マシンへのデバイス割り当てに指定される PCI デバイスを特定します。
    # 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)
    virsh nodedev-list コマンドは、システムに接続されているすべてのデバイスを一覧表示し、文字列とともに各 PCI デバイスを識別します。出力を PCI デバイスのみに制限するには、以下のコマンドを入力します。
    # 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 デバイス番号を記録します。この数字は他のステップで必要になります。
    ドメイン、バス、および機能に関する情報は、virsh nodedev-dumpxml コマンドの出力から確認できます
    # virsh nodedev-dumpxml pci_0000_01_00_0

    図16.6 PCI デバイスファイルのコンテンツ

    
    <device>
      <name>pci_0000_01_00_0</name>
      <parent>pci_0000_00_01_0</parent>
      <driver>
        <name>igb</name>
      </driver>
      <capability type='pci'>
        <domain>0</domain>
        <bus>1</bus>
        <slot>0</slot>
        <function>0</function>
        <product id='0x10c9'>82576 Gigabit Network Connection</product>
        <vendor id='0x8086'>Intel Corporation</vendor>
        <iommuGroup number='7'>
          <address domain='0x0000' bus='0x00' slot='0x19' function='0x0'/>
        </iommuGroup>
      </capability>
    </device>
    
    注記
    IOMMU グループに複数のエンドポイントがあり、それらすべてがゲストに割り当てられていない場合は、ゲストを起動する前に以下のコマンドを実行して、ホストから他のエンドポイントを手動でデタッチする必要があります。
    $ virsh nodedev-detach pci_0000_00_19_1
  2. デバイスの追加

    virsh nodedev コマンドの出力を --host-device パラメーターの値として使用します。
    virt-install \
    --name=guest1-rhel7-64 \
    --disk path=/var/lib/libvirt/images/guest1-rhel7-64.img,size=8 \
    --vcpus=2 --ram=2048 \
    --location=http://example1.com/installation_tree/RHEL7.0-Server-x86_64/os \
    --nonetworks \
    --os-type=linux \
    --os-variant=rhel7
    --host-device=pci_0000_01_00_0
  3. インストールを完了する

    ゲストインストールを完了します。PCI デバイスがゲストに接続されている。

16.1.4. 割り当てられた PCI デバイスのデタッチ

ホストの PCI デバイスがゲストマシンに割り当てられている場合、ホストはデバイスを使用できなくなります。PCI デバイスが管理モードにある場合は (ドメイン XML ファイルの managed='yes' パラメーターを使用して設定)、ゲストマシンに接続してゲスト仮想マシンからデタッチし、必要に応じてホストマシンに再アタッチします。PCI デバイスが管理モードにない場合は、PCI デバイスをゲスト仮想マシンから切断し、virsh または virt-manager で再接続できます。

手順16.6 virsh でゲストから PCI デバイスのデタッチ

  1. デバイスの接続を解除します。

    ゲストの XML ファイルを削除して、以下のコマンドで PCI デバイスをゲストから切断します。
    # virsh detach-device name_of_guest file.xml
  2. ホストへのデバイスの再接続(オプション)

    デバイスが managed モードの場合は、この手順を省略します。デバイスは、自動的にホストに戻ります。
    デバイスが managed モードを使用していない場合は、以下のコマンドを使用して PCI デバイスをホストマシンに再接続します。
    # virsh nodedev-reattach device
    たとえば、pci_0000_01_00_0 デバイスをホストに再アタッチするには、以下のコマンドを実行します。
    # virsh nodedev-reattach pci_0000_01_00_0
    デバイスがホストで利用できるようになりました。

手順16.7 virt-manager を使用した PCI デバイスのゲストからの接続解除

  1. 仮想ハードウェアの詳細画面を開く

    virt-manager で、デバイスが含まれる仮想マシンをダブルクリックします。Show virtual hardware details ボタンを選択して、仮想ハードウェアの一覧を表示します。

    図16.7 仮想ハードウェアの詳細ボタン

    Show virtual hardware details ボタン。
  2. デバイスの選択および削除

    左側パネルの仮想デバイスの一覧より、接続を解除する PCI デバイスを選択します。

    図16.8 デタッチする PCI デバイスの選択

    PCI デバイスの詳細および削除ボタン。
    削除 ボタンをクリックして確定します。デバイスがホストで利用できるようになりました。

16.1.5. PCI ブリッジ

PCI(peripheral Component Interconnects)ブリッジは、ネットワークカード、モデム、サウンドカードなどのデバイスにアタッチするために使用されます。物理対応と同様に、仮想デバイスを PCI Bridge にもアタッチできます。以前は、すべてのゲスト仮想マシンに 31 個の PCI デバイスしか追加できませんでした。31st PCI デバイスが追加されると、PCI ブリッジが 31st スロットに自動的に配置され、追加の PCI デバイスを PCI ブリッジに移動するようになりました。各 PCI ブリッジには 31 スロットが追加されたので、このデバイスはすべてブリッジが可能です。これにより、ゲスト仮想マシンで 900 を超えるデバイスを利用できます。
PCI ブリッジの XML 設定例については、「 ドメイン XML の例」を参照してください。この設定は自動で設定されており、手動で調整することは推奨されません。

16.1.6. PCI デバイスの割り当ての制限

PCI デバイスの割り当て(PCI デバイスを仮想マシンにアタッチ)では、PCI デバイスのデバイス割り当てを有効にするために AMD IOMMU または Intel VT-d サポートを持つホストシステムが必要です。
Red Hat Enterprise Linux 7 では、ゲストデバイスドライバーによる PCI 設定領域へのアクセスが限定されています。この制限により、ドライバーが拡張された PCI 設定領域にあるデバイス機能に依存する可能性があり、設定に失敗することがあります。
Red Hat Enterprise Linux 7 仮想マシンごとに割り当てられたデバイスの合計は 32 に制限されます。これにより、仮想マシンに存在する PCI ブリッジの数や、マルチ機能スロットの作成方法にかかわらず、PCI 機能の合計が 32 合計に変換されます。
デバイスが割り当てられたゲストをホストから完全に分離するには、プラットフォームが割り込みの再マッピングをサポートしている必要があります。このようなサポートがないと、ホストは悪意のあるゲストからの割り込み注入攻撃に対して脆弱となる可能性があります。ゲストが信頼できる環境では、管理者は vfio_iommu_type1 モジュールに allow_unsafe_interrupts オプションを使用して引き続き PCI デバイスの割り当てを許可することを選択できます。これは、.conf ファイル(例: local.conf)を、以下の内容を含む /etc/modprobe.d に追加して永続的に実行できます。
options vfio_iommu_type1 allow_unsafe_interrupts=1
または、sysfs エントリーを使用して動的に実行するか、同じ処理を行います。
# echo 1 > /sys/module/vfio_iommu_type1/parameters/allow_unsafe_interrupts