ProxmoxでGPUをVMにパススルーする:IOMMU確認・VFIO割り当て・Error 43の回避

Photo: Nana Dua / Pexels
先に結論です。Proxmox で GPU を VM に渡す作業は、BIOS で VT-d(AMD は IOMMU)を有効にする → IOMMU グループを確認する → GPU をホストのドライバーではなく vfio-pci に割り当てる → VM を q35・OVMF(UEFI)で作って GPU を追加する、の4段階です。Windows で Error 43 が出たら、ドライバーの版・ホストの画面出力・vBIOS の3点を順に疑います。
なお、ミニPCの多くは PCIe の拡張スロットがないため、この記事はグラフィックボードを挿せるデスクトップ機を前提にしています。Jellyfin のトランスコードだけが目的なら、CPU 内蔵 GPU を LXC に渡すほうが手軽です。
事前確認:BIOS と IOMMU グループ
BIOS で Intel は VT-d、AMD は IOMMU(AMD-Vi)を有効にします。カーネル側は、Intel CPU でもカーネル 6.8 以降は IOMMU が既定で有効とされており、現行の Proxmox VE 9 系なら intel_iommu=on を足す必要は基本的にありません(AMD はもともと既定で有効です)。
有効になっているかは次のコマンドで確かめます。
dmesg | grep -e DMAR -e IOMMU -e AMD-Vi
次に、GPU が他の機器と同じ IOMMU グループに入っていないかを見ます。パススルーはグループ単位で行われるため、GPU と同じグループに SATA コントローラーなどが入っていると、それもまとめてホストから切り離されてしまいます。
pvesh get /nodes/$(hostname)/hardware/pci --pci-class-blacklist ""
表の iommugroup 列で、GPU の映像と HDMI 音声だけが同じ番号になっていれば理想的です。他の機器と混ざっている場合は、マザーボードの別のスロットに挿し替えると分かれることがあります。
GPU を vfio-pci に割り当てる
ホストの Proxmox が GPU を使ってしまわないように、起動時から vfio-pci というパススルー用のドライバーに割り当てます。まず VFIO のモジュールを読み込む設定です。
printf "vfio\nvfio_iommu_type1\nvfio_pci\n" > /etc/modules-load.d/vfio.conf
続いて GPU の ID を調べます。
lspci -nn | grep -i nvidia
01:00.0 VGA compatible controller ... [10de:xxxx] と 01:00.1 Audio device ... [10de:yyyy] のように、映像と音声の2つが出るのが一般的です。末尾の [ベンダー:デバイス] を両方控えて、/etc/modprobe.d/vfio.conf に書きます。
options vfio-pci ids=10de:xxxx,10de:yyyy
softdep nouveau pre: vfio-pci
softdep snd_hda_intel pre: vfio-pci
softdep の行は、ホスト側のドライバー(NVIDIA 用の nouveau と HDMI 音声用の snd_hda_intel)より先に vfio-pci を読み込ませる指定です。AMD の GPU なら nouveau を amdgpu に読み替えます。反映して再起動し、割り当てを確認します。
update-initramfs -u -k all
reboot
lspci -nnk -s 01:00
Kernel driver in use: vfio-pci と表示されれば成功です。
VM 側の設定:q35・OVMF・All Functions
VM は作成時に次のように設定します。
- マシン:q35(PCI-Express として渡すのに必要)
- BIOS:OVMF(UEFI)。EFI ディスクも追加する
- CPU の種別:host
作成後、VM の「ハードウェア」→「追加」→「PCI デバイス」で GPU(01:00)を選び、「All Functions」(映像と音声をまとめて渡す)と、詳細設定の「PCI-Express」にチェックを入れます。この GPU を VM の画面出力にするなら「Primary GPU」にもチェックします。
注意点として、GPU が出す画面は Proxmox の Web 画面のコンソール(noVNC)では見られません。公式 wiki でも、モニターをつなぐかリモートデスクトップで見るよう案内されています。私は、GPU を追加する前に Windows 側でリモートデスクトップを有効にしておく順番をおすすめします。モニターをつながずに使うなら、HDMI ダミープラグ を挿しておくと、GPU がモニター接続ありの状態として動くとされています。
Windows で Error 43 が出たときに見る3点
デバイスマネージャーで GPU に「コード 43」が出る場合、次の順で確認します。
- ドライバーの版:以前の NVIDIA ドライバーは、VM 上で動いていることを検出すると Error 43 を出していました。NVIDIA は R465 以降のドライバーで GeForce の VM へのパススルーをサポート(ベータ)としているため、まずは最新ドライバーを入れ直します。古いドライバーしか使えないカードでは、VM の設定ファイル(
/etc/pve/qemu-server/<VMID>.conf)の cpu 行をcpu: host,hidden=1にして、KVM であることを隠す方法が知られています - ホストが GPU の画面出力を掴んでいないか:ホストの起動画面に使っている GPU を渡すと、ホスト側の画面出力の機能が GPU のメモリ領域を確保したままになることがあります。
dmesg | grep -i "can't reserve"で BAR の行が出ていればこの状態です。カーネルの起動オプションにinitcall_blacklist=sysfb_initを足すと解消した事例が、Proxmox のフォーラムで多く報告されています。GRUB で起動している場合は/etc/default/grubのGRUB_CMDLINE_LINUX_DEFAULTに書いてupdate-grub、ZFS を UEFI で入れた systemd-boot の環境では/etc/kernel/cmdlineに書いてproxmox-boot-tool refreshを実行します - vBIOS(GPU の ROM):ホストの起動時に初期化された GPU は、VM から ROM を正しく読めないことがあるとされています。メーカー配布のものや別の PC で吸い出した vBIOS ファイルを
/usr/share/kvm/に置き、PCI デバイスの設定にromfile=ファイル名を指定すると改善する場合があります
2と3をまとめて避ける方法として、ホストの画面出力は CPU 内蔵 GPU に任せ、渡したい GPU を「起動に使わない GPU」にする構成もあります。BIOS で起動時の画面出力先を内蔵 GPU に変えられるかを確認してみてください。
まとめ
- BIOS で VT-d / IOMMU を有効にし、
dmesgで IOMMU を、pveshで IOMMU グループを確認する /etc/modprobe.d/vfio.confに GPU の ID を書き、Kernel driver in use: vfio-pciになるまで確かめる- VM は q35・OVMF で作り、「All Functions」「PCI-Express」を付けて GPU を追加する
- Error 43 は、ドライバーの版・ホストの画面出力(
initcall_blacklist=sysfb_init)・vBIOS の順に疑う
GPU パススルーはつまずく箇所が多い作業ですが、どの段階にも確認用のコマンドがあります。1段階ずつ結果を確かめてから次へ進むのが、結局いちばんの近道です。
運営者が作った Excel テンプレートを BOOTH で配布しています。IT 資産管理台帳(無料 Lite 版あり) / IT 資格の学習管理シート


