このページの目次
KVMのメモリとデバイス仮想化
カバー範囲: EPT/NPT (ステージ2ページテーブル) → MMU仮想化 → virtio (半仮想化) → VFIO (パススルー) → vhost (カーネル空間での高速化) → virtio-net/virtio-blk 詳細解説 カーネルバージョン: 2.6 ~ 6.x
メモリ仮想化: EPT/NPT
3層のアドレス変換:
GVA (ゲスト仮想アドレス)
→ ゲストページテーブル (ゲストOSが管理)
→ GPA (ゲスト物理アドレス)
→ EPT/NPT (KVMが管理、「ステージ2ページテーブル」)
→ HPA (ホスト物理アドレス)
EPT (Intel Extended Page Tables) / NPT (AMD Nested Page Tables):
ハードウェアが GVA→GPA→HPA の2次元ページウォーク (24ステップ!) を直接実行
→ KVM がシャドウページテーブル (shadow page table) を維持する必要がない
→ 現代のCPUはすべてハードウェアサポートを備えている
EPT violation: ゲストが自身のページテーブルを変更 → EPTページテーブルが期限切れ → VM exit
→ KVM が EPT マッピングを更新 → VMRESUME
MMU 仮想化
// arch/x86/kvm/mmu/mmu.c
// KVM MMU は2種類のページテーブルを維持する:
// 1. EPTページテーブル (ハードウェア使用): GPN → HPN
// 2. シャドウページテーブル (EPT非対応の旧CPUのみ): GVA → HPA
// TDP (Two-Dimensional Paging) = IntelのEPT、AMDのNPT
// kvm_mmu_page_fault():
// ゲストが GPA にアクセス → EPT violation → handle_ept_violation()
// → kvm_mmu_map() → EPT 内で GPA→HPA のマッピングを確立
// → ゲストに戻る
virtio: 半仮想化IO
// drivers/virtio/
// デザイン原則: ゲストは自分がVM内にあることを認識 → 共有メモリ(virtqueue)を使用して通信
// 実際のハードウェアをシミュレートする必要がない → 極めて高いIOパフォーマンス
// virtio デバイスモデル:
// フロントエンド (ゲスト): virtio-blk, virtio-net, virtio-scsi, virtio-gpu
// バックエンド (ホスト):
// QEMU (ソフトウェアシミュレーション)
// vhost (カーネル空間での高速化: vhost-net, vhost-scsi, vhost-vsock)
// vDPA (ハードウェアアクセラレーション: ネットワークカード/smartNIC)
virtqueue: 共有リングバッファ
// virtio のコア転送メカニズム:
// 1. split virtqueue: 従来のフォーマット (ディスクリプタテーブル + available ring + used ring)
// 2. packed virtqueue (1.1): よりコンパクトでキャッシュラインに優しい
// ゲストがIOをサブミット:
// ディスクリプタ + available ring に書き込み → kick (ドアベルへの書き込み)
// ホストが消費:
// ディスクリプタを取得 → IOを処理 → used ring に書き込み → 割込み (MSI-X)
// ゲストが完了:
// 割込み → used ring を読み取り → バッファを解放
vhost: カーネル空間での高速化
// drivers/vhost/net.c
// vhost は virtio のデータパスをカーネルに移動する:
// ゲスト → virtqueue → vhost (ホストカーネル) → tap デバイス → プロトコルスタック
// QEMU ユーザー空間をバイパス → レイテンシが約50%削減
// vhost-net: ネットワーク (最も一般的)
// vhost-scsi: ストレージ
// vhost-vsock: ゲスト↔ホスト通信 (AF_UNIX を介したVM境界を越えた通信)
VFIO: デバイスパススルー
// 物理PCIeデバイスをゲストに排他的に割り当てる:
// 1. ホスト側でデバイスをアンバインド (echo dev > /sys/bus/pci/drivers/xxx/unbind)
// 2. vfio-pci にバインド (echo vendor device > /sys/bus/pci/drivers/vfio-pci/new_id)
// 3. QEMU: -device vfio-pci,host=01:00.0
// 4. IOMMU による分離: デバイスのDMAはこのVMのメモリのみアクセス可能
// パフォーマンス: ベアメタルに近い (GPU、NVMe をゲストにパススルー)
// 制限: オンライン移行不可 (デバイス状態の保存/復元ができない)
参考
- ソースコード:
arch/x86/kvm/mmu/,drivers/virtio/,drivers/vhost/,drivers/vfio/ - カーネルドキュメント:
Documentation/virt/kvm/,Documentation/driver-api/virtio/ - LWN: "Virtio without the QEMU middleman (vhost)", "VFIO and device assignment"
キーワード: EPT, NPT, stage-2 page table, virtio, virtqueue, vhost, VFIO, PCI passthrough