====== Proxmox VE 6.3でPCIパススルーあれこれ ======
===== 試した環境 =====
* Proxmox VE 6.3-3
* ZFSルート環境
* Supermicro X10DRi
* Xeon E5-2673v3×2
===== PCIパススルーの有効化 =====
==== IOMMUの有効化 ====
本ページでもPCIパススルーのあれこれを長々と書いているが、PCIパススルー有効化の肝はIOMMUの有効化である(もちろんVT-dを有効化しとくといった前提はあるけど)
カーネルコマンドライン''/etc/kernel/cmdline''に''intel_iommu=on iommu=pt''を追加し、''pve-efiboot-tool refresh''を実行する。
# cat /etc/kernel/cmdline
root=ZFS=rpool/ROOT/pve-1 boot=zfs intel_iommu=on iommu=pt
# pve-efiboot-tool refresh
unning hook script 'pve-auto-removal'..
Running hook script 'zz-pve-efiboot'..
Re-executing '/etc/kernel/postinst.d/zz-pve-efiboot' in new private mount namespace..
Copying and configuring kernels on /dev/disk/by-uuid/D067-47DC
Copying kernel and creating boot-entry for 5.4.78-2-pve
なお、AMDプラットフォームの場合は''intel_iommu''の代わりに''amd_iommu''を使う。
また、ZFSルートシステム以外では''/etc/default/grub''の''GRUB_CMDLINE_LINUX_DEFAULT''に上記のパラメータを追加し、''update-grub''を実行する。
==== Interrupt Remappingの確認 ====
システムがIRQリマッピングに対応してるか確認する。
起動メッセージ内に''remapping enabled''的なログがあればOK。
# dmesg | grep remapping
[ 1.736785] DMAR-IR: Queued invalidation will be enabled to support x2apic and Intr-remapping.
[ 1.737508] DMAR-IR: Enabled IRQ remapping in x2apic mode
ない場合は''allow_unsafe_interrupts''を設定すればいいらしい。
# echo "options vfio_iommu_type1 allow_unsafe_interrupts=1" > /etc/modprobe.d/vfio.conf
==== 有効化の確認 ====
一度システムを再起動し、起動メッセージ内に''IOMMU enabled''があることを確認する。
# dmesg | grep -e DMAR -e IOMMU -e AMD-Vi
[ 0.014749] ACPI: DMAR 0x0000000079D90148 000128 (v01 ALASKA A M I 00000001 INTL 20091013)
[ 0.950958] DMAR: IOMMU enabled
(中略)
[ 1.734769] DMAR-IR: Queued invalidation will be enabled to support x2apic and Intr-remapping.
[ 1.735497] DMAR-IR: Enabled IRQ remapping in x2apic mode
[ 3.273462] DMAR: dmar0: Using Queued invalidation
[ 3.273479] DMAR: dmar1: Using Queued invalidation
[ 3.295150] DMAR: Intel(R) Virtualization Technology for Directed I/O
[ 3.421919] ehci-pci 0000:00:1a.0: DMAR: 32bit DMA uses non-identity mapping
[ 3.539671] ehci-pci 0000:00:1d.0: DMAR: 32bit DMA uses non-identity mapping
===== VFIO =====
VFIOはユーザースペースからデバイスを操作するためのフレームワークである。PCIパススルーにおいては、ホストからデバイスを分離するのに用いられる。
==== モジュールの読み込み ====
''/etc/modules''にVFIOモジュールを記述する。
vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd
==== initramfsの再構築と確認 ====
カーネルモジュール関連の変更を行った際は、忘れずにinitramfsを再構築し、マシンを再起動する。
# update-initramfs -u -k all
# reboot
再起動後、lsmodで関連モジュールが出てくればOK
# lsmod | grep vfio
==== デバイスの指定 ====
ホストから分離するPCIデバイスをベンダーIDとデバイスIDのペアで指定する。
パススルーデバイスへのVFIOの適用は、仮想マシンの起動時に自動的に行われるため、基本的には対象デバイスを明示する必要はないようだ。一方で、ホスト側のドライバが一度でも適用されると具合の悪いデバイスでは、あらかじめVFIOが適用されるよう明示する必要があるっぽい。(ぶっちゃけGPUのことなんですけどね。少しずつ状況は変わっているようだけど。)
=== 対象デバイスの確認 ===
ベンダIDとデバイスIDは''lspci''コマンドで確認する。
# lspci -nn | grep SATA
00:11.4 SATA controller [0106]: Intel Corporation C610/X99 series chipset sSATA Controller [AHCI mode] [8086:8d62] (rev 05)
00:1f.2 SATA controller [0106]: Intel Corporation C610/X99 series chipset 6-Port SATA Controller [AHCI mode] [8086:8d02] (rev 05)
行末の 8086:8d62 というのがそれ。
■confファイルに記述する場合 \\
/etc/modprobe.d/vfio.confに以下の行を追加。複数のデバイスを指定する場合はコンマでつなぐ。
options vfio-pci ids=ベンダID:デバイスID
■カーネルコマンドラインに記述する場合 \\
/etc/kernel/cmdlineに''vfio-pci.ids=vvvv:dddd''の一節を追加する。
root=ZFS=rpool/ROOT/pve-1 boot=zfs intel_iommu=on iommu=pt vfio-pci.ids=vvvv:dddd
==== IOMMUデバイスグループ ====
PCIパススルーしたいデバイスのIOMMUグループを確認する。
パススルーはIOMMUグループ単位で行われるため、対象デバイスと同一グループの不必要なデバイスも一緒にパススルーされてしまう。
{{ virtualization:proxmox_ve_6_2_the_same_iommu_group.png |}}
シェルから確認する場合は以下のような感じで。
# find /sys/kernel/iommu_groups/ -type l | sort
...
/sys/kernel/iommu_groups/40/devices/0000:00:1d.0
/sys/kernel/iommu_groups/41/devices/0000:00:1f.0
/sys/kernel/iommu_groups/41/devices/0000:00:1f.2
/sys/kernel/iommu_groups/41/devices/0000:00:1f.3
/sys/kernel/iommu_groups/42/devices/0000:01:00.0
...
IOMMUグループの変更はデバイスを取りつけるPCIeスロットを変えるのが基本だが、どうにもならない時はACSオーバーライドを使う。
カーネルの起動パラメータに''pcie_acs_override=param''を追加して再起動。
|id:vvvv:dddd| |
|downstream| |
|multifunction| |
上手くいけば下図のようにIOMMUグループが分離される。でも、必ずしも分離できるとは限らないので、その時は諦めるしかない。
{{ virtualization:proxmox_ve_6_2_separate_iommu_group.png |}}
===== 雑多なメモ =====
* PVE 6.2ではVFIOがカーネルに内蔵されてたようで、/etc/modulesをいじらなくても使えてた気がする。
* modulesに書いても書かなくても、lsmodにvfio関連モジュールは出てこなかった。
* このせいで/etc/modprobe.dのconfファイルでのデバイス指定が効かず、カーネルコマンドラインで指定しないとダメだった記憶。
===== 参考サイト =====
* [[https://pve.proxmox.com/pve-docs/pve-admin-guide.html|Proxmox VE Administration Guide]]
* [[https://pve.proxmox.com/pve-docs/pve-admin-guide.html#qm_pci_passthrough|10.9. PCI(e) Passthrough]]
* [[https://pve.proxmox.com/pve-docs/pve-admin-guide.html#sysboot|3.11. Host Bootloader]]
* [[https://wiki.archlinux.jp/index.php/OVMF_%E3%81%AB%E3%82%88%E3%82%8B_PCI_%E3%83%91%E3%82%B9%E3%82%B9%E3%83%AB%E3%83%BC|OVMF による PCI パススルー - ArchWiki]]
* [[http://www.30boys.tokyo/kvmwiki/|KVM-wiki TOP - PukiWiki]]