このページの目次
QEMU と KVM の連携
概要: QEMU-KVM プロセスモデル → KVM_CREATE_VM/KVM_RUN → メモリレイアウト → vCPU スレッドループ → デバイスエミュレーション → ライブマイグレーション カーネルバージョン: 2.6.20 ~ 6.x
プロセスモデル
flowchart TD
QEMU["1つのVM = 1つのQEMUプロセス"]
QEMU --> MAIN["🧵 メインスレッド<br/>event loop, monitor"]
QEMU --> IO["🧵 IOスレッド (iothread)<br/>virtioデバイスIOの処理"]
QEMU --> VCPU["🧵 vCPUスレッド × N<br/>それぞれがKVM_RUNを実行"]
QEMU --> MIGRATE["🧵 移行スレッド<br/>ライブマイグレーション"]
classDef root fill:#e3f2fd,stroke:#1565c0
classDef thread fill:#fff3e0,stroke:#ef6c00
class QEMU root
class MAIN,IO,VCPU,MIGRATE thread
VM作成フロー
// QEMU → KVM:
kvm_fd = ;
// 1. VMの作成
vm_fd = ;
// 2. ゲストRAMの割り当て (QEMUが管理):
guest_ram = ;
// 3. KVMへの登録:
struct kvm_userspace_memory_region region = ;
;
// 4. vCPUの作成:
for
vCPU実行ループ
// QEMU: kvm_cpu_exec() (accel/kvm/kvm-all.c)
int
IOスレッドとvirtio処理
// QEMU iothread: 独立したevent loop
// → eventfd (virtio kick) でのepoll
// → QEMUがvirtioリクエストを処理:
// virtio-blk: read/write → ホストファイル (qcow2/raw) へのマッピング
// virtio-net: tap fd → Linux tun/tap の読み書き
//
// vhost (QEMUのバイパス):
// ioeventfd + irqfd → カーネルが直接処理
// → QEMUは設定のみを行い、データパスには関与しない
ライブマイグレーション
QEMU + KVMの連携:
1. ソース側: すべてのゲストRAMをread-onlyとしてマーク
→ 以降の書き込みでライトフォールトが発生 → ダンティページを記録
2. 反復コピー: RAMをプリコピーでターゲットへ転送
3. ダンティページ収束: 各ラウンドでdirty rateが減少 → 閾値に到達
4. stop-and-copy: ソースVMを一時停止 → 最後のダンティページとレジスタ状態をコピー → ターゲットで起動
5. ダウンタイムは約100ms (ワークロードによる)
参考
- ソースコード: QEMU
accel/kvm/kvm-all.c(KVMアクセラレーションのコア), Linuxvirt/kvm/kvm_main.c - カーネルドキュメント:
Documentation/virt/kvm/api.rst(ioctl APIリファレンス)
キーワード: KVM_RUN, kvm_run, ioctl, KVM_CREATE_VM, vCPUスレッド, iothread, ライブマイグレーション