Ubuntu 22.04 の KVM / QEMU で PCI パススルーを使う場合、中心になるのは IOMMU、IOMMU グループ、VFIO、libvirt の hostdev です。GPU や USB コントローラーをゲストへ渡す構成は便利ですが、ホストからデバイスを切り離すため、戻れる管理経路を確保してから進めます。
この記事は、Ubuntu 22.04 の既存環境で KVM PCI パススルー設定を読み直すための記事です。新規構築では Ubuntu 26.04 側の記事を優先しつつ、22.04 環境の設定確認や古い構築記録の読み替えに使ってください。
- PCI パススルーでホストとゲストのどちらがデバイスを持つか
- IOMMU と IOMMU グループの確認
- 対象デバイスを
vfio-pciに割り当てる流れ - libvirt で PCI Host Device として追加する考え方
- 画面喪失や起動失敗を避けるための注意点
書籍
作って理解する仮想化技術 – ハイパーバイザを実装しながら仕組みを学ぶ
KVM、QEMU、仮想デバイス、I/O 仮想化、ハイパーバイザの仕組みを低レイヤから理解したい場合の参考書籍です。価格や在庫はリンク先で確認してください。
Amazon で見るこのリンクは Amazon アソシエイトリンクです。
PCI パススルーで何をしているのか
KVM の PCI パススルーでは、ホスト OS が通常のドライバで使っている PCI デバイスを切り離し、vfio-pci に束ねてから、QEMU / libvirt 経由でゲスト OS に渡します。
| 要素 | 役割 |
|---|---|
| IOMMU | デバイスの DMA を隔離し、ゲストに渡すデバイスがホストの任意メモリへ触れないようにする |
| IOMMU グループ | 安全に分離できる最小単位 |
VFIO / vfio-pci | PCI デバイスをユーザー空間の VM へ渡す Linux 側の仕組み |
| libvirt / virt-manager | VM 定義に PCI Host Device として対象デバイスを追加する管理層 |
重要なのは、PCI パススルーはデバイス単体を気軽に貸す機能ではなく、IOMMU で隔離できる単位をゲストへ所有させる構成だという点です。
作業前の前提を確認する
まず、CPU と BIOS / UEFI が仮想化支援と IOMMU を有効にできることを確認します。Intel では VT-x / VT-d、AMD では AMD-V / AMD-Vi が関係します。
egrep -wo 'vmx|svm' /proc/cpuinfo | sort -u
sudo apt update
sudo apt install -y cpu-checker
kvm-okホストで使っている唯一の GPU をいきなりゲストへ渡すと、ホスト側の画面を失うことがあります。ホスト用 GPU とゲスト用 GPU を分ける、SSH でホストへ戻れるようにする、GRUB 設定を戻せるようにする、という準備を先に行います。
KVM と virt-manager をインストールする
Ubuntu 22.04 に KVM / libvirt / virt-manager をインストールします。
sudo apt update
sudo apt install -y qemu-kvm libvirt-daemon-system libvirt-clients virtinst virt-manager ovmf
sudo usermod -aG libvirt "$USER"
id "$USER"libvirt グループ追加の反映には、ログアウトまたは再ログインが必要です。
IOMMU を有効化する
BIOS / UEFI で VT-d または AMD-Vi を有効化したうえで、Linux カーネルの起動パラメータに IOMMU の指定を追加します。既存のパラメータがある場合は消さずに追記します。
GRUB_CMDLINE_LINUX="intel_iommu=on iommu=pt"GRUB_CMDLINE_LINUX="amd_iommu=on iommu=pt"変更前にバックアップを取ってから、GRUB を更新して再起動します。
sudo cp /etc/default/grub /etc/default/grub.bak.$(date +%Y%m%d%H%M%S)
sudo update-grub
sudo rebootIOMMU の有効化を確認する
再起動後、カーネルログで IOMMU が有効になっているか確認します。Intel 環境では DMAR、AMD 環境では AMD-Vi が出ることがあります。
sudo dmesg | grep -Ei 'DMAR|IOMMU|AMD-Vi'
find /sys/kernel/iommu_groups/ -mindepth 1 -maxdepth 1 -type d | sort -VIOMMU グループを確認する
対象の GPU や USB コントローラーが、どの IOMMU グループに属しているかを確認します。PCI パススルーでは、この確認が非常に重要です。
for group in /sys/kernel/iommu_groups/*; do
echo "IOMMU group ${group##*/}"
for device in "$group"/devices/*; do
lspci -nn -s "${device##*/}"
done
done同じ IOMMU グループに複数のデバイスがある場合、そのグループ全体が分離単位になります。GPU 本体と HDMI audio function が同じグループにいる程度なら一緒に渡せますが、ホストで使う SATA、NIC、USB controller などが同じグループに混ざる場合は注意が必要です。
対象デバイスの ID を確認する
パススルーしたいデバイスの vendor ID と device ID を確認します。
lspci -nnkGPU と GPU の audio function を渡す場合、次のような ID を控えます。この例では、10de:1f82 と 10de:10fa が vfio-pci に渡す ID です。
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation TU117 [10de:1f82]
01:00.1 Audio device [0403]: NVIDIA Corporation Device [10de:10fa]vfio-pci に割り当てる
対象デバイスをホスト側の通常ドライバではなく vfio-pci で掴むように設定します。ID は実際の環境に合わせて変更します。
sudo tee /etc/modules-load.d/vfio.conf >/dev/null <<'EOF'
vfio
vfio_iommu_type1
vfio_pci
EOF
sudo tee /etc/modprobe.d/vfio.conf >/dev/null <<'EOF'
options vfio-pci ids=10de:1f82,10de:10fa
EOF
sudo update-initramfs -u
sudo reboot再起動後、対象デバイスの Kernel driver が vfio-pci になっているか確認します。
lspci -nnk -s 01:00.0
lspci -nnk -s 01:00.1VM に PCI デバイスを追加する
virt-manager で対象 VM を開き、詳細画面から Add Hardware を選び、PCI Host Device として対象デバイスを追加します。GPU を渡す場合は、GPU 本体だけでなく、同じカード上の audio function も一緒に渡すことが多いです。
libvirt の XML では、PCI デバイスは hostdev として表現されます。managed='yes' の場合、libvirt がゲスト起動時にホストからデバイスを切り離し、ゲスト停止後に戻す動作を担当します。
<hostdev mode='subsystem' type='pci' managed='yes'>
<source>
<address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
</source>
</hostdev>Windows ゲストで確認する
Windows ゲストを起動し、デバイスマネージャーで GPU や USB コントローラーが認識されているか確認します。GPU の場合は、ドライバを入れるまでは基本ディスプレイアダプターとして見えることがあります。
- デバイスマネージャーで対象デバイスが見えるか
- ドライバを入れた後にエラーコードが出ていないか
- GPU 出力に接続したディスプレイへ画面が出るか
- USB コントローラー配下の機器がゲスト側で認識されるか
よくある失敗ポイント
| 症状 | 確認すること |
|---|---|
| IOMMU グループが出ない | BIOS / UEFI の VT-d / AMD-Vi、GRUB パラメータ、再起動の有無 |
vfio-pci で掴めない | vendor ID / device ID、initramfs 更新、既存ドライバが先に掴んでいないか |
| ホスト画面が消える | ホストが使用中の GPU を vfio-pci に渡していないか |
| VM が起動しない | 同じ IOMMU グループ内の必要デバイスをまとめて渡しているか |
| ゲスト再起動後に GPU が戻らない | GPU の reset 問題、ホスト再起動の必要性、対象 GPU の相性 |
| USB 機器が不安定 | USB デバイス単体ではなく USB コントローラー単位で渡しているか |
まとめ
Ubuntu 22.04 の KVM で PCI パススルーを使う場合、中心になるのは IOMMU、IOMMU グループ、VFIO、libvirt の hostdev です。成功すると Windows ゲストから GPU や USB コントローラーを直接扱えますが、ホストからデバイスを切り離す構成であることを忘れないようにします。
22.04 の既存環境を見直すときは、IOMMU グループ、対象デバイス ID、vfio-pci の割り当て、ホストへ戻る管理経路を分けて確認します。手順通りに進めるだけでなく、失敗時に画面や入力を失わない構成にしてから作業します。

