※2024/04/05 稀にVMが少しの間フリーズする。に2つの修正を追加。
前置き#
普段はWindows、でもたまにUbuntu使っていたので
ホストはWindowsでHyperVを使ってゲストにUbuntuを入れていた。
ある日Androidのビルドをしているときにゲストに割り当てているM.2 SSDがSata3並の速度で稼働していることに気がついた。
もともとゲストにiGPUを割り当てれずGUIの使用に不便を感じていたところにこれだったので別の方法を考えていたところ、
ホストをUbuntuにしてiGPUを扱い、ゲストにIntel ARCを割り当てる案が浮かんだので取り組むことにした。
構成#
CPU: Core i5 12600k
RAM: 96GB
GPU: Intel UHD Graphics 770 & Intel ARC A770 16GB
OS: Kubuntu 22.04LTS
Kernel: 6.8.0-zen1-noir-rt7
ResizeBarはONです。
IOMMUを有効にする。#
BiosでVT-dとIOMMUに関する項目を有効にする。
次にカーネルコマンドラインのGRUB_CMDLINE_LINUX_DEFAULT
に以下を追記してIOMMUを有効にする。
sudo vim /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt"
変更を反映する
sudo update-grub
ホストがパススルー対象を使用しないようにする#
/etc/modules
に以下の内容を追記。
vfio
vfio_iommu_type1
vfio_pci
vfio_vurqfd
/etc/modprobe.d/vfio.conf
を作成して以下の内容を書き込みホストがGPUを使用しないようにする。
softdep snd_hda_intel pre: vfio-pci
softdep i915 pre: vfio-pci
options vfio-pci ids=8086:56a0,8086:4f90
8086:56a0
はVGAで8086:4f90
はオーディオデバイス。
変更を反映する。
sudo update-initramfs -u -k all
再起動するとIntel ARCでホストの出力ができなくなるので別途操作する手段を用意しておこう。
自分はIntel UHD Graphics 770の出力とRustdeskとsshを用意した。あると便利。
VMを作る。#
必要なソフトウェアのインストール
sudo apt install qemu-kvm libvirt-daemon-system bridge-utils virt-manager
aptで取得されるqemuのバージョンが古かったので自分はqemuをビルドした。
ビルド手順
別にしなくてもいいので折りたたみ。
wget https://download.qemu.org/qemu-8.2.2.tar.xz
tar xvJf qemu-8.2.2.tar.xz
cd qemu-8.2.2
./configure --target-list=x86_64-softmmu --enable-spice --enable-kvm
make -j12
sudo make install
ビルドしたものは/usr/local
にインストールされる。
virt-managerの設定からxml編集を有効化する。
virt-managerで適当にWindowsのマシンを作る。
ステップ5の画面でインストール前に設定をカスタマイズする
にチェックを入れてから完了を押すと
インスタンスの細かい設定を開けるのでPCIデバイスを割り当てる。
今回は
- USB controller (00:14.0)
- VGA (03:00.0)
- Audio (04:00.0)
- nvme ssd (06:00.0)
- nvme ssd (0a:00.0)
を割り当てた。
割り当てたいデバイスのアドレスはlspciで確認すべし。
トラブルを避けるおまじない#
このまま起動したいところだが自分の環境の場合2つのトラブルが発生した。
- シャットダウン時に
vfio-pci 0000:03:00.0: not ready ****ms after FLR; waiting
が何回か出たあとホストごとフリーズする。 - ResizeBar周りがなんかおかしい。(こっちはわりとどうでもいい)
vfio-pci 0000:03:00.0: not ready ****ms after FLR; waiting
#
これはIntel ARCのReset Methotに機能しないものが定義されていることによるエラーらしい。/sys/bus/pci/devices/{0000:03:00.0,0000:04:00.0}/reset_method
をクリアすると発生しないようだ。
- /root/arc-reset_methot.sh
#!/bin/bash
echo > /sys/bus/pci/devices/0000\:03\:00.0/reset_method
echo > /sys/bus/pci/devices/0000\:04\:00.0/reset_method
- /etc/systemd/system/arc-reset_methot.service
[Unit]
Intel ARC reset_methot clear.
[Service]
ExecStart= /root/arc-reset_methot.sh
Type=simple
Restart=no
User=root
[Install]
WantedBy=multi-user.target
sudo systemctl enable arc-reset_methot.service
これで起動時やシャットダウン時にエラーが起こらなくなる。
Resizebarに関する修正。#
/etc/libvirt/qemu/vm.xmlを以下の内容に修正する。
- <domain type='kvm'>
+ <domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
</devices>
+ <qemu:commandline>
+ <qemu:arg value="-fw_cfg"/>
+ <qemu:arg value="opt/ovmf/X-PciMmio64Mb,string=65536"/>
+ </qemu:commandline>
</domain>
他の問題#
現在ゲストでWindows11を動かしていて気になった問題。
GPU-ZでBus InterfaceがPCIe x1 1.1 @x1 1.1になっている。#
原因を探っていると、qemuやパススルー以前の問題で
ホストがLink Speed 2.5GT/s,Width x1として認識しているようで、pcie_set_speed.sh
を使っても操作できなかった。
sudo ./pcie_set_speed.sh 03:00.0 1
Link capabilities: 08400811
Max link speed: 1
Link status: 1011
Current link speed: 1
Configuring 0000:02:01.0...
Original link control 2: 00000001
Original link target speed: 1
New target link speed: 1
New link control 2: 00000001
Triggering link retraining...
Link status: 1011
Current link speed: 1
Intelのコミュニティでも報告されているが解決しなかったようだ
サポートページではこう説明されている。
稀にVMが少しの間フリーズする。#
dmesgを見てもログがなかったので途方に暮れていた。
色々調べているとArchWikiに自分のシチュエーションに合致しそうな内容が書いてあったので試してみる。
仮想マシン内のアプリケーションで長い遅延が発生したり開始に長い時間がかかる
効果があるかはわからないがRNGデバイスを追加してみた。ビデオカードの HDMI 出力からの音声がおかしい
音声が遅れるというのはなかったが音割れが多かったので試そうと思った。
(フリーズと思っているものがHDMI出力の極端な遅延により画面と音声が止まっているふうに感じられるという拡大解釈。)
MSI utility v3を使って各デバイスがMSIで動いているか確認して、
Line-Based Interruptsになっているものがあったら☑を入れてMSIに切り替える。
自分の場合はHigh Definition Audio コントローラがLineBasedになっていた。(Supported modesにLineBasedなかったのにね)
2024/3/30にこの2つの変更を行ってから2024/04/05(現在)までの使用している時間にはフリーズは観測されなかった。
(ホスト、VM共に常時起動状態なのでもしかしたら使用していないときに起こっている可能性は無きにしも有らず)
High Definition Audio コントローラがLineBasedに対応していないのに割り込み方法がLineBasedになっていたのが原因ではないかと推測している。
試したけど解決しなかった修正
/var/log/libvirt/qemu/*.log
にログが吐き出されているのを今日始めて知った。
ログを確認してみるとusbコントローラーのリセットに失敗しているようでqemu-system-x86_64: vfio: Cannot reset device 0000:00:14.0, no available reset mechanism.
qemu-system-x86_64: vfio: Cannot reset device 0000:00:14.0, no available reset mechanism.
qemu-system-x86_64: vfio: Cannot reset device 0000:00:14.0, no available reset mechanism.
qemu-system-x86_64: vfio: Cannot reset device 0000:00:14.0, no available reset mechanism.
となっていた。
USBコントローラーを事前にVM用に予約すればいいらしいので以下の内容をvfio.confに追記して様子を見ようと思う。softdep xhci_pci pre: vfio-pci
options vfio-pci ids=8086:7ae0
GPUから映像を出力したときに若干文字や色が汚い。#
多分目が悪い