MMIO on VT-x

22
MMIO ON VT-X @syuu1228 13413日土曜日

description

 

Transcript of MMIO on VT-x

Page 1: MMIO on VT-x

MMIO ON VT-X@syuu1228

13年4月13日土曜日

Page 2: MMIO on VT-x

よくこんな風に説明しますね単純なエミュレーション:ゲストOSのプログラムの全命令をソフトウェアエミュレーションして実行→すごい遅い

VT-x以前の仮想化:ゲストOSのプログラムをそのままCPUで実行するとホストOSのステートが壊れる→実行してはならない命令を動的に置き換えてネイティブに実行(VMwareのBinary Translation)

VT-xを用いた仮想化:CPUをゲストモードへ切り替え、ゲストOSのプログラムをネイティブに実行(置き換え不要)

13年4月13日土曜日

Page 3: MMIO on VT-x

ゲストOSのプログラムをそのまま実行できる!

13年4月13日土曜日

Page 4: MMIO on VT-x

ゲストOSの命令は全部ネイティブに実行されるから、ハイパーバイザは介入しないんだよね!

13年4月13日土曜日

Page 5: MMIO on VT-x

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日土曜日

Page 6: MMIO on VT-x

VT-Xなハイパーバイザで命令エミュレーション必要なの…?

13年4月13日土曜日

Page 7: MMIO on VT-x

_人人人人人人_

> 必要です <

‾Y^Y^Y^Y^Y‾

13年4月13日土曜日

Page 8: MMIO on VT-x

何故?

13年4月13日土曜日

Page 9: MMIO on VT-x

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日土曜日

Page 10: MMIO on VT-x

IO命令によるVMExitIO命令が実行された時点でVMExitが発生

VMExitの詳細情報(Exit Qualification)から以下のような情報を取得

アクセスサイズ(1,2,4 bytes)

IN方向かOUT方向か

String命令(INS)か

REP prefixが付いているか

IOポート番号はイミディエイト値か、DXレジスタ参照か

IOポート番号(イミディエイト値)

13年4月13日土曜日

Page 11: MMIO on VT-x

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日土曜日

Page 12: MMIO on VT-x

MMIOによるVMExit

MMIOは通常のメモリアクセスと同じ命令を用いる→IO命令と違って命令で判別してVMExit出来ない

アクセスしたアドレスで判別可能→MMIO領域に該当するページにアクセスした時にVMExit(EPT violation)が起きるようにEPTを設定(read/write共に拒否)

13年4月13日土曜日

Page 13: MMIO on VT-x

MMIOでのVMExit時に得られる情報

EPT violation時のVMExit Qualification

どの種類のアクセス権違反でVMExitが起きたか

ページに設定された権限

ゲストOSがアクセスしたアドレス(論理・物理)

アクセスしたアドレスとアクセス方向(読み・書き)は分かる

書き込み元・読み込み先の情報(アドレス or レジスタ)とアクセス幅が分からないどんな命令が実行されたのか分からない

13年4月13日土曜日

Page 14: MMIO on VT-x

情報が足りない状態でMMIOをエミュレートするには

ゲストEIPの指すアドレスの命令をデコードして、オペコード・オペランドを取得

オペコード通りの動作をエミュレート

アクセス先アドレスがMMIO領域ならデバイスの挙動をエミュレート

13年4月13日土曜日

Page 15: MMIO on VT-x

情報が足りない状態でMMIOをエミュレートするには

ゲストEIPの指すアドレスの命令をデコードして、オペコード・オペランドを取得

オペコード通りの動作をエミュレート

アクセス先アドレスがMMIO領域ならデバイスの挙動をエミュレート

13年4月13日土曜日

Page 16: MMIO on VT-x

_人人人人人人人人人人人人_

> 命令エミュレーション <

‾Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y‾

13年4月13日土曜日

Page 17: MMIO on VT-x

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日土曜日

Page 18: MMIO on VT-x

x86アーキテクチャでは、メモリアクセス可能な命令やアドレッシングモードの種類が非常に多い

そもそもEPT violationはページへのアクセス権限エラーを知らせるVMExitであって、MMIOを知らせるVMExitではない

なんでCPUがやってくれないのか(想像)

13年4月13日土曜日

Page 19: MMIO on VT-x

しんどい

ただでさえMMIO領域に触れる度にVMExitするのに、更にデバイスエミュレータがユーザランドに居るのでコンテキストスイッチが発生

/usr/sbin/bhyve

BSDkernel vmm.ko

ioctl(VM_RUN)

guestkernel

VMExit

VMEntry

guestuserland

Host mode Guest mode

デバイスエミュレータ

13年4月13日土曜日

Page 20: MMIO on VT-x

Local APIC仮想化支援Local APICは割り込み周りで頻繁にアクセスされるが、MMIOを使っており準仮想化にも馴染みづらいデバイス

この領域のMMIOだけVT-xが特別扱い専用のVMExit ReasonとExit Qualificationを用意→命令エミュレーションが不要に

レジスタ・条件によってはVMExit自体省略

13年4月13日土曜日

Page 21: MMIO on VT-x

Coalesced MMIO (KVM)MMIO領域の中には読み書きによる副作用が無く、単純なメモリ読み/書きに置き換えられる部分が存在

VGAボードのピクセルデータの領域とか

VMExitが発生したらカーネル内で命令エミュレーションを実行、メモリ読み/書きを実施ユーザランドでのデバイスエミュレーションを省略

e1000ドライバ(NIC)のパフォーマンスが9.7%向上

13年4月13日土曜日

Page 22: MMIO on VT-x

まとめハードウェア仮想化支援機構といっても、なんでもやってくれるわけじゃない

最後はソフト屋が頑張るしかない

根性とバッドノウハウ・転んでも泣かない

すげぇ頑張ったのに新しいハード出るとハード出来るようになってたりすることもある(VT-x自体がそう)

13年4月13日土曜日