Bhyve Internals
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Bhyve Internals

on

  • 2,677 views

 

Statistics

Views

Total Views
2,677
Views on SlideShare
2,677
Embed Views
0

Actions

Likes
6
Downloads
11
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as OpenOffice

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Bhyve Internals Presentation Transcript

  • 1. BHyVe internals @syuu1228 1
  • 2. 1, BHyVe 概要 2
  • 3. BHyVe とはFreeBSD 版の Linux KVM のようなものIntel VT を用いたハイパーバイザ開発の初期段階でごく限定的な機能が実装されている             ↓ 最低限のハイパーバイザ実装のよいサンプルになりそう 3
  • 4. 新しい Web サイトと GSoC web site http://www.bhyve.org/GSoC 2012: BHyVe BIOS emulation to boot legacy systems http://bit.ly/bhyve_bios 4
  • 5. 実装状況Intel VT-x, EPT 必須 (= Nehalem 以降必須 )BIOS 非対応 (disk ブート出来ない )対応デバイス : virtio-net, virtio-blk pci passthrough(VT-d) paravirtual console/debug port UART対応 OS: FreeBSD 8, 9, 10 5
  • 6. 動作イメージ/usr/sbin/bhyve User program IOCTL(VM_RUN) VMExit vmm.k GuestBSD kernel o kernel VMLAUNCH 6
  • 7. 使い方/boot/loader.confhw.physmem="0x100000000" (ホストのメモリ割り当てを減らしてゲスト用の領域を 用意)kldload vmm.ko/usr/sbin/bhyveload -m ${lowmem} -M {highmem} -h {bootdir} $ {vmname}/usr/sbin/bhyve -c ${cpus} -m ${lowmem} -M{highmem} -s 1,virtio-net,tap0 -s 2,virtio-blk,${diskdev} 7
  • 8. 各コマンドの役割分担/usr/sbin/bhyveload VM インスタンスを作成し、 BSD カーネルを VM インスタンスのメモ リ領域にロードして起動可能な状態を作る/usr/sbin/bhyve bhyveload が初期化した VM インスタンスを実行し、ディス ク、 NIC 、コンソールなどのデバイスエミュレーション処理を行う VM インスタンスの状態は、プロセス内ではなく /dev/vmm/$ {vmname} というデバイス上、つまりカーネル内に保持される。 このファイルへ read(), write(), mmap() する事により VM 内のメモリ空 間にアクセス出来る。 8
  • 9. bhyveload の動作sysctl(“hw.vmm.create”, vm_name)→ /dev/vmm/${vm_name} を作成open(/dev/vmm/${vm_name})seg.gpa = 0 seg.len = mem_size ioctl(fd, VM_MAP_MEMORY, seg) membase = mmap(NULL, mem_size, PROT_READ| PROT_WRITE, MAP_SHARED, fd, 0) 9
  • 10. userboot.soFreeBSD のブートローダをユーザ空間で動くように移植し たものメモリやレジスタへの読み書きを wrap 、ゲストのメモリ空 間/レジスタへアクセス (メモリ空間は mmap 、レジスタの読み書きは ioctl 経由 で VMM が管理するゲストのデスクリプタへ)これを利用して kload が実装されている ( Linux における kexec と同じ) 10
  • 11. bhyve の動作open(/dev/vmm/${vm_name})デバイス初期化pthread_create(fbsdrun_start_thread) fbsdrun_start_thread() { while(1) { ioctl(VM_RUN, &vmexit) handler[vmexit.exitcode](&vmexit, &vcpu); } }メイン関数はデバイスエミュレーションの処理要求イベントを kevent() で待つ 11
  • 12. デモhttp://www.youtube.com/watch?v=N2TbKzE_puA 12
  • 13. 2, CPU の初期化と OS のロード 13
  • 14. vCPU の初期化bhyveload で以下の初期化を実施 CR0 = PE | PG | NE # ページング、プロテクトモード CR4 = PAE | VMXE # PAE 、 VMX 有効 EFER = LME | LMA # long mode 有効 GDT 初期化&セグメントレジスタ初期化 タスクレジスタ初期化 ページテーブル& CR3 初期化 RSP 初期化 14 エントリポイント設定
  • 15. mptable の初期化/usr/sbin/bhyve から実行(引数の CPU 数を使用)(未実装な ACPI を使わずに)セカンダリ CPU の情報を OS に伝えるBIOS ROM 領域上にテーブルを用意PCI デバイスや割り込みの情報の伝達にも使ってる? 15
  • 16. bhyveload の役割ホストのユーザ空間でブートローダを起動して、カーネル をロードする為のレジスタ/セグメント/ページテーブ ルの初期化を行うゲストはいきなり 64bit モードでカーネルを実行 16
  • 17. 3, IO デバイスエミュレーション 17
  • 18. ゲストカーネルのコンフィグレーションdevice pcidevice bvmconsoledevice bvmdebugdevice mptable ACPI や多くのデバイスは無効 virtio.ko, if_vtnet.ko, virtio_pci.ko, virtio_blk.ko はモジュール としてビルド 18
  • 19. IO エミュレーションio emulation 実行 consol net blk e PCI /usr/sbin/bhyve IOCTL return VMExit IO 命令 vmm.k Guest BSD kernel o kernel 19
  • 20. IO エミュレーションゲスト OS が in/out 命令を実行、 VMExitvmm.ko で EXIT_REASON_INOUT をハンドルVM_EXITCODE_INOUT で ioctl を return 、カーネルから /usr/ sbin/bhyve へ制御を移すhandler[VM_EXITCODE_INOUT]()       ↓ inout_handlers[port].handler() の順にハンドラがコールされ、 IO ポートに割り当てられ たハンドラが実行される 20
  • 21. bvm_consoleIO 空間の 0x220 に inl / outl で読み書きゲストドライバ int getc(void) { return inl(0x220); } void putc(int c) { outl(0x220, c); } 割り込みなどない。VMM if (in) { read(fd, &c, 1); *eax = (c & 0xff); }else write(fd, *eax, 1); 21
  • 22. PCI バスCONFIG_ADDRESS レジスタ: 0xcf8CONFIG_DATA レジスタ: 0xcfc – 0xcff各仮想 PCI デバイスは初期化時に自分のコンフィグレジス タの値を設定各仮想 PCI デバイスの IO レジスタはデバイス初期化時に動 的に確保 22
  • 23. PCI デバイスの MSI 割り込みサポートPCI 割り込みとして MSI 割り込みのみサポートデバイス初期化時に configuration space 上の MSI capable フラグを 有効化/usr/sbin/bhyve からの割り込み要求は、 VM_LAPIC_IRQ ioctl とし て vmm.ko へ送られる 引数として cpuid と vector ナンバを指定vmm.ko で ioctl を受けて vlapic にレジスタ値をセットvmlaunch 前に vlapic の値をチェックして、割り込みがあったら VMCS にフラグをセット 23
  • 24. MSR register のエミュレーションLocal APIC をエミュレートする為に、 wrmsr/rdmsr 命令で VMExit を発生させ、エミュレーションを行なっているほぼ vmm.ko でエミュレーションを行なっているが、初期 化周りの一部の処理で /usr/sbin/bhyve へエミュレーション を行わせている 24
  • 25. タイマーLocal APIC Timer vmlaunch 前にタイマーの値を計算、 vlapic へ割り込みを設定 vmm.ko 内でエミュレーションTSC rdtsc を trap していないように見える (その場合どうなるんだろう??)PIT 8254 /usr/sbin/bhybe で IO ポートアクセスのエミュレーションをして いる 割り込むコードが見当たらないような…?? 25
  • 26. virtio-net, blkPCI デバイス、 IO エミュレーションと MSI 割り込みを使用/usr/sbin/bhyve でエミュレーションMMIO は使っていない (そもそも MMIO に対応していないっぽい…) 26
  • 27. pci passthrough(VT-d)デフォルトでは使わないIntel VT-d を使って PCI デバイスをゲストに割り当てる機能物理デバイス→ゲストへの割り込み転送は vmm.ko 内で行な っているが、 io は一度 /usr/sbin/bhyve へ戻しているよう に見えるMMIO 空間は EPT 経由でゲストにマップしている模様 27
  • 28. UART( bvm_console がダサいので)最近実装されましたてっきり PC の COM ポートをエミュレーション出来るよう にしたのかと思ったら、なんと PCI デバイス…。Siig CyberSerial 1-port と自己申告IOAPIC 未実装だから割り込みも未実装\ (^o^) / 28
  • 29. まとめたったこれだけのデバイスエミュレーションで、 (ちょっと苦しいけど)ゲスト OS が動く事が分かる 但し、準仮想化デバイスを幾つか使っているのでゲスト側ドライ バが必須現状では FreeBSD しか動かないが、 FreeBSD カーネルに 依存している訳ではない事がわかる bhyveload を fork して自分の起動したい OS に対応したものを書 けば、動きそう 29
  • 30. おまけBHyVe Hackathon 参加者募集中 http://bit.ly/bhyve_hackathon 詳しくは @syuu1228 まで 30