第七回 カーネル/VM探検隊発表x86-64/Linuxに独自メモリ空間を勝手増設                 中村 実        nminoru1975@gmail.com          Twitter @nminoru_jp  ...
自己紹介• 某電機メーカーのサラリーマンです。• 01~05 Java VM• 06~10 メインフレームのソフトエミュ  レータ• 11    ファイルシステム                         2
エミュレータを高速化するに      は?• ゲストとホストでCPUが異なる計算機を想  定 – ARM、MIPS、SPARC、Alphaをx86-64上で実行• ゲストの仮想メモリがネック – ソフトウェアでエミュレーションすると絶対   的...
ホストMMUをどうやって使う      か?• どうすればいい? 1. OSを自前で作る 2. OSから一部のCPUを切り離して独自処理 3. 既存のOSを改造 このLTではx86-64/Linux上で32ビットCPUを エミュレーションする勝...
オレオレVM• Linux仮想メモリ(VM)中に自分専用のVMを!  – https://github.com/nminoru/oleolevm/    x86風の2段のページテーブルを持つCPUを仮定• 使い方  – /proc/oleole...
どのように改造するか?• Hugetlb を参考に (`・ω・´)• vm_area_structのvm_flagsを勝手に追加  – /include/linux/mm.h     #define VM_HUGETLB 0x00400000 ...
Shadow Page Table(SPT)  • ゲストの仮想メモリ空間をホストのページテーブルに    組み込む。                                          CR3            oleole...
サンプルはここまでで力尽きま      した                 8
ゲストCR3を切り替え対応 • ゲストのコンテキストスイッチに応じてSPTの書き換   えが必要 • 毎回破棄するとコスト高なので過去のSPTも保存      – PUDをゲスト仮想空間1つに割り当てると効率がイイ!!         CR3 ...
ゲストモード対応• ゲストにもuser modeとsupervisor modeがあり  アクセス禁止領域が違う• User mode用とsupervisor mode用の空間を分  けてしまえば解決        Guest Virt Spa...
JITコンパイラ対応• 高速化のためのJIT Compilation  – Dynamic Binary Translationとも言う• 分岐回数テーブル  – 普通はハッシュテーブル                             ...
ゲストデバッグ機能対応• Watchpoint Debug  – 指定したメモリ範囲にアクセスがあったことを検    出• 問題  – アクセスの補足方法     • x86のdebug registerはエミュは使い辛い     • ゲストの...
アドレス判定• #PF例外はCR2に例外を起こしたメモリアドレ  スを返すが不正確 – movq %rax, [0x0FFE] で #PF がでてもCR2は0x1000に   なるかも。• x86命令をデコードしてアドレスを判定 – struc...
再実行• ゲストのLOAD/STOREは#PF例外補足後に再実  行できないとダメ  – でもSPTにプロテクションをかけているよ• x86を1命令エミュレーション  – #PFを起こしたx86命令をカーネルランドで1命令    エミュし、pt...
まとめ• オレオレVMを使えばx86-64のMMUを全部  使える (`・ω・´)• でもカーネルのリベースが大変 (´;ω;`)• なにかうまい手はありませんか?                            15
参考文献• Jim Smith, Ravi Nair, Virtual Machines:  Versatile Platforms for Systems and Processes                              ...
清聴ありがとうございまし     た。               17
ここから未使用          18
予約領域を使う• x86/x86-64は#PF例外の種類が少ない• #PF例外時のエラーコード – Present bit – W/R bit – U/S bit• そうだ!! 予約領域を使おう – RSVD                  ...
SPTの一貫性(1/2)• ゲストのページテーブルとSPTの一貫性の維  持するには? 1. ゲストのページテーブル領域に書込み保護をか    ける 2. 毎回SPTを破棄 3. 毎回SPTをゲストのページテーブルとチェック• x86-64の予...
SPTの一貫性(2/2)• 予約領域へビットを打った場合「SPTを  チェックしろ」という意味• RSVD=1の#PF例外をハンドルして検査• 最初はPGDのreserved bitを打つ。• #PF例外があがるとPGDのreserved bi...
改造なしで独自メモリ管理• vm_area_structにvm_opsを設定 static int foo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) {     vmf...
X86-64の仮想メモリは将来拡張さ          れるか?• U.S. Patent 6,671,791 Processor including a translation  unit for selectively translatin...
Upcoming SlideShare
Loading in …5
×

x86-64/Linuxに独自メモリ空間を勝手増設

791 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
791
On SlideShare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
8
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

x86-64/Linuxに独自メモリ空間を勝手増設

  1. 1. 第七回 カーネル/VM探検隊発表x86-64/Linuxに独自メモリ空間を勝手増設 中村 実 nminoru1975@gmail.com Twitter @nminoru_jp http://www.nminoru.jp/~nminoru/ 1
  2. 2. 自己紹介• 某電機メーカーのサラリーマンです。• 01~05 Java VM• 06~10 メインフレームのソフトエミュ レータ• 11 ファイルシステム 2
  3. 3. エミュレータを高速化するに は?• ゲストとホストでCPUが異なる計算機を想 定 – ARM、MIPS、SPARC、Alphaをx86-64上で実行• ゲストの仮想メモリがネック – ソフトウェアでエミュレーションすると絶対 的に遅い – ホストのMMUを使ってゲストのメモリ空間を エミュレーションしましょう。 3
  4. 4. ホストMMUをどうやって使う か?• どうすればいい? 1. OSを自前で作る 2. OSから一部のCPUを切り離して独自処理 3. 既存のOSを改造 このLTではx86-64/Linux上で32ビットCPUを エミュレーションする勝手改造を紹介しま す 4
  5. 5. オレオレVM• Linux仮想メモリ(VM)中に自分専用のVMを! – https://github.com/nminoru/oleolevm/ x86風の2段のページテーブルを持つCPUを仮定• 使い方 – /proc/oleolevm を mmap – CPU 命令のインタプリータがロード・ストア – ゲストのTLB ミス・保護違反は SIGSEGV シグナルで通知 Memory Load/Store mmap CPU Interpreter/proc/oleolevm oleolevm SIGSEGV ioctol or syscall 5
  6. 6. どのように改造するか?• Hugetlb を参考に (`・ω・´)• vm_area_structのvm_flagsを勝手に追加 – /include/linux/mm.h #define VM_HUGETLB 0x00400000 #define VM_OLEOLETLB 0x100000000UL• VM_HUGETLBとis_vm_hugetlb_pageを手掛 かりに追加 if (is_vm_hugetlb_page(vma)) return copy_hugetlb_page_range(dst_mm, src_mm, vma); if (is_vm_oleoletlb_page(vma)) return -ENOMEM; 6
  7. 7. Shadow Page Table(SPT) • ゲストの仮想メモリ空間をホストのページテーブルに 組み込む。 CR3 oleolevm 0x3,000,000 Guest Virt Space PGD Page 512GB 0x2,000,000 PUD 空き4GB 1GB写像 0x1,000,000 PMD Guest Phy Space 2MB Page PTEgCR3 ST PT 4KB 0x0,000,000 Page 7
  8. 8. サンプルはここまでで力尽きま した 8
  9. 9. ゲストCR3を切り替え対応 • ゲストのコンテキストスイッチに応じてSPTの書き換 えが必要 • 毎回破棄するとコスト高なので過去のSPTも保存 – PUDをゲスト仮想空間1つに割り当てると効率がイイ!! CR3 PGD PMD PMD PMD PMD CR3が変更され たら入れ替え PUD PTE PTE PTE PTE 1GB PMD PMD PMD PMDPMD PMD PMD PMD PTE PTE PTE PTEPTE PTE PTE PTE 9
  10. 10. ゲストモード対応• ゲストにもuser modeとsupervisor modeがあり アクセス禁止領域が違う• User mode用とsupervisor mode用の空間を分 けてしまえば解決 Guest Virt Space (Supervisor) 空き CPU Interpreter Guest Virt Space (User) 空き Guest Phy Space 10
  11. 11. JITコンパイラ対応• 高速化のためのJIT Compilation – Dynamic Binary Translationとも言う• 分岐回数テーブル – 普通はハッシュテーブル Branch Counter Table – オレオレVMならMMUで用意• 翻訳コードへのlookup table Page カウン タ – これもMMUで用意できる• 翻訳元コードの書込み保護 空き – 書込み保護違反時にカーネル側 Guest Virt Space で翻訳コードの破棄が可能 Page 命令 11
  12. 12. ゲストデバッグ機能対応• Watchpoint Debug – 指定したメモリ範囲にアクセスがあったことを検 出• 問題 – アクセスの補足方法 • x86のdebug registerはエミュは使い辛い • ゲストのwatchpoint範囲をカバーするようにSPTのペー ジにプロテクションを付ける – アドレスの判定 – Watchpointに引っかかったx86命令の再実行方法 12
  13. 13. アドレス判定• #PF例外はCR2に例外を起こしたメモリアドレ スを返すが不正確 – movq %rax, [0x0FFE] で #PF がでてもCR2は0x1000に なるかも。• x86命令をデコードしてアドレスを判定 – struct pt_regsに#PFが起きた時点のレジスタが格納 されている – %ripから16バイトを読み込んで命令をデコード – でもオペコードレベルで400命令以上のデコード が必要 (´;ω;`) 13
  14. 14. 再実行• ゲストのLOAD/STOREは#PF例外補足後に再実 行できないとダメ – でもSPTにプロテクションをかけているよ• x86を1命令エミュレーション – #PFを起こしたx86命令をカーネルランドで1命令 エミュし、pt_regsに結果を書き戻す。%ripも1命 令分続ける。• x86のSingle Step実行を使う 1. #PFハンドラでSPTのプロテクションを解除し、 EFLAGSにTFを立ててユーザランドに戻る 2. 1命令を実行したら#DB例外が発生 3. SPTのプロテクションを元に戻す 14
  15. 15. まとめ• オレオレVMを使えばx86-64のMMUを全部 使える (`・ω・´)• でもカーネルのリベースが大変 (´;ω;`)• なにかうまい手はありませんか? 15
  16. 16. 参考文献• Jim Smith, Ravi Nair, Virtual Machines: Versatile Platforms for Systems and Processes 16
  17. 17. 清聴ありがとうございまし た。 17
  18. 18. ここから未使用 18
  19. 19. 予約領域を使う• x86/x86-64は#PF例外の種類が少ない• #PF例外時のエラーコード – Present bit – W/R bit – U/S bit• そうだ!! 予約領域を使おう – RSVD 19
  20. 20. SPTの一貫性(1/2)• ゲストのページテーブルとSPTの一貫性の維 持するには? 1. ゲストのページテーブル領域に書込み保護をか ける 2. 毎回SPTを破棄 3. 毎回SPTをゲストのページテーブルとチェック• x86-64の予約領域を使ってSPTのチェックを 遅延させる方法があるよ – 特許4897578「仮想計算機の制御プログラムおよ び仮想計算機システム」服部 直也ほか 20
  21. 21. SPTの一貫性(2/2)• 予約領域へビットを打った場合「SPTを チェックしろ」という意味• RSVD=1の#PF例外をハンドルして検査• 最初はPGDのreserved bitを打つ。• #PF例外があがるとPGDのreserved bitを解除し て直下のPUDの512エントリにresreved bitを打 つ。• 中位のエントリのreserved bitを下位のテーブ ルに写してゆく。• 最後のPTEのreserved bitを解除する時にゲス トPTEとチェックを行う 21
  22. 22. 改造なしで独自メモリ管理• vm_area_structにvm_opsを設定 static int foo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { vmf->page = page; // ここにロジックを入れる } static struct vm_operations_struct foo_vm_ops = { .fault = foo_vm_fault, }; static int foo_mmap(struct file *filp, struct vm_area_struct *vma) { vma->vm_ops = &foo_vm_ops; } static struct file_operations foo_fops = { .mmap = foo_mmap, }; 22
  23. 23. X86-64の仮想メモリは将来拡張さ れるか?• U.S. Patent 6,671,791 Processor including a translation unit for selectively translating virtual addresses of different sizes using a plurality of paging tables and mapping mechanisms 23

×