Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

月を見上げています

アウトプットのために定期的に書くようにしよう(自戒)

NVMe SSDをVMにパススルーする

NVMe SSDは単にNVMeプロトコルに対応したPCIeデバイスなので、GPUなどと同様にPCI Passthroughの手段を用いてVMにデバイスごとパススルーすることができます。ほとんど手順としては同じなのですが、備忘録代わりに具体的な手順を書いておきます。

今回の作業はホスト側にDebian BookwormベースのProxmox VE 8.3.1を、ゲスト側にDebain 12 (Bookworm)を用いました。が、他のディストリビューション(Arch LinuxFedoraなど)でも殆ど手順は変わらないはずです。

BIOS(UEFI)、カーネルの起動オプションの設定

まずBIOSの設定でVT-d(intel)やAMD-V(AMD)、IOMMUその他を有効にしておきます。今回はなんとなくでAbove 4G decoding(Resizable BAR)も有効にしましたが、これは特段影響しなさそうです。

次に、 /etc/default/grub を編集して GRUB_CMDLINE_LINUX_DEFAULTintel_iommu=on iommu=pt を追加します(前者はAMD環境では不要)。そうしたら update-grub として設定を適用します。

dmesgを見て設定が適用されていることを確認します:

# dmesg | grep -e DMAR -e IOMMU
[    0.527449] pci 0000:00:00.2: AMD-Vi: IOMMU performance counters supported
[    0.529504] perf/amd_iommu: Detected AMD IOMMU #0 (2 banks, 4 counters/bank).

カーネルモジュールの読み込み

必要なカーネルモジュールを起動時に読み込ませるため、 /etc/modules-load.d/ 以下に適当なファイルを作成して以下を追加します(拡張子が.confでないといけないかもしれない(未検証)):

vfio
vfio_iommu_type1
vfio_pci

そうしたら update-initramfs -u -k all でinitramfsを再生成すると起動時に読み込まれるようになるはずです。念の為確認しておきましょう:

# lsmod | grep ^vfio
vfio_pci               16384  1
vfio_pci_core          86016  1 vfio_pci
vfio_iommu_type1       49152  1
vfio                   65536  8 vfio_pci_core,vfio_iommu_type1,vfio_pci

カーネルモジュールの設定

ここがGPUのパススルーと違うところで、対象となるNVMe SSDに対してカーネルのnvmeドライバ ではなく 、vfioドライバにデバイスを初期化させる。そのために、nvme_coreより先にvfioをロードさせます。GPUではシステムに1枚しか刺さなかったり刺しても全部パススルーしたりするので気軽にblacklist nouveauみたいなことができてしまいますが、それをnvmeに対して行うとおそらく別のnvmeデバイスも見えなくなってしまうので少し違う方法を取る必要があります。

まず対象となるSSDのデバイスIDを確認します:

# lspci -nn | grep -i non-volatile
01:00.0 Non-Volatile memory controller [0108]: Phison Electronics Corporation PS5019-E19 PCIe4 NVMe Controller (DRAM-less) [1987:5019] (rev 01)

ここでは 1987:5019 がデバイスIDです。現時点ではnvmeドライバが利用されているはずです。

# lspci -ks 01:00.0
01:00.0 Non-Volatile memory controller: Phison Electronics Corporation PS5019-E19 PCIe4 NVMe Controller (DRAM-less) (rev 01)
    Subsystem: Phison Electronics Corporation PS5019-E19 PCIe4 NVMe Controller (DRAM-less)
    Kernel driver in use: nvme
    Kernel modules: nvme

vfio-pciを代わりに使わせたいので、 /etc/modprobe.d/ 以下に適当にファイルを作成して以下の内容を書き込みます(今回は nvme-passthrough.conf としました)。以下の例ではデバイスIDを 1987:5019 としています(Phison E19のもの)が、手元のデバイスに合わせて書き換えられるべきです。なお、複数のデバイスを指定する場合は ids=xxxx:xxxx,yyyy:yyyy とカンマで区切ります。

options vfio-pci ids=1987:5019
softdep nvme_core pre: vfio-pci

こう書けばPCI(e)のデバイス1987:5019に対してvfio-pciドライバを使用し、softdepでvfio-pciがnvme_coreより先に読み込まれるようになります。これで再起動すれば lsblk などから当該NVMeデバイスが消えていて、 lspci -nnk で出てくるKernel driver in useの項目がvfio-pciになっているはずです。(mkinitramfsの再生成と再起動が必要だったかもしれない)

# lspci -ks 01:00.0
01:00.0 Non-Volatile memory controller: Phison Electronics Corporation PS5019-E19 PCIe4 NVMe Controller (DRAM-less) (rev 01)
    Subsystem: Phison Electronics Corporation PS5019-E19 PCIe4 NVMe Controller (DRAM-less)
    Kernel driver in use: vfio-pci
    Kernel modules: nvme

あとはProxmox側でVMにデバイスをアタッチすればゲストから使えるようになります。