やりたいこと
libvirt で仮想マシンを立てているが、GPU を使いたい
対象
- debian 12
- CPU: intel 第5世代~第10世代
- libvirt で qemu 環境を構築したい
- 複数の VM で GPU を切り替えたい
- VM が secure boot に対応していること
- 注意: libvirt 上から スナップショットを取れなくなります
- virtual machine - Is there a way to share a GPU with a guest VM in the same way we can share a CPU using VT-x/AMD-V? - Super User
- 既存の VM が BIOS 起動の場合は、 gpt ディスクへ変換して XML を触らないと起動しなくなります(高度)
- ↑再インストールの方が楽です
- kernel が古いと gvt が
guest page write error
となる可能性がある- Windows 10 VM running BlueIris has igfx driver crash every few days, GVT-g, GVT-d, DMAR errors : VFIO
I had problems with kernel versions from 5.12 to 6.2, VMs would always crash
とのことなので、最新の kernelを使いましょう(未検証)
- この現象が発生すると qemu が defenct になって kill できない(親が init なのでもっと kill できない)
- Windows 10 VM running BlueIris has igfx driver crash every few days, GVT-g, GVT-d, DMAR errors : VFIO
インストール
0. KVM の インストールと設定
既にKVM環境を構築済みの場合はこの手順は不要です。
sudo apt install libvirt-daemon-system qemu-system
リモートからSSHで接続して virt-manager を設定できるようにする。
$ sudo vi /etc/libvirt/libvirtd.conf # Listen for unencrypted TCP connections on the public TCP/IP port. # ... # This is disabled by default, uncomment this to enable it. listen_tcp = 1 # Override the port for accepting insecure TCP connections # This can be a port number, or service name # # This setting is not required or honoured if using systemd socket # activation. # tcp_port = "16509"
あとは libvirt をリロードするだけ。
$ sudo systemctl reload libvirtd
Windows マシンで、 WSL2 が入っていたら、 virt-manager
を使えるので、GUIで簡単に制御できる。
# WSL上で実行してください(debian系) apt install virt-manager # SSHキーを転送 ssh-keygen -t rsa -b 4096 ssh-copy-id example-username@example-hostname # ログインできることを確認 ssh example-username@example-hostname # virt-manager で接続する virt-manager -c example-username@example-hostname
virt-manager でGUIへ接続する場合は、 Display を VNC server
と設定しないと、接続できません。(TLSを設定すればできるのですが、そこまでやっていません)
LINUX Kernel の設定
1. 環境確認
QEMUのバージョン確認(2.12以上)
$ qemu-system-x86_64 --version QEMU emulator version 7.2.4 (Debian 1:7.2+dfsg-7+deb12u1) Copyright (c) 2003-2022 Fabrice Bellard and the QEMU Project developers $ apt info qemu-system Package: qemu-system Version: 1:7.2+dfsg-7+deb12u1 Priority: optional Section: otherosfs Source: qemu ....
qemu が 2.12以上ならOK(最近のlinux ならほぼクリアしている)。
CPUの状態確認。
$ cat /proc/cpuinfo | grep model model : 94 model name : Intel(R) Core(TM) i3-6100 CPU @ 3.70GHz
Intel 系でかつ、第5世代~第10世代であること。
2. kernel パラメータの調整 (IOMMU を有効化)
i915.enable_gvt=1 intel_iommu=on
をパラメータに与える。
$ sudo vi /etc/default/grub # GRUB_CMDLINE_LINUX="" GRUB_CMDLINE_LINUX="i915.enable_gvt=1 i915.enable_guc=0 intel_iommu=on"
CPU が第10世代~第11世代の場合は次の資料で設定を確認して、必要に応じてオプションを追加すること。 wiki.archlinux.org
参考: オプションの種類を確認する方法
$ sudo modinfo i915 | grep -P "enable_gvt|enable_guc" parm: enable_guc:Enable GuC load for GuC submission and/or HuC load. Required functionality can be selected using bitmask values. (-1=auto [default], 0=disable, 1=GuC submission, 2=HuC load) (int) parm: enable_gvt:Enable support for Intel GVT-g graphics virtualization host support(default:false) (bool)
3. kernel モジュールのロード設定
kvmgt, vfio-iommu-type1, mdev を有効にする。
$ sudo vi /etc/modules-load.d/kvmgt.conf
# Load kvmgt, vfio-iommu-type1 and mdev
kvmgt
gvt を使っている時に出てくるエラーを無視する設定を行う。
$sudo vi /etc/modprobe.d/kvm.conf options kvm ignore_msrs=Y report_ignored_msrs=N
4. grub へ反映
grub の設定を行う。
※事前に /boot/grub/grub.cfg
のバックアップを取得したほうが良いかも
$ sudo update-grub Generating grub configuration file ... Found linux image: /boot/vmlinuz-6.1.0-12-amd64 Found initrd image: /boot/initrd.img-6.1.0-12-amd64 Found linux image: /boot/vmlinuz-6.1.0-10-amd64 Found initrd image: /boot/initrd.img-6.1.0-10-amd64 Warning: os-prober will not be executed to detect other bootable partitions. Systems on them will not be added to the GRUB boot configuration. Check GRUB_DISABLE_OS_PROBER documentation entry. done
5. 再起動
再起動して、grub を反映する。
KVM の設定
6. KVM の hook 設定
必要なツールをインストール
# libxml2-utils は xmllint のため、 uuid-runtime は uuidgen コマンドを使うため
$ apt install libxml2-utils uuid-runtime
libvirtd 用の hook を設定する。
$ sudo vi /etc/libvirt/hooks/qemu #!/bin/sh GVT_PCI="0000:00:02.0" MDEV_TYPE=i915-GVTg_V5_4 GVT_GUID=`cat "/etc/libvirt/qemu/$1.xml" | xmllint --xpath 'string(/domain/devices/hostdev[@type="mdev"][@mode="subsystem"][@display][@model="vfio-pci"]/source/address/@uuid)' -` # echo "$1 $2 $3 $GVT_GUID" >> /tmp/libvirt_gvthook if [ $# -ge 3 ] && [ -n "$GVT_GUID" ]; then # echo gvt_ok >> /tmp/libvirt_gvthook if [ "$2" = "prepare" ] && [ "$3" = "begin" ]; then echo "$GVT_GUID" > "/sys/bus/pci/devices/$GVT_PCI/mdev_supported_types/$MDEV_TYPE/create" elif [ "$2" = "release" ] && [ "$3" = "end" ]; then echo 1 > "/sys/bus/pci/devices/$GVT_PCI/$GVT_GUID/remove" fi fi
参考: 上記コードは以下を参考に作成しました。 wiki.archlinux.org
スティッキービットを設定して、root / root で実行されるようにする
# 念のため権限を設定 $ sudo chown root:root /etc/libvirt/hooks/qemu # ユーザー・グループの権限で実行されるように設定 $ sudo chmod ug+s /etc/libvirt/hooks/qemu # その他ユーザーに実行権限を付与 $ sudo chmod o+x /etc/libvirt/hooks/qemu # 不用意に書き込み権を与えない $ sudo chmod go-w /etc/libvirt/hooks/qemu # 権限チェック $ ls -l /etc/libvirt/hooks/qemu -rwSr-Sr-x 1 root root 754 Sep 23 18:03 /etc/libvirt/hooks/qemu
VM の設定と起動
7. UEFI 起動を可能にする
ファームを適用する。
$ sudo apt install ovmf # 設定を更新 $ sudo systemctl reload libvirtd
8. 対象の VM を設定する
次の設定で VM を設定する(必須)。
Archtecture: x86_64 Chipset: Q35 Firmware: UEFI x86_64: /usr/share/OVMF/OVMF_CODE_4M.ms.fd
<os> <type arch="x86_64" machine="pc-q35-7.2">hvm</type> <loader readonly="yes" type="pflash">/usr/share/OVMF/OVMF_CODE_4M.ms.fd</loader> <nvram>/var/lib/libvirt/qemu/nvram/{VMの名前}_VARS.fd</nvram> <boot dev="hd"/> </os>
注意: 起動対象の HDD(イメージ) は gpt でセキュアブートに対応していないといけません。 セキュアブートしていない場合は、GPUを一時的に認識しますが、使えない状態になります。(デバイスマネージャで警告状態となります)
9. GPU を VM に設定する
virsh で接続して、手動でXMLを追加する。
$ uuidgen
875cd399-1c1b-47f0-8d7b-9f64023c1f56
$ virsh -c qemu:///system edit win10
以下の XML に追加する。
<hostdev mode="subsystem" type="mdev" managed="no" model="vfio-pci" display="off"> <source> <address uuid="{uuidgenで生成した値をここに設定する}"/> </source> <alias name="hostdev0"/> <address type="pci" domain="0x0000" bus="0x00" slot="0x07" function="0x0"/> </hostdev>
10. 対象のVMを起動する
正常に起動したら、Intel HD Graphics がデバイスドライバから参照できます。 また、タスクマネージャにGPUの項目が出れば、成功です。
なお、GPUメモリの関係で1台しか割り当たらないことがあります。
参考文献
- GVT 関連
- Intel GVT-g - ArchWiki
- [ANNOUNCE][RFC] KVMGT - the implementation of Intel GVT-g(full GPU virtualization) for KVM gvt-g アナウンスメール
- http://www.linux-kvm.org/images/f/f3/01x08b-KVMGT-a.pdf (PDF) KVMでのGPUの仕組み(少し古い)
- https://kiyoka.moe/post/1.html - report_ignored_msrs に関する言及、参考になった
- KVM環境でIntel iGPUグラフィックを仮想マシンにパススルー(というか共有)する - naba_san’s diary こちらの方がよくまとまってるかも