はじめまして、nilpeと申します。普段はしがない大学生をやってます。
さて、日々暮らしてると唐突に、qemuから直接ホストに刺さっているpcieカードが使いたいな、ってなることありますよね? 1
しかしながら、chatGPTに聞いてもまともな答えは帰って来なかったので、いろいろ試してうまく行った部分を紹介させていただきます。
警告(再掲)
この手法は、筆者の環境でのみ検証しています。再現しようとして何らかの問題が発生しても、筆者は責任を取りかねます。
前提
- 筆者はmarvell 88se9230と呼ばれる、Linux 6.8.0ではマトモに動かない2 (例1、例2)RAIDカードを使っている。
- しかしながら、4.4系~5.15系では正常に動作する(らしい)ことを知っている。 3
- 筆者のマシンはamd ryzen7 5700xとTUF GAMING B550-PLUSで組まれている。本記事ではintel製cpuを想定していない。
下準備
まずは、必要なソフトウェアを用意します。
以下のコマンドを実行しましょう。
sudo apt install -y qemu qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virt-manager
次に、必要なデーモンを立ち上げて、ユーザーを登録します。
# libvirtデーモンを有効にして起動
sudo systemctl enable --now libvirtd
# ユーザーをlibvirtグループに追加
sudo usermod -aG libvirt $(whoami)
# 設定を反映するために再ログイン
newgrp libvirt
# KVMの状態を確認
sudo systemctl status libvirtd
# インストールされたQEMU/KVMのバージョンやサポート情報を確認
virsh list --all
次に、grubの起動ファイル(/etc/default/grub)を編集します。ACSと呼ばれる、iommuの分離を有効化します。こちらもご覧ください。以下のように編集しましょう。
警告(再掲)
この手法は、筆者の環境でのみ検証しています。再現しようとして何らかの問題が発生しても、筆者は責任を取りかねます。
GRUB_CMDLINE_LINUX_DEFAULT="quiet iommu=pt splash amd_iommu=on pcie_acs_override=downstream,multifunction"
できたら、以下のコマンドを実行して編集を有効化しましょう。
sudo update-grub
acsはカーネルのメインラインにはなく、パッチがあたっているカーネルを利用しなければなりません。ACS Override Kernel Builds から、所望のカーネルを取得しましょう。以下は一例です。
wget https://gitlab.com/Queuecumber/linux-acs-override/-/jobs/1244659933/artifacts/download
unar ~/Downloads/artifacts.zip
cd ./artifacts
sudo apt install linux-headers-5.12.2-acso_5.12.2-acso-1_amd64.deb linux-image-5.12.2-acso_5.12.2-acso-1_amd64.deb
では、デバッグしたいカードのidを取得しましょう。
lspci -nnk
03:00.0 SATA controller [0106]: Marvell Technology Group Ltd. 88SE9230 PCIe 2.0 x2 4-port SATA 6 Gb/s RAID Controller [1b4b:9230] (rev 11)
Subsystem: Marvell Technology Group Ltd. 88SE9230 PCIe 2.0 x2 4-port SATA 6 Gb/s RAID Controller [1b4b:9230]
Kernel driver in use: vfio-pci
Kernel modules: ahci
今回はmarvellのカードが1枚しか刺さっていないので、これが正解です。出力結果から、「03:00.0」と「1b4b:9230」という形式のidをメモしておきましょう。
ここまで来たらリブートして、先程インストールしたカーネルで立ち上げます。
このままだと、必要なドライバが当たっていないので、とりあえず今現在動いているドライバを蹴り出し、vfioと呼ばれるドライバを当てます。
vfioについては他の方が解説を挙げていらっしゃると思うので省きます。
echo "03:00.0" | sudo tee /sys/bus/pci/drivers/ahci/unbind
echo 1b4b 9230 | sudo tee -a /sys/bus/pci/drivers/vfio-pci/new_id
今回はahciが動いていたのでこのコマンドで大丈夫でしたが、他のカードの場合は適切に読み替えてください。
エラーもなく動いたら、このカードは/dev/vfio/に割り当てられているので、権限を変更します。
sudo chmod 666 /dev/vfio/20
最後に、qemuにカードを渡します。
qemu-system-x86_64 -enable-kvm -m 2048 -cpu host -hda ~/ubuntu_vm.qcow2 -device vfio-pci,host=03:00.0 -vga virtio
結果
qemuにpcieカードが渡ります。あとは適当な方法でデバッガを当てれば良いと思います。
それはそれとして、どうしてlinux6.8.0なのにこのRAIDカードは動いてるんですかね・・・?
余談
これで動いたとき、一瞬で忘れそうだからと友人にLINEを送りました。夜遅くにこれを投げられた友人に合掌。