QEMU(KVM)でNVMe SSDをPCIパススルーして使用する
KVMでPCIパススルーを行うには、デバイスの制御をデバイスドライバからvfio-pci
に切り替えなきゃいけないけど、検索して出てくる方法は大抵デバイスドライバを無効化するとか、ベンダーID/デバイスIDで使用するドライバを上書きする等対象範囲が広すぎて、同じデバイスを2つ積んでて片側だけKVMに割り当てるといったことができない。
OVMF による PCI パススルー#ゲストとホストで同じ GPU を使う
ここにあるような起動時にスクリプトを実行するような方法もあまりスマートじゃないのでやりたくない。
それこそ、virt-managerだと起動時の作業がなくても、設定したデバイスだけ自動でvfio-pci
に切り替えてくれるのに、QEMUを直接叩く場合はできないの?って思って調べたので、その方法をまとめます。
(おそらく今回の方法はNVMe SSD以外のGPU・NIC・USBコントローラー等普通のPCIeデバイスでも使えますが、動作検証を行なってないのであくまでタイトルはNVMe SSDだけにしてます。また、当方Arch Linuxを使ってるので、それ以外のLinuxディストリビューションでは適宜読み替えが必要かもしれません。)
デバイスを使用中の場合は止める
SSDだったらマウントされているとかですね。アンマウントしてデバイスにアクセスしているプロセスがいない状態にしてください。
デバイスの情報を得る
とりあえず以下のコマンドを打ってください。
$ lspci -D -v
そうすると、積んでるPCIeデバイスの一覧が出てきます。その中からKVMに割り当てたいデバイスを探してください。僕の場合これですね
0000:01:00.0 Non-Volatile memory controller: Intel Corporation SSD Pro 7600p/760p/E 6100p Series (rev 03) (prog-if 02 [NVM Express])
Subsystem: Intel Corporation SSD Pro 7600p/760p/E 6100p Series [NVM Express]
Flags: bus master, fast devsel, latency 0, IRQ 44, NUMA node 0, IOMMU group 13
Memory at fe900000 (64-bit, non-prefetchable) [size=16K]
Capabilities: <access denied>
Kernel driver in use: nvme
必要な情報は先頭と末尾にあるやつです。デバイスの識別番号が0000:01:00.0
で、nvme
ドライバによって制御されてます。
デバイスの制御をvfio-pci
に切り替える
ここら辺カーネルモジュールをいじるのでスーパーユーザーに入っての作業になります。
# modprobe vfio-pci
# echo -n "0000:01:00.0" > /sys/bus/pci/drivers/nvme/unbind
# echo vfio-pci > /sys/bus/pci/devices/0000:01:00.0/driver_override
# echo 0000:01:00.0 > /sys/bus/pci/drivers_probe
まず1つ目のコマンド、これはvfio-pci
カーネルモジュールを読み込んでます。起動後に一度実行すればあとは不要ですし、起動時の設定で自動読み込みするようにしていれば不要です。
2つ目のコマンドは0000:01:00.0
のデバイスをnvme
ドライバから切り離しています。"0000:01:00.0"
の部分と/sys/bus/pci/drivers/nvme/unbind
内のnvme
は各自自分のデバイスに合わせて変えてください。
3つ目のコマンドは0000:01:00.0
で使用するドライバにvfio-pci
を指定しています。
そして、4つ目のコマンドで0000:01:00.0
のドライバを再読み込みさせると、無事デバイスの制御がvfio-pci
に切り替わります。
試しに、再度lspci -D -v
で確認してみましょう。
0000:01:00.0 Non-Volatile memory controller: Intel Corporation SSD Pro 7600p/760p/E 6100p Series (rev 03) (prog-if 02 [NVM Express])
Subsystem: Intel Corporation SSD Pro 7600p/760p/E 6100p Series [NVM Express]
Flags: bus master, fast devsel, latency 0, IRQ 44, NUMA node 0, IOMMU group 13
Memory at fe900000 (64-bit, non-prefetchable) [size=16K]
Capabilities: <access denied>
Kernel driver in use: vfio-pci
切り替わってることが確認できればOKです。
QEMU(KVM)の起動
これでKVMからPCIeデバイスを使用する準備は整ったので、あとはパラメータにパススルーを指定して起動しましょう。
$ sudo qemu-system-x86_64 \
-cpu host -smp 8 --enable-kvm \
-m 16G \
-bios efi/OVMF.fd \
-device vfio-pci,host=0000:01:00.0
これは僕が普段使ってるコマンドから起動に必要なものだけを抜き出したコマンドです。
今回大事なのは-device vfio-pci,host=0000:01:00.0
のオプション。これでPCIパススルーを指定します。host=
の値はデバイスの識別番号ですね。
-bios efi/OVMF.fd
はQEMUでUEFIを使いたいときに必要なやつです。NVMeからの起動はBIOSじゃできないので。efi/OVMF.fd
はUEFIのファームウェアを指定してください。主要なLinuxディストリビューションだとパッケージマネージャーで公式のレポジトリから取ってこれることが多いので、それを指定すればいいでしょう。自分はあまりそこらへん考えるのが面倒なので、以下で用意したのをいろいろな場所で使いまわしてます。
QEMUはUEFI用のファームウェアを持っていないので、UEFI環境でのブートをしたかったら別途用意しなきゃいけないのですが、Intel用のファームウェアはLinuxのパッケージマネージャーのレポジト...
コメント