KVM: GPU Passthrough (1)
前回に引き続きopenSUSE tumbleweed/cockpitな環境でKVM環境を整えていく。当面の目標はGPU Passthroughを行うことにある。
過去の自分のメモを見るととりあえずよく使うパッケージをインストールしている。既にcockpitでVM作れるのを確認しているのでKVM関連のパッケージはインストール不要かもしれないが一応入れて置く。
# 今回環境では未インストールだった(無くても動いているようだが)
# qemu-kvm libvirt
# 今回環境ではインストール済みだった
# ovmf virt-manager
# PassthroughやKVMには関係ないけど情報取得で使うのでインストールしておく
# sysstat dstat gparted
とりあえず、一通りインストールして進めることにする。virt-managerは何故か再インストールされた。
# zypper update
# zypper dup
# zypper install ovmf virt-manager
# zypper install sysstat dstat gparted
# zypper install qemu-kvm libvirt
次はBoot Loaderを編集する。yastなら[yast]->[System]->[Boot Loader] ->[Kernel Parameters]。yast使わないなら/etc/default/grubを編集後にgrub2-mkconfigで良いはず。ただ、openSUSEはyastにIFが用意されているのでyast経由で設定変更する方が良いだろう。
# diff /etc/default/grub grub_20210214.bkup
11c11
< GRUB_CMDLINE_LINUX_DEFAULT="splash=silent quiet kvm.ignore_msrs=1 intel_iommu=on iommu=pt mitigations=auto"
---
> GRUB_CMDLINE_LINUX_DEFAULT="splash=silent quiet mitigations=auto"
# grub2-mkconfig -o /boot/grub2/grub.cfg
この段階で再起動を行い、変更後のKernel Parameterで起動させる。
Arch Wikiにあるスクリプトを実行してIOMMUの確認をする。
# cat IOMMU_Mapping.sh
#!/bin/bash
shopt -s nullglob
for d in /sys/kernel/iommu_groups/*/devices/*; do
n=${d#*/iommu_groups/*}; n=${n%%/*}
printf 'IOMMU Group %s ' "$n"
lspci -nns "${d##*/}"
done;
IOMMU Group 1 01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP107 [GeForce GTX 1050 Ti] [10de:1c82] (rev a1)
IOMMU Group 1 01:00.1 Audio device [0403]: NVIDIA Corporation GP107GL High Definition Audio Controller [10de:0fb9] (rev a1)
今回はGPU (GTX 1050 Ti)のPassthroughを行う。Intel CPUなのでBIOS設定を行いinternal GPU (iGPU)を使うように設定している。本番期のryzen threadripperと違ってintel cpuは楽でよい。iGPU有りでメニーコアでって一般には需要無いのでdiscreate(dGPU)が必須なthreadripperの仕様も理解するが。
GTX 1050 Ti はvfio-pciにバインドさせる。vfio-pciが先にロードされてGPUをバインドするように/etc/sysconfig/kernelに設定を記載する。
# echo "INITRD_MODULES=\"pci_stub vfio vfio_iommu_type1 vfio_pci vfio_virqfd kvm kvm_intel\"" >> /etc/sysconfig/kernel
念のためGPU driverをblacklistに入れておく。おそらくこの設定は不要である。私の場合はホストでAMD系のGPU、ゲストでnVidia系のGPUと住み分けているので、nouveauは要らない。
# echo -e "blacklist nouveau" >> /etc/modprobe.d/99-local.conf
vfio-pciでバインドするデバイスを指定する。基本的にはグループ単位でバインドすることになる。今回はGTX 1050 Tiにしているが、USBコントローラなどもPassthrough可能。
# echo 'vfio-pci' > /etc/modules-load.d/vfio-pci.conf
# echo "options vfio-pci ids=10de:1c82,10de:0fb9" >> /etc/modprobe.d/99-local.conf
設定作ったらinitrdを作成して再起動する。
# mkinitrd
# reboot
再起動後はvfioが目的のGPUをバインドできているかを確認する。
# dmesg | grep -i vfio
[ 1.967824] VFIO - User Level meta-driver version: 0.3
[ 1.975814] vfio-pci 0000:01:00.0: vgaarb: changed VGA decodes: olddecodes=io+mem,decodes=io+mem:owns=none
[ 1.996153] vfio_pci: add [10de:1c82[ffffffff:ffffffff]] class 0x000000/00000000
[ 2.016129] vfio_pci: add [10de:0fb9[ffffffff:ffffffff]] class 0x000000/00000000
[ 3.165316] vfio-pci 0000:01:00.0: vgaarb: changed VGA decodes: olddecodes=io+mem,decodes=io+mem:owns=none
次回はGTX 1050 Tiをゲストに渡して動作するかを確認する。例によってWindowsで動くかが心配である。