• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
x86-64/Linuxに独自メモリ空間を勝手増設
 

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

on

  • 536 views

 

Statistics

Views

Total Views
536
Views on SlideShare
535
Embed Views
1

Actions

Likes
0
Downloads
4
Comments
0

1 Embed 1

http://s.deeeki.com 1

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

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

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

    • 第七回 カーネル/VM探検隊発表x86-64/Linuxに独自メモリ空間を勝手増設 中村 実 nminoru1975@gmail.com Twitter @nminoru_jp http://www.nminoru.jp/~nminoru/ 1
    • 自己紹介• 某電機メーカーのサラリーマンです。• 01~05 Java VM• 06~10 メインフレームのソフトエミュ レータ• 11 ファイルシステム 2
    • エミュレータを高速化するに は?• ゲストとホストでCPUが異なる計算機を想 定 – ARM、MIPS、SPARC、Alphaをx86-64上で実行• ゲストの仮想メモリがネック – ソフトウェアでエミュレーションすると絶対 的に遅い – ホストのMMUを使ってゲストのメモリ空間を エミュレーションしましょう。 3
    • ホストMMUをどうやって使う か?• どうすればいい? 1. OSを自前で作る 2. OSから一部のCPUを切り離して独自処理 3. 既存のOSを改造 このLTではx86-64/Linux上で32ビットCPUを エミュレーションする勝手改造を紹介しま す 4
    • オレオレ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
    • どのように改造するか?• 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
    • 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
    • ゲスト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
    • ゲストモード対応• ゲストにもuser modeとsupervisor modeがあり アクセス禁止領域が違う• User mode用とsupervisor mode用の空間を分 けてしまえば解決 Guest Virt Space (Supervisor) 空き CPU Interpreter Guest Virt Space (User) 空き Guest Phy Space 10
    • JITコンパイラ対応• 高速化のためのJIT Compilation – Dynamic Binary Translationとも言う• 分岐回数テーブル – 普通はハッシュテーブル Branch Counter Table – オレオレVMならMMUで用意• 翻訳コードへのlookup table Page カウン タ – これもMMUで用意できる• 翻訳元コードの書込み保護 空き – 書込み保護違反時にカーネル側 Guest Virt Space で翻訳コードの破棄が可能 Page 命令 11
    • ゲストデバッグ機能対応• Watchpoint Debug – 指定したメモリ範囲にアクセスがあったことを検 出• 問題 – アクセスの補足方法 • x86のdebug registerはエミュは使い辛い • ゲストのwatchpoint範囲をカバーするようにSPTのペー ジにプロテクションを付ける – アドレスの判定 – Watchpointに引っかかったx86命令の再実行方法 12
    • アドレス判定• #PF例外はCR2に例外を起こしたメモリアドレ スを返すが不正確 – movq %rax, [0x0FFE] で #PF がでてもCR2は0x1000に なるかも。• x86命令をデコードしてアドレスを判定 – struct pt_regsに#PFが起きた時点のレジスタが格納 されている – %ripから16バイトを読み込んで命令をデコード – でもオペコードレベルで400命令以上のデコード が必要 (´;ω;`) 13
    • 再実行• ゲストの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
    • まとめ• オレオレVMを使えばx86-64のMMUを全部 使える (`・ω・´)• でもカーネルのリベースが大変 (´;ω;`)• なにかうまい手はありませんか? 15
    • 参考文献• Jim Smith, Ravi Nair, Virtual Machines: Versatile Platforms for Systems and Processes 16
    • 清聴ありがとうございまし た。 17
    • ここから未使用 18
    • 予約領域を使う• x86/x86-64は#PF例外の種類が少ない• #PF例外時のエラーコード – Present bit – W/R bit – U/S bit• そうだ!! 予約領域を使おう – RSVD 19
    • SPTの一貫性(1/2)• ゲストのページテーブルとSPTの一貫性の維 持するには? 1. ゲストのページテーブル領域に書込み保護をか ける 2. 毎回SPTを破棄 3. 毎回SPTをゲストのページテーブルとチェック• x86-64の予約領域を使ってSPTのチェックを 遅延させる方法があるよ – 特許4897578「仮想計算機の制御プログラムおよ び仮想計算機システム」服部 直也ほか 20
    • 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
    • 改造なしで独自メモリ管理• 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
    • 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