Unsafe Nested
Virtualization on Intel CPU
深井 貴明(筑波大学)
2016年12月5日
1
Nested Virtualization
2
VMM
VMM
QEMU/KVM, VirtualBox, etc.
VM
CPU
VM
VM の中にVMM が!
Nested Virtualization
3
L0 VMM (Layer 0)
L1 VMM (Layer 1)
QEMU/KVM, VirtualBox, etc.
L2 VM (Layer 2)
CPU
VM
VM の中にVMM が!
Nested Virtualization
4
L0 VMM (Layer 0)
L1 VMM (Layer 1)
QEMU/KVM, VirtualBox, etc.
L2 VM (Layer 2)
CPU
VM
VM の中にVMM が!
仮想化支援機能で
速度向上!
VT-x/AMD-V
Virtual VT-x/AMD-V
仮想化支援機能を
提供
BitVisor の Nested Virtualization
• イーゲル榮樂さんによる発表
Unsafe Nested Virtualization
5
Unsafe Nested Virtualization とは
• L1 VMM が trusted だと仮定し,いくつかの仮想化支援
機能をパススルーで L1 に提供する
• E.g. EPT をパススルーとか
• Para-passthrough な BitVisor ならではの (荒) 技
6
実行の流れ
7
L2 用 VMCB を
ロード
L1 用VMCBを
ロード
L1 VMM
L0 VMM
L2 VM
L1 が作成したVMCSを変換なしに直接ロード
VMExit VMEnter VMExit VMEnter
アドレス変換
L1 VMM
L0 VMM
L2 VM
CPU
EPT L2p L1p
PT L2v  L2p
L2 動作時
• L1 が作成した EPT を直接ロード
• BitVisor では L0p = L1p
• L0 の保護なしUnsafe
(L2p = L2 Physical address, …)
夢が広がりますね
• VMM のデバッグなどの用途に
• 木村さんのシステムと組み合わせればとても夢が広がるか
も
• 自由なライセンスの Nested Virtualization
• BitVisor は BSD ライセンス
• Open かつ not GPL で Nested Virtualization できる VMM は
ほかにない
9
しかし…
• Intel VT-x - 未着手
• AMD SVM - 実装済み
10
しかし…
• Intel VT-x - 未着手
• AMD SVM - 実装済み
11
Unsafe Nested Virtualization
on Intel CPU
12
基本設計
基本的には AMD 版と同じ(だと思う)
• L1 が作成した VMCS を (ほぼ) 直接ロード
• EPT は L1 が作成したものを直接ロード
VT-x と AMD-V の違いに対応
• VMX 命令
• VMExit 時の Host State のロード
13
AMD 版実装との主な違い
• 全部
• 命令エミュレーション
• Host States の Shadowing
• VMExit のエミュレーション
• vCPU マイグレーションへの対応
14
AMD 版実装との主な違い
• 全部
• 命令エミュレーション
• Host States の Shadowing
• VMExit のエミュレーション
• vCPU マイグレーションへの対応
15
VMX instructions
• VMXOFF
• VMXON
• INVEPT
• INVVPID
• VMREAD
• VMWRITE
• VMLAUNCH
• VMRESUME
• VMCLEAR
• VMPTRLD
• VMPTRST
16
VMX instructions
• VMXOFF
• VMXON
• INVEPT
• INVVPID
• VMREAD
• VMWRITE
• VMLAUNCH
• VMRESUME
• VMCLEAR
• VMPTRLD
• VMPTRST
17
実行したふりだけする
BitVisor が代わりに実行
VT-x 命令のエミュレーション
基本的には
• VMCS を L1/L0  L2/L0 に切り替え
• 実際に命令を実行
• 結果を L1 に返す
• L1 RFLAGS の反映
• オペランドとして渡されたレジスタ or メモリに結果を渡す
18
例: VMREAD
19
L0 BitVisor
L1 VMM
CPU
L1/L0
VMCS
L2/L0
VMCS
L1/L0
VMCS
L2/L1
VMCS
VMREAD!
例: VMREAD/VMWRITE
20
L0 BitVisor
L1 VMM
CPU
L1/L0
VMCS
L2/L0
VMCS
L1/L0
VMCS
L2/L1
VMCS
VMREAD!
VMExit
例: VMREAD/VMWRITE
21
L0 BitVisor
L1 VMM
CPU
L2/L0
VMCS
L2/L0
VMCS
L1/L0
VMCS
L2/L1
VMCS
VMPTRLD
VMREAD!
例: VMREAD/VMWRITE
22
L0 BitVisor
L1 VMM
CPU
L2/L0
VMCS
L2/L0
VMCS
L1/L0
VMCS
L2/L1
VMCS
VMREAD
VMREAD!
例: VMREAD/VMWRITE
23
L0 BitVisor
L1 VMM
CPU
L1/L0
VMCS
L2/L0
VMCS
L1/L0
VMCS
L2/L1
VMCS
VMREAD!
VMPTRLD
例: VMREAD/VMWRITE
24
L0 BitVisor
L1 VMM
CPU
L1/L0
VMCS
L2/L0
VMCS
L1/L0
VMCS
L2/L1
VMCS
VMREAD!
VMEnter
AMD 版実装との主な違い
• 全部
• 命令エミュレーション
• Host States の Shadowing
• VMExit のエミュレーション
• vCPU マイグレーションへの対応
25
VMCS が持つ States
26
VMCS
Guest State
Host State
Control State
VMCS が持つ States
27
VMCS
Guest State
Host State
Control State
VMExit 時に物理コアに
ロードされる情報
• RIP
• RSP
• etc.
VMCS が持つ States
28
VMCS
Guest State
Host State
Control State
VMExit 時に物理コアに
ロードされる情報
• RIP
• RSP
• etc.
L2 からのVMExit 時も
BitVisor の状態でないと困る
VMCS Shadowing
29
L2/L0 VMCS
Guest State
L1 が設定
Host State
L0 が設定
Control State
L1 が設定
Host State
L1 が設定
Shadow VMCS
CPU にセット L0 BitVisor が管理
AMD 版実装との主な違い
• 全部
• 命令エミュレーション
• Host States の Shadowing
• VMExit のエミュレーション
• VMCS のライフサイクルの対応
30
VMCS の切り替え
31
L1 VMM
L0 VMM
L2 VM
VMExit VMEnter VMExit VMEnter
CPU L1/L0
VMCS
L2/L0
VMCS
L1/L0
VMCS
VMCS の切り替え
32
L1 VMM
L0 VMM
L2 VM
VMExit VMEnter VMExit VMEnter
CPU L1/L0
VMCS
L2/L0
VMCS
L1/L0
VMCS
VMExit 時の処理
33
Intel SDM 3C が手元にある人は LOADING HOST STATE という章を見てみましょう
34
こんなにある!
35
bool to_64bit_mode;
ulong tmp;
ulong cr0, cr3, cr4;
/* These bit is not modified */
const u64 cr0_reserved = 0xffffffff1ffaffc0; /* 63:32, 28:19, 17, 15:6 */
ulong cr0_mask = CR0_ET_BIT | CR0_CD_BIT | CR0_NW_BIT | CR0_NE_BIT |
cr0_reserved;
ulong cr3_mask = ~(current->pte_addr_mask | PAGESIZE_MASK);
ulong cr4_mask = CR4_VMXE_BIT;
ulong acr;
u64 guest_efer;
const u64 efer_mask = MSR_IA32_EFER_LME_BIT | MSR_IA32_EFER_LMA_BIT;
struct vmcs_host_states hs = current->u.vt.shadow_vt->current_shadow_vmcs->hs;
ulong exit_ctl = current->u.vt.shadow_vt->current_shadow_vmcs->exit_ctl_shadow;
ulong exec_ctl;
/* Load some L2-L0 VMCS field */
これが”VMExit” 時のアトミックな処理…
AMD 版実装との主な違い
• 全部
• 命令エミュレーション
• Host States の Shadowing
• VMExit のエミュレーション
• vCPU マイグレーションへの対応
36
vCPU マイグレーション
= vCPU の物理コア間の移動
(プロセスマイグレーションみたいなイメージ)
37
物理コア 物理コア 物理コア 物理コア
vCPU
vCPU マイグレーションの流れ
38
物理コア 物理コア
vCPU
RAM
VMM
VMCS
VMCSの
キャッシュ
VMCS
vCPU マイグレーションの流れ
39
物理コア 物理コア
RAM
VMM
VMCS
VMCS
VMCLEAR
VMCSの
キャッシュ
キャッシュ
吐き出し
vCPU マイグレーションの流れ
40
物理コア 物理コア
RAM
VMM
VMCS
VMCS
VMCS
vCPU
VMCLEAR VMPTRLD
VMCSの
キャッシュ
キャッシュ
吐き出し
vCPU
Nested Virtualization での
vCPU マイグレーションの流れ
41
物理コア 物理コア
RAM
L1 VMM
L2/L0 VMCS
VMCLEAR
L0 VMM
L2/L1 VMCS
L1 Host State
vCPU
Nested Virtualization での
vCPU マイグレーションの流れ
42
物理コア 物理コア
RAM
L1 VMM
L2/L1 VMCS
L2/L1 VMCS
VMCLEAR
L0 VMM
L1 Host State
vCPU
Nested Virtualization での
vCPU マイグレーションの流れ
43
物理コア 物理コア
RAM
L1 VMM
L2/L1 VMCS
VMCLEAR
L0 VMM
L1 Host State
L2/L1 VMCS
Nested Virtualization での
vCPU マイグレーションの流れ
44
物理コア 物理コア
RAM
L1 VMM
L2/L1 VMCS
VMCLEAR
L0 VMM
L1 Host State
L2/L1 VMCS
VMPTRLD
Nested Virtualization での
vCPU マイグレーションの流れ
45
物理コア 物理コア
RAM
L1 VMM
L2/L1 VMCS
VMCLEAR
L0 VMM
L1 Host State
L2/L1 VMCS
VMPTRLD
L2/L1 VMCS
Nested Virtualization での
vCPU マイグレーションの流れ
46
物理コア 物理コア
RAM
L1 VMM
L2/L1 VMCS
VMCLEAR
L0 VMM
L1 Host State
L2/L1 VMCS
VMPTRLD
L2/L1 VMCS
L1 Host State
Nested Virtualization での
vCPU マイグレーションの流れ
47
物理コア 物理コア
RAM
L1 VMM
L2/L1 VMCS
VMCLEAR
L0 VMM
L1 Host State
L2/L1 VMCS
VMPTRLD
L2/L0 VMCS
L1 Host State
L0 Host
State
vCPU
その他ハマったところ: EFER
• IA32_MSR_EFER が Exit 時にロードされたりされなかっ
たりする
• Exit control でL1 が制御可能
• ゲストとホストが同じ EFER の設定を使っていると,VMExit の
たびに EFER を更新しないような設定にされたりする (KVM)
• うまく対応する必要がある
48
EFER の扱い
• L1 EFER  Physical EFER
• VMEntry from L0 to L2
• VMExit from L2 to L0
• If (exit_ctl & load_host_efer)
• L1/L0_VMCS_GUEST_EFER = L2/L1_VMCS_HOST_EFER
• else
• L1/L0_VMCS_GUEST_EFER = Physical EFER
• Restore EFER
• 32 Bit OS 対応どうしよう?
49
コード行数
• 明らかに Intel 対応の方が行数が多い
AMD: +266行,-6行 (Changeset #106)
Intel: +1455行, -1行
50
対応状況 (L2 は Ubuntu 16.04 64bit)
51
L1 VMM 対応状況
KVM O
VirtualBox on Linux O
VirtualBox on Windows O?
VMWare workstation player on Linux O
Bhyve O?
Hyper-V ?
BitVisor O
Xen ?
* on Mac ?
対応/検証状況
52
• とりあえず OS 起動のみ検証
• デバイスの共有などは未検証
• Nested EPT は未対応
• L2 は Ubuntu 16.04 64bit, Thinkpad X1 でのみの検証
性能評価
• とかやりたかったんですけどね…
• Advent Calendar で書けるといいな…
53
まとめ
• Intel CPU 向けに Unsafe Nested Virtualization の対応
• Intel だと以下が大変だった
• 命令エミュレーション
• Host States の Shadowing
• VMExit のエミュレーション
• vCPU マイグレーションへの対応
• 色々大変だったけど何とか動いて?よかった
• そのうちメインラインに入る…かも…?
54
55
書いてね
56

Unsafe Nested Virtualization on Intel CPU