注意書き

本サイトでは、アフィリエイト広告およびGoogleアドセンスを利用しています。

Proxmoxによる仮想マシンへGPUパススルー(SR-IOV)

インフラストラクチャ

最近賑わっているミニPCというものを買いました。中でもIntel N100系列が意外にも実行パフォーマンスが良いという話のようで、盛り上がっているのかなと感じています。調べてみると N97 が安く、処理も N100より少し早いということで、以下の製品を買ってみました。メモリは 12GB で、仮想化プラットフォームProxmoxを動かすには心許ないところではありますが、実験環境としてはとてもよいと思ってます。

スポンサーリンク

最大のポイント

N100やN97には、Alder Lake 世代のEコアが搭載されており、これがSkylake級の性能を持っている&低消費電力であるというのが魅力です。そして、内蔵GPUも Intel UHD Graphics が使えて、これが SR-IOV (Single Root – I/O Virtualization) が使えるという、仮想化勢にはとても魅力あるものになっています。

Proxmox VE 8.3 で SR-IOV を有効にする

それでは、早速セットアップを行っていきましょう。ここでは Proxmox VE 8.3 を使用します。標準的にセットアップが完了している状態から、解説を進めます。以降の内容は、とてもよく出来ているドキュメント、以下のブログ記事を参考にしています。

Proxmox VE 8.2: Windows 11 vGPU (VT-d) Passthrough with Intel Alder Lake -
Using Proxmox 8.2 and want to share your Intel GPU with several Windows 11 VMs? Find out how to configure Intel VT-d and share the GPU with up to 7 VMs.

環境情報

セットアップ後、パッケージ類を最新にインストールしたところ、以下のようなカーネルバージョンとなりました。

  • Proxmox VE 8.3
    • Kernel : 6.8.12-5-pve

パッケージのインストール

以下のコマンドを入力します。

apt update && apt install git sysfsutils pve-headers mokutil -y
rm -rf /usr/src/i915-sriov-dkms-*
rm -rf /var/lib/dkms/i915-sriov-dkms
find /lib/modules -regex ".*/updates/dkms/i915.ko" -delete
apt install build-* dkms

次に、 i915-sriov-dkms のソースコードを取得します。

cd ~
git clone https://github.com/strongtz/i915-sriov-dkms.git
cd ~/i915-sriov-dkms

ソースコードの編集とビルド

私が手元で試したときには、モジュールをコンパイルする過程でエラーが発生してしまいました。これは、 https://github.com/strongtz/i915-sriov-dkms/issues/227 に記載の内容と同じもののようでした。

ファイル i915-sriov-dkms/drivers/gpu/drm/i915/intel_runtime_pm.c について、246行でエラーが出ているので、以下のように修正します。

if (pm_runtime_get_if_active(rpm->kdev, ignore_usecount) <= 0) // ← この記述を、
if (pm_runtime_get_if_active(rpm->kdev) <= 0)                  // ← このように変更する

そして、dkms 追加&インストールを行います。

cd ~/i915-sriov-dkms
dkms add .
dkms install -m i915-sriov-dkms -v $(cat VERSION) --force

セキュアブート関連

以下のコマンドを実行して、パスワードを入力します。パスワードは root パスワードとは別で新規に設定するものです。あとでこのパスワードを入力するので注意してください。

mokutil --import /var/lib/dkms/mok.pub

Grub更新

以下のコマンドを実行して、Grubを更新します。PCIデバイスをパススルーする際に必要となる、 intel_iommu=on などのパラメータもここで追記します。

cp -a /etc/default/grub{,.bak}
sudo sed -i '/^GRUB_CMDLINE_LINUX_DEFAULT/c\GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt i915.enable_guc=3 i915.max_vfs=7"' /etc/default/grub
update-grub
update-initramfs -u -k all

Intel の GPU を lspci コマンドで確認しておきます。
VGA カードがどの PCIe バス上にあるかを確認する必要があります。通常は00:02.0です。

lspci | grep VGA

そして以下のコマンドを実行します。

echo "devices/pci0000:00/0000:00:02.0/sriov_numvfs = 7" > /etc/sysfs.conf

セキュアブート

これまでの設定が適用できたら再起動します。このとき Perform MOK management の画面が出てくるので、Enroll MOK を選択して、先ほど設定したパスワードを入力します。

  • Enroll MOK
  • Continue
  • Yes
  • (パスワード入力)
  • 再起動

上記のようなコマンドを辿って、再び再起動します。

確認

シェルから以下のコマンドを実行して、VFが出現しているか、 IOMMU 有効になっているかなどを確認しておきます。

lspci | grep VGA
dmesg | grep IOMMU

VFを7つ生やしましたが、1つあたり2GBのメモリを消費するという記載を見かけましたので、今回のようなメモリが少ない環境では手加減した数で作るのがよさそうです。

このような状況になっていれば、SR-IOV の有効化はできたと思われます。

Windows11 のインストール

