GPUパススルーで仮想マシンの性能向上

仮想マシンを利用する際、オンボードと追加カードのように2系統のビデオ出力を搭載しているなら、追加カードのGPUをパススルーすれば仮想マシンでも実機に迫る性能でグラフィック機能を利用出来ます。
利用方法は、まず状況を確認し、対応する機能部分をパススルーする設定で行います。

CPUとマザーボードの確認 (IOMMU)

まずは端末で以下のコマンドを実行し、CPUの仮想化支援機能が表示されるか確認します。
Intel (VT-d):

grep --color vmx /proc/cpuinfo

AMD (AMD-Vi):

grep --color svm /proc/cpuinfo

何も出力されない場合は、BIOSで「Intel VT-d」や「AMD IOMMU/SVM」が無効になっている可能性があります。

IOMMUグループの分離状況

オンボード機能だけでもパススルーが利用出来る可能性があります。その場合はまずパススルーしたいGPU(VGAとAudioの2項目)が、他のデバイス(SATAやUSB等)を含まない単独のGroupに割り当てられているか確認します。

for d in /sys/kernel/iommu_groups/*/devices/*; do
  n=${d#*/iommu_groups/*}; n=${n%%/*}
  printf 'IOMMU Group %s ' "$n"
  lspci -nns "${d##*/}"
done

同じGroup内にマザーボードのチップセットなどが含まれていると、そのままではパススルーできません(ACSパッチなどの高度な対策が必要になります)。たとえばAMD機はグループ化されているので厳しいことが多いです。

なお、ミニPCで人気だったIntel Alder Lake-N (N100等) の搭載機は、AMD機と比較してGPUパススルーの成功率が格段に高くなります。この世代のIntel CPUは、従来のパススルーよりも優れた 「SR-IOV (Intel Graphics Virtualization Technology)」 に対応している可能性が高いためです。

通常のパススルーはホストからGPUを完全に奪い、VM専用になりますが、SR-IOVでは1つのGPUを「仮想的な複数のGPU」に分割し、ホスト(Ubuntu)の画面を出したまま、VMでも爆速なGPU支援(動画再生支援含む)を使うことができます。

IOMMUの有効化

パススルーが出来そうなら、grubの設定ファイルを編集します。

sudo nano /etc/default/grub

Intelの場合はGRUB_CMDLINE_LINUX_DEFAULT="… intel_iommu=on iommu=pt"とします。AMDの場合は後半がamd_iommu=on iommu=ptとなります。

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash amd_iommu=on iommu=pt"

編集が終わったらgrubをアップデートし、再起動します。

sudo update-grub
sudo reboot

再起動後の確認

dmesg | grep -e DMAR -e IOMMU

ここでIOMMU enabledと表示されていれば、パススルーの準備が完全に整ったことになります

ホストがGPUを掴んでいる場合

ホストがGPUを掴んで離さない場合は、GPUのPCI IDを確認し、vfioを設定します。
まず次のコマンドでPCI IDを確認します。

lspci -nn

たとえばデバイスIDが下記のように表示されます。
VGA (GPUコア): 1002:164c (03:00.0)
Audio (HDMI音声): 1002:1637 (03:00.1)

続いてvfio.confに記述します。上記の例だと次のようになります。

sudo nano /etc/modprobe.d/vfio.conf
softdep amdgpu pre: vfio-pci
options vfio-pci ids=1002:164c,1002:1637
sudo update-initramfs -u

設定を変更して再起動したら、再度確認します。

sudo dmesg | grep -i iommu

もし設定が正しく反映されていれば、以下のような行が表示されます:
AMD-Vi: IOMMU enabled
pci 0000:00:00.2: Adding to iommu group 0
もしdmesgenabledと出たなら、このコマンドで確認します。

lspci -nnk -s 03:00.0

ここが Kernel driver in use: vfio-pci になっていれば、準備完了です。

仮想マシン側でパススルーしたGPUを追加

仮想マシン側では、対象のデバイスを選択して追加します。
上記の例ですとリストから以下の2つを探してチェックを入れ、「追加」をクリックします。

0000:03:00.0 Lucienne [1002:164c] (GPU本体)0000:03:00.1 Renoir/Cezanne HDMI/DP Audio Controller [1002:1637] (音声)

GPUパススルー後の仮想マシン(VM)内、あるいはホストOS側でハードウェア動画再生支援(ハードウェアアクセラレーション)が有効かどうかを確認するには、以下の方法が最も確実です。

sudo apt update && sudo apt install vainfo
vainfo

VAProfileH264Main : VAEntrypointVLD のように、コーデック名と VAEntrypointVLD(デコード支援)が表示されれば有効です。もしエラーが出る場合は、ドライバが正しく当たっていないか、パススルーに失敗しています。

Windowsの場合はYouTubeの4K動画などをブラウザで再生し、タスクマネージャのGPU関連でグラフが動いていれば、GPUがデコード処理を肩代わりしています。