virtio-nvgpu により KVM ゲストでネイティブに近い NVIDIA GPU パフォーマンスを実現
KVM ゲスト内でのネイティブに近い NVIDIA GPU アクセス
要点: virtio-nvgpu は、ホストとゲスト間で NVIDIA カーネルドライバの ioctl をドライバ ABI レベルで転送し、Linux KVM ゲストが未変更の NVIDIA ユーザーモードドライバを実行できるようにします。これにより、レンダリングパフォーマンスはベアメタルの 2% 以内に達し、追加の CPU コストはほぼ発生しません。
仕組み
- ゲストカーネルドライバ (GPL) は、通常の
/dev/nvidia*ノードを登録します。各ioctl()で、生のリクエストを virtqueue にシリアライズし、mmap()では共有メモリウィンドウをゲストプロセスに直接マップします。 - デバイスクレート (Apache-2.0、Rust) は VMM 内で実行され、これらの virtqueue メッセージを受信し、埋め込まれたファイル記述子とポインタを変換して、ioctl をホストの NVIDIA ドライバに転送します。バッファのブックキーピングはここにあります。
- イベント virtqueue は、GPU が作業を完了したときにゲストに通知し、ビジーポーリングを排除します。
- 分離計画 – 将来のゲストごとのサンドボックス化されたヘルパー (isolate コンポーネント) が実際のデバイスファイル記述子を保持します。現在は VMM プロセスが直接保持します。
このアーキテクチャは chromeos/virtio-media を反映しています。GPL ゲストドライバは、寛容なライセンスの VMM 非依存デバイスクレートの隣にあり、すべての VMM 相互作用はトレイトとして表現されます。
パフォーマンス結果 (RTX 3060、ドライバ 595.99.02)
| メトリック | ゲスト (virtio-nvgpu) | ベアメタルホスト |
|---|---|---|
| 一般的なゲーム描画のフレームタイム (≥2 ms) | -0.4% から +1.7% (ノイズ範囲内) | — |
| 超軽量描画のフレームタイム (≤0.5 ms) | 最大 +40.8% (待機コストが支配的) | — |
| 100 fps 非ペーシング実行の CPU 使用率 (12 秒) | 0.37 秒 | 0.40 秒 |
| フレームあたりのホスト-ゲスト間遷移 | ≈0.02 (約 59 フレームあたり 1 回) | 数千回 (Venus) |
| マルチゲストスケーリング (1 つの RTX 3060 で 4 ゲスト) | 合計 103.7 fps、各約 25.8 fps、シングルゲストパフォーマンスと同一 | — |
解釈: GPU バウンドのワークロードでは、ゲストはベアメタルと区別がつきません。唯一の測定可能なペナルティは、フレームバジェットが GPU ウェイクレイテンシ (~0.02 ms) より小さい場合に現れます。
サポートされているユースケース
- Vulkan および OpenGL レンダリング (ヘッドレス EGL も動作)
- ゲスト内の Wayland コンポジタ によるオフスクリーンフレームの提示
- CUDA メモリ割り当て および Vulkan/GL とのゼロコピー相互運用
- ゲスト側 CUDA バッファからの直接 NVENC エンコーディング (H.264/H.265 出力)
この設計は、物理スキャンアウト、MIG/SR-IOV、および完全な統合仮想メモリ (cudaMallocManaged) を意図的に除外しています。
ドライバ ABI の処理
NVIDIA のカーネルドライバ ABI はリリース間で変更されます。virtio-nvgpu は明示的な ABI プロファイル を提供します。
| プロファイル | 対象範囲 |
|---|---|
535.129.03 |
535.129.03 から次のプロファイルまで |
580.178.04 |
580.178.04 から次のプロファイルまで |
595.71.05 |
595.71.05 以降 |
535.129.03 より古いドライバは拒否されます。新しいドライバは、新しいプロファイルが追加されるまで最後のプロファイルで受け入れられます。プロファイルは NVIDIA の open-gpu-kernel-modules ソースから機械的に生成され、手書きではありません。
他の GPU 仮想化アプローチとの比較
| アプローチ | ゲストドライバ | API 変換 | GPU 共有 | NVENC サポート | 分離 |
|---|---|---|---|---|---|
| VFIO パススルー | ホストドライバがゲスト PCI デバイスにバインド | なし (ネイティブ) | GPU ごとに 1 VM (または専用カード) | 動作 (ネイティブ) | 強力 (IOMMU がゲストメモリを分離) |
| virtio-gpu + Venus | ゲスト Mesa ドライバ (virgl) | 描画呼び出しごとのシリアライズとリプレイ | 複数 VM が GPU を共有 | 不可 (バッファはホスト上) | 中程度 |
| virtio-nvgpu (このプロジェクト) | 未変更の NVIDIA ユーザーモードドライバ | ドライバ ABI レベルで ioctl を転送 (フレームあたり約 1 回) | 複数 VM が単一カードを共有 (最大 4 までテスト済み) | 動作、ゼロコピー | 弱い – すべての ioctl が転送され、ホストドライバが TCB 内にある |
重要な洞察: 変換境界をグラフィックス API からカーネルドライバに移すことで、
virtio-nvgpuは Venus の描画呼び出しごとの大きなオーバーヘッドを排除しつつ、複数のゲストが GPU を共有できるようにします。
セキュリティと分離に関する考慮事項
- ゲスト GPU ワークとホストメモリを分離する IOMMU 境界はありません。ホスト NVIDIA ドライバはホストの IOMMU ドメインで実行され、実質的に信頼コンピューティングベースの一部です。
- 現在の実装は、すべての ドライバ ioctl を転送します (ABI プロファイルで明示的に拒否されたものを除く)。寛容なフラグ (
--permissive-abi) により、デバッグ用にこれをさらに緩和できます。 - 将来の作業 (
isolate/) は、実際のデバイスファイル記述子をゲストごとのヘルパープロセスでサンドボックス化することを目指していますが、まだ実装されていません。 - VFIO と比較すると、攻撃面は大きくなります。侵害されたゲストは、許可された任意の ioctl を発行でき、GPU を共有するホスト上の複数プロセスの実行に似ています。
コミュニティフィードバック (Hacker News ハイライト)
- @refibrillator は、3 つの主要な GPU 共有方法 (VFIO、virtio-gpu/Venus、virtio-nvgpu) に言及し、
virtio-nvgpuはホストドライバが TCB 内にあるため、最も弱い分離を提供すると指摘しています。 - @orphereus は、通常の GPU パススルーを使用しない理由を尋ねています。答えは、パススルーでは GPU を VM 間で共有できないことです。
- @markasoftware は、gVisor の
nvproxyとの違いを尋ねています。README はnvproxyを直接のインスピレーションとして挙げていますが、違いは詳述していません。 - @ericd は、VFIO の複雑さなしに高性能なゲーミング VM が実現できることに興奮を表明しています。
- @majorchord は Windows ゲストサポートについて問い合わせています。現在のプロジェクトは Linux ゲストのみを対象としています。
リポジトリ構成
| ディレクトリ | ライセンス | 目的 |
|---|---|---|
driver/ |
GPL-2.0 | virtqueue を介して ioctl と mmap を転送するゲストカーネルモジュール |
device/ |
Apache-2.0 | virtio デバイスと ABI 変換を実装する VMM 非依存 Rust クレート |
isolate/ |
Apache-2.0 | 将来のゲストごとのサンドボックス化ヘルパーの設計ノート (コードはまだありません) |
gen/ |
— | NVIDIA ソースから派生した自動生成 ABI テーブル |
protocol/ |
BSD-3-Clause OR GPL-2.0+ | 共有ワイヤフォーマットと ABI 定義 |
はじめに
- ゲストドライバ (
driver/) をビルドし、KVM ゲスト内にロードします。 - 必要なトレイト (ディスクリプタチェーン I/O、イベント処理、ゲスト/ホストメモリマッピング) を実装して、
device/クレートを VMM に統合します。 - ゲスト内で Vulkan または Wayland アプリケーションを実行します。README のベンチマークスクリプト (
BENCHMARKS.md) で、ネイティブに近いパフォーマンスを確認できます。
制限事項と将来の作業
- 単一の RTX 3060 で最大 4 つ のゲストでテスト済み。それ以上のゲストは未テストです。
- ドライババージョン 595.99.02 (RTX 3060) と 615.71.09 (RTX A2000) のみで検証済み。他のカードは未テストです。
- CUDA 機能は転送されますが、列挙以外は十分に検証されていません。
- Windows ゲストサポートはまだありません。プロジェクトは Linux のみを対象としています。
- 分離の改善 (ゲストごとのサンドボックス、seccomp フィルタ) は計画されていますが、まだ実装されていません。
ライセンス
リポジトリには 3 つのライセンスゾーンがあります。ゲストドライバは GPL-2.0、デバイスクレートと isolate 設計は Apache-2.0、共有プロトコルヘッダーは BSD-3-Clause (または GPL-2.0+) です。
要約すると、virtio-nvgpu は、ABI レベルで NVIDIA ドライバ ioctl を転送することで、KVM ゲストにベアメタルに近い GPU パフォーマンスを提供しつつ、複数の VM が単一カードを共有できることを実証しています。ただし、VFIO パススルーよりも分離は弱くなります。