仮想マシンにWindows11をインストールし、GPUを接続してみます。まずはGPU接続せずにVMを作成します。最近のProxmoxではゲストOSにWindowsを選ぶと、以下のようにvirtioドライバ用のisoファイルを設定できるようになりました。

VMの構成

システムの設定では、上記の画面のように設定します。 UEFI であること、q35チップセット構成あたりは重要なポイントとなるようです。次にCPUについては host を選択し、エミュレート無しで設定します。

ネットワークについては、 E1000を選択して最初は構成します。また Windows11のセットアップ中はネットワーク接続を使いたくないため、以下の画面のように Disconnect にチェックを入れた状態で進めます。

Windows11 のインストール

基本的には、通常のWindows11とインストールは変わりません。ただし少し注意点として以下のようなものがあります。

  • ディスクドライブの認識のために、virtioのデバイスドライバ読み込み作業が必要
  • ネットワーク接続ができない状態でインストールするために、BypassNROの準備が必要
  • SR-IOVを利用したGPUをVMへ接続して使う場合、物理のHDMIなどから画面出力ができないようなので、リモートデスクトップが必要。そのため、Professional 以上のエディションが要求される

virtIOデバイスドライバ読み込みは、以下のような画面で必要になります。ドライバが無いとディスクドライブの列挙で何も表示されません。

ここで、ドライバを読み込ませてディスクを認識させます。そのときの流れを次の図に示します。

あとは、通常の Windows11 インストール同様に進めることができます。ファイルのコピーなどが完了するまでしばらく待ちます。

以下の画面になったら、 Shift+F10 を押下して、コマンドプロンプトを開きます。そこで、BypassNRO.cmd を実行します。再起動が始まり、再度セットアップからとなりますが、ネットワーク接続無しを選択して、Microsoftアカウントなしでのインストール続行ができるようになります。

cd oobe
BypassNRO.cmd

Windows11が起動後は、 virtIO ディスクを開いて、ドライバのインストールを行います。

ドライバのインストールが終わったら、 virtio-win-guest-tools もインストールしておきましょう。

ネットワークの復帰とデバイスドライバの準備

Windows11 をシャットダウンします。そして、ネットワークデバイスを以下のように設定し直します。 E1000 から VirtIOのものへ、Disconnect 状態を解除とします。そして Windows11 VM を起動します。

このあと、GPUを接続するので、先にデバイスドライバを用意しておきます。Intel のダウンロードサイトにアクセスして、 使用する GPU のドライバを取得します。私の環境では以下のドライバを使用しました。インストールは GPU 接続後におこないます

リモートデスクトップの支度など

仮想GPU接続後は、Proxmox の Webブラウザ画面からは操作ができなくなるため、リモートデスクトップを有効化します。この時点で、他のPCを用いて接続できることを確認しておいて下さい。

また、ユーザーパスワードについても無期限に設定しておくとトラブルが避けられるとのことなので、以下のコマンドを実行して変更しておきます。

wmic UserAccount set PasswordExpires=False

仮想GPUの接続など

ようやくVMへGPUを接続します。VMが起動している状態であれば、シャットダウンして下さい。 Proxmox VMの Hardware 設定画面から、PCI デバイスを選択します。このとき、00:02.1~00:02.7 などの割り振りの中からデバイスを選択します。

デバイスが選択できたら、 Primary のグラフィックデバイスとして使用するためにチェックを入れます。

先の画面では、1~7までデバイスのリストがあるので、同時に7つのVMでの同時利用ができます。リスト上の同じデバイスを、同時に複数VMで使うことは出来ず、同時に使いたい場合には被らないものを選択してください。なお、パフォーマンスが維持できるかどうかは環境に依存すると思われます。

そして、これまで使用していたディスプレイアダプタを無効とします。

この状態で VMを起動させ、リモートデスクトップ接続を行います。そして、先ほどダウンロードしたグラフィックスドライバをインストールします。インストール後に、デバイスマネージャーを確認し、以下のような状態であれば正しくドライバがインストールできていると判断できます。

この状態になると、VulkanCapsViewerもGPUを認識して情報を出力します。参考までに画面のキャプチャを掲載します。VMの中にいるのか、外でとったものなのか、これだけだともう分からないですね。

Ubuntu (24.04)の場合

Ubuntu 24.04 LTS についても同様にGPUを接続してみました。しかし、Windowsほどにはスムーズに行かないこと、また、一般ユーザーでは GPU を認識できる状態には至っていません。 デスクトップ画面で使いたかったのに無念です。

しかし、root ユーザーであれば、一定の状態になったので、それをここに記載して共有します。この先の誰かの糧になれば幸いです。

パッケージのインストールなど

標準状態で認識できるほど甘くは無く、ドライバをビルドする必要があります。そのため、まずはパッケージの取得から進めます。ここでは現在動作していたカーネルが、 6.8.0-50-generic というバージョンだったため、これに対応するヘッダをインストールしています。

sudo apt install build-* git dkms
sudo apt install linux-headers-6.8.0-50-generic

ドライバのインストール

