MMIO on VT-x
-
Upload
takuya-asada -
Category
Technology
-
view
1.698 -
download
0
description
Transcript of MMIO on VT-x
MMIO ON VT-X@syuu1228
13年4月13日土曜日
よくこんな風に説明しますね単純なエミュレーション:ゲストOSのプログラムの全命令をソフトウェアエミュレーションして実行→すごい遅い
VT-x以前の仮想化:ゲストOSのプログラムをそのままCPUで実行するとホストOSのステートが壊れる→実行してはならない命令を動的に置き換えてネイティブに実行(VMwareのBinary Translation)
VT-xを用いた仮想化:CPUをゲストモードへ切り替え、ゲストOSのプログラムをネイティブに実行(置き換え不要)
13年4月13日土曜日
ゲストOSのプログラムをそのまま実行できる!
13年4月13日土曜日
ゲストOSの命令は全部ネイティブに実行されるから、ハイパーバイザは介入しないんだよね!
13年4月13日土曜日
intvmm_emulate_instruction(void *vm, int vcpuid, uint64_t gpa, struct vie *vie, mem_region_read_t memread, mem_region_write_t memwrite, void *memarg){ int error;
if (!vie->decoded) return (EINVAL);
switch (vie->op.op_type) { case VIE_OP_TYPE_MOV: error = emulate_mov(vm, vcpuid, gpa, vie, memread, memwrite, memarg); break; case VIE_OP_TYPE_AND: error = emulate_and(vm, vcpuid, gpa, vie, memread, memwrite, memarg); break;
( ゚д゚)ハッ! こんな所にBHyVeのソースコードが…
命令エミュレーションっぽいコードが有るんですけど…
13年4月13日土曜日
VT-Xなハイパーバイザで命令エミュレーション必要なの…?
13年4月13日土曜日
_人人人人人人_
> 必要です <
‾Y^Y^Y^Y^Y‾
13年4月13日土曜日
何故?
13年4月13日土曜日
VT-xなハイパーバイザのライフサイクル
ホストOSのカーネルからゲストモードへ切替(VMEntry)
ハードウェアへのアクセスなどハイパーバイザの介入が必要な処理が実行されたらゲストモードを停止、ホストOSへ戻る(VMExit)
/usr/sbin/bhyve
BSDkernel vmm.ko
ioctl(VM_RUN)
guestkernel
VMExit
VMEntry
guestuserland
Host mode Guest mode
13年4月13日土曜日
IO命令によるVMExitIO命令が実行された時点でVMExitが発生
VMExitの詳細情報(Exit Qualification)から以下のような情報を取得
アクセスサイズ(1,2,4 bytes)
IN方向かOUT方向か
String命令(INS)か
REP prefixが付いているか
IOポート番号はイミディエイト値か、DXレジスタ参照か
IOポート番号(イミディエイト値)
13年4月13日土曜日
IO命令のエミュレーションExit Qualificationの情報に基いてIO命令をエミュレーション出来る
IN命令(イミディエイト値):EAX = ioport_read(imm)
OUT命令(イミディエイト値):ioport_write(imm, EAX)
IN命令(DX参照):EAX = ioport_read(DX)
OUT命令( DX参照):ioport_write(DX, EAX)
INS命令:*(ES:EDI) = ioport_read(DX)
OUTS命令:ioport_write(DX, *(ES:EDI))
13年4月13日土曜日
MMIOによるVMExit
MMIOは通常のメモリアクセスと同じ命令を用いる→IO命令と違って命令で判別してVMExit出来ない
アクセスしたアドレスで判別可能→MMIO領域に該当するページにアクセスした時にVMExit(EPT violation)が起きるようにEPTを設定(read/write共に拒否)
13年4月13日土曜日
MMIOでのVMExit時に得られる情報
EPT violation時のVMExit Qualification
どの種類のアクセス権違反でVMExitが起きたか
ページに設定された権限
ゲストOSがアクセスしたアドレス(論理・物理)
アクセスしたアドレスとアクセス方向(読み・書き)は分かる
書き込み元・読み込み先の情報(アドレス or レジスタ)とアクセス幅が分からないどんな命令が実行されたのか分からない
13年4月13日土曜日
情報が足りない状態でMMIOをエミュレートするには
ゲストEIPの指すアドレスの命令をデコードして、オペコード・オペランドを取得
オペコード通りの動作をエミュレート
アクセス先アドレスがMMIO領域ならデバイスの挙動をエミュレート
13年4月13日土曜日
情報が足りない状態でMMIOをエミュレートするには
ゲストEIPの指すアドレスの命令をデコードして、オペコード・オペランドを取得
オペコード通りの動作をエミュレート
アクセス先アドレスがMMIO領域ならデバイスの挙動をエミュレート
13年4月13日土曜日
_人人人人人人人人人人人人_
> 命令エミュレーション <
‾Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y‾
13年4月13日土曜日
intvmm_emulate_instruction(void *vm, int vcpuid, uint64_t gpa, struct vie *vie, mem_region_read_t memread, mem_region_write_t memwrite, void *memarg){ int error;
if (!vie->decoded) return (EINVAL);
switch (vie->op.op_type) { case VIE_OP_TYPE_MOV: error = emulate_mov(vm, vcpuid, gpa, vie, memread, memwrite, memarg); break; case VIE_OP_TYPE_AND: error = emulate_and(vm, vcpuid, gpa, vie, memread, memwrite, memarg); break;
( ゚д゚)ハッ! これがそうだったのか
13年4月13日土曜日
x86アーキテクチャでは、メモリアクセス可能な命令やアドレッシングモードの種類が非常に多い
そもそもEPT violationはページへのアクセス権限エラーを知らせるVMExitであって、MMIOを知らせるVMExitではない
なんでCPUがやってくれないのか(想像)
13年4月13日土曜日
しんどい
ただでさえMMIO領域に触れる度にVMExitするのに、更にデバイスエミュレータがユーザランドに居るのでコンテキストスイッチが発生
/usr/sbin/bhyve
BSDkernel vmm.ko
ioctl(VM_RUN)
guestkernel
VMExit
VMEntry
guestuserland
Host mode Guest mode
デバイスエミュレータ
13年4月13日土曜日
Local APIC仮想化支援Local APICは割り込み周りで頻繁にアクセスされるが、MMIOを使っており準仮想化にも馴染みづらいデバイス
この領域のMMIOだけVT-xが特別扱い専用のVMExit ReasonとExit Qualificationを用意→命令エミュレーションが不要に
レジスタ・条件によってはVMExit自体省略
13年4月13日土曜日
Coalesced MMIO (KVM)MMIO領域の中には読み書きによる副作用が無く、単純なメモリ読み/書きに置き換えられる部分が存在
VGAボードのピクセルデータの領域とか
VMExitが発生したらカーネル内で命令エミュレーションを実行、メモリ読み/書きを実施ユーザランドでのデバイスエミュレーションを省略
e1000ドライバ(NIC)のパフォーマンスが9.7%向上
13年4月13日土曜日
まとめハードウェア仮想化支援機構といっても、なんでもやってくれるわけじゃない
最後はソフト屋が頑張るしかない
根性とバッドノウハウ・転んでも泣かない
すげぇ頑張ったのに新しいハード出るとハード出来るようになってたりすることもある(VT-x自体がそう)
13年4月13日土曜日