濃いバナ
KVMの仕組み仮想化友の会
平 初 <htaira@pantora.net>

KVMの仕組み
KVMはQEMUの拡張機能

Guest OS•KVM拡張機能(qemu-kvm.c)が同時にコンパイル•カーネル空間で動くコンポーネントとユーザ空間で動くコンポーネントが存在

QEMU

QEMU SystemEmulator
qemu-kvm
kvmctl/dev/kvm

Linux Kernel

kvm.kokvm-intel.ko

kvm-amd.ko

2種類のカーネルモジュール•Intel VT(Intel Virtualization Technology)向けのカー
ネルモジュール → kvm-intel.ko•AMD-V(AMD Virtualization)向けのカーネルモ
ジュール → kvm-amd.ko

KVMとQEMU間の通信方法•KVMキャラクタデバイス(/dev/kvm)を経由•操作はmmap()、ioctl()などの関数•操作はユーザ空間で動くライブラリ(kvmctl.c)を経由
し行うこと

KVMが有効な場合
Hardware•/dev/kvmが存在する•kvm̲allowed == 1 (QEMUの中の変数)

Processor
Intel VTAMD-V

QEMUとKVM比較QEMUの仕組み

KVMの仕組みQEMUQEMU
QEMU SystemEmulator

QEMU System
Emulatorqemu-kvm
kvmctl/dev/kvm

Linux Kernel

HardwareProcessor

Linux Kernel

kvm.kokvm-intel.ko

kvm-amd.ko

Intel VT

AMD-V

HardwareProcessor

KVMのソースコード解説
ソースコードのディレクトリ構造 1/2• kvm-15/•

kvm ... QEMUのラッパスクリプト(Python)••••vl.c ... QEMU System Emulatorのコアコンポーネント
qemu-kvm.c ... QEMUのKVM拡張機能に関する関数が含まれる
qemu-kvm.h ... QEMUのKVM拡張機能に関する関数のヘッダーファイル
cpu-exec.c ... QEMUのゲストOSのCPU命令を解釈する関数が含まれる•
•••
•
•
•

kvm̲main.c ... QEMUのKVM拡張機能に関する関数のヘッダーファイル
x86̲emulate.c ... x86リアルモードをエミュレーションするコンポーネント
kvm̲vmx.c ... Intel VT用のカーネルモジュール
vmx.c ... Intel VT使用時にIntel VT用命令を処理するコンポーネント
mmu.c ... Intel VTの時にメモリ管理を行うコンポーネント
kvm̲svm.c ... AMD-V用のカーネルモジュール
svm.c ... AMD-V使用時にAMD-V用命令を処理するコンポーネント• kvm-15/qemu/ ... KVMに対応したQEMU• kvm-15/kernel/ ... KVMカーネルモジュール

KVMのソースコード解説
ソースコードのディレクトリ構造 2/2• kvm-15/user/ ... ユーザ空間で動くコンポーネント•••

kvmctl.c ... KVMキャラクタデバイス(/dev/kvm)と通信するコンポーネント
main.c ... KVM機能を試すテストアプリケーション
test/ ... ほとんどアセンブラで書かれた小さなOSが入っています。

• kvm-15/scripts/ ... KVMの周辺スクリプト• kvm-15/drivers/ ... ゲストOS向けパラバーチャルドライバ• hypercall.c ... Linux向けパラバーチャルドライバ(SCSIドライバやNICドライバが今後このドライバを経由するはず)

KVMのソースコード解説
KVMの起動# kvm --image ./hda.img※現在、Debian GNU/Linuxでは、まだスクリプトは使われていません。

kvmスクリプト(kvm-15/kvm)

1-1 Intel用カーネルモジュールとAMD用カーネルモジュールのどちらを読み込むかチェックする。
(/proc/cpuinfoの情報より自動判別)
1-2 最適なカーネルモジュールが読み込まれる。
1-3 KVMキャラクタデバイス(/dev/kvm)があるかチェックする。
1-4 CPUが64bitアーキテクチャがチェックし、最適なQEMUを起動する。
(Pythonのplatformライブラリによりカーネルの種類は自動判別)

KVMのソースコード解説
KVMの起動kvmスクリプト(kvm-15/kvm)

1-4 CPUが64bitアーキテクチャがチェックし、最適なQEMUを起動する。
(Pythonのplatformライブラリによりカーネルの種類は自動判別)

KVMのソースコード解説
KVMの起動main() in kvm-15/qemu/vl.c

kvm̲qemu̲init()
in kvm-15/qemu/qemu-kvm.c

2-1 KVMを使うかどうかチェックされる。
2-2 KVMを使う場合(kvm̲allowed == 1)、KVMを初期化する関数
kvm̲qemu̲init()が呼ばれる。

KVMのソースコード解説
KVMの起動kvm̲qemu̲init()
in kvm-15/qemu/qemu-kvm.c

3-1 kvm̲init()が呼ばれる。

kvm̲init()
in kvm-15/user/kvmctl.c

KVMのソースコード解説
KVMの起動kvm̲init()
in kvm-15/user/kvmctl.c

4-1 KVMキャラクタデバイス(/dev/kvm)がオープンされる。
4-2 KVMのAPIバージョン確認が行われる。
ioctl(fd, KVM̲GET̲API̲VERSION, 0);

kvm̲dev̲ioctl()
in kvm-15/kernel/kvm̲main.c/dev/kvm

kvm̲context̲t 構造体
int fd …

/dev/kvm

KVMのソースコード解説
KVMの起動5-1 switch文でKVM内の処理が分岐される。
5-2 KVMのAPIバージョン(KVM̲API̲VERSION)を返す。

kvm̲dev̲ioctl()
in kvm-15/kernel/kvm̲main.c/dev/kvm

KVMのソースコード解説
KVMの起動kvm̲init()in kvm-15/user/kvmctl.c

4-3 kvm̲context̲t 構造体が作られ初期化される。

KVMのソースコード解説
KVMの起動main() in kvm-15/qemu/vl.c

2-3 KVM拡張ページ空間(KVM̲EXTRA̲PAGES)を考慮し、必要な物理メモリサイズ(phys̲ram̲size)を計算する。
2-4 kvm̲qemu̲create̲context()を呼び出す。

kvm̲qemu̲create̲context()
in kvm-15/qemu/qemu-kvm.c

KVMのソースコード解説
KVMの起動kvm̲qemu̲create̲context()
in kvm-15/qemu/qemu-kvm.c

3-2 kvm̲create()を呼び出す。

kvm̲create̲context()
in kvm-15/user/kvmctl.c

KVMのソースコード解説
KVMの起動kvm̲create̲context()
in kvm-15/user/kvmctl.c

4-4 仮想マシン作成が作成される。
ioctl(fd, KVM̲CREATE̲VM, 0);

kvm̲dev̲ioctl()
in kvm-15/kernel/kvm̲main.c/dev/kvm

5-3 switch文でKVM内の処理が分岐される。
5-4 kvm̲dev̲ioctl̲create̲vm()が呼ばれる。