Proxmox にインストールした i915-sriov-dkms ドライバのビルドと同じ手順を行います。しかし、コンパイルの過程でエラーが出てしまうため、今回は別のリポジトリのものを使用しました。以下のリポジトリにあった kernel-v6.12 ブランチのものを使っています。

GitHub - bbaa-bbaa/i915-sriov-dkms: dkms module of Linux i915 driver with SR-IOV support
dkms module of Linux i915 driver with SR-IOV support - bbaa-bbaa/i915-sriov-dkms

このソースからだと、 dkms install -m i915-sriov-dkms -v $(cat VERSION) --force の実行で成功しました。

続いて、起動時オプション設定については以下のようにします。Grubの更新を行います。

cp -a /etc/default/grub{,.bak}
sudo sed -i '/^GRUB_CMDLINE_LINUX_DEFAULT/c\GRUB_CMDLINE_LINUX_DEFAULT="quiet   i915.enable_guc=3' /etc/default/grub
update-grub
update-initramfs -u -k all

そしてVMを再起動して、認識状態を確認してみると以下のような感じでした。

$ lspci -vs 06:10.0
06:10.0 VGA compatible controller: Intel Corporation Device 46d1 (prog-if 00 [VGA controller])
        Subsystem: Device 0301:02f3
        Physical Slot: 16-2
        Flags: bus master, fast devsel, latency 0, IRQ 38
        Memory at 80000000 (64-bit, non-prefetchable) [size=16M]
        Memory at 7000000000 (64-bit, prefetchable) [size=512M]
        Capabilities: <access denied>
        Kernel driver in use: i915
        Kernel modules: xe, i915

#  lspci -vs 06:10.0
06:10.0 VGA compatible controller: Intel Corporation Device 46d1 (prog-if 00 [VGA controller])
        Subsystem: Device 0301:02f3
        Physical Slot: 16-2
        Flags: bus master, fast devsel, latency 0, IRQ 38
        Memory at 80000000 (64-bit, non-prefetchable) [size=16M]
        Memory at 7000000000 (64-bit, prefetchable) [size=512M]
        Capabilities: [ac] MSI: Enable+ Count=1/1 Maskable+ 64bit-
        Kernel driver in use: i915
        Kernel modules: xe, i915

vainfo や vulkan-tools などインストールしてみて、rootユーザーで情報を確認してみると以下のように情報が表示されました。なお、一般ユーザーではアクセスできず、あと一歩といったところでした。

root@appuser-ubuntu:~# vainfo
error: can't connect to X server!
libva info: VA-API version 1.14.0
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so
libva info: Found init function __vaDriverInit_1_14
libva info: va_openDriver() returns 0
vainfo: VA-API version: 1.14 (libva 2.12.0)
vainfo: Driver version: Intel iHD driver for Intel(R) Gen Graphics - 22.3.1 ()
vainfo: Supported profile and entrypoints
(以下省略)
vulkaninfo の結果より抜粋
Devices:
========
GPU0:
        apiVersion         = 4206796 (1.3.204)
        driverVersion      = 92274693 (0x5800005)
        vendorID           = 0x8086
        deviceID           = 0x46d1
        deviceType         = PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU
        deviceName         = Intel(R) Graphics (ADL-N)
        driverID           = DRIVER_ID_INTEL_OPEN_SOURCE_MESA
        driverName         = Intel open-source Mesa driver
        driverInfo         = Mesa 22.0.5
        conformanceVersion = 1.3.0.0
        deviceUUID         = 2014cb47-62ae-f426-3667-8c8c2fec81a8
        driverUUID         = afd24048-a0df-6936-015a-c89b1fd56d3f
GPU1:
        apiVersion         = 4202700 (1.2.204)
        driverVersion      = 1 (0x0001)
        vendorID           = 0x10005
        deviceID           = 0x0000
        deviceType         = PHYSICAL_DEVICE_TYPE_CPU
        deviceName         = llvmpipe (LLVM 13.0.1, 256 bits)
        driverID           = DRIVER_ID_MESA_LLVMPIPE
        driverName         = llvmpipe
        driverInfo         = Mesa 22.0.5 (LLVM 13.0.1)
        conformanceVersion = 0.0.0.0
        deviceUUID         = 00000000-0000-0000-0000-000000000000
        driverUUID         = 00000000-0000-0000-0000-000000000000

rootで認識できるということで、コンテナ環境にGPUを渡して、H/Wアクセラレートの効いた動画処理をやらせる、というようなことは可能になるのかもしれませんね

参考情報

今回の内容の実現にあたり、さまざまな情報を参照しました。本記事より詳細なことが記載されていますし、アップデートもあるかもしれませんので、うまくいかない場合には確認してみることをお勧めします。

おまけ

Proxmoxが流行ってきているのを感じます。 2025年春には書籍も出るようですね。昔からProxmoxを使っているユーザーとしては嬉しいところです。

created by Rinker
インプレス
¥3,520 (2025/01/04 15:10:14時点 Amazon調べ-詳細)
created by Rinker
日経BP
¥3,520 (2025/01/04 16:18:08時点 Amazon調べ-詳細)

コメント

タイトルとURLをコピーしました