[hellogcc] Re: [投稿] QEMU Internal - Precise Exception Handling 2/5

  • From: 陳韋任 <chenwj@xxxxxxxxxxxxxx>
  • To: hellogcc@xxxxxxxxxxxxx
  • Date: Fri, 9 Mar 2012 19:58:35 +0800

> 可以得知,我們在呼叫 __stb_mmu 的時候發生例外。__{ld,st}{b,w,l,q}_{cmmu,mmu} 是用來存取
> guest 內存的 helper function。它們首先會查找 TLB (env1->tlb_table) 試圖取得
> guest virtual address 相對映的 host virtual address。如果 TLB 命中,可直接利用
> 該 host virtual address 存取 guest 內存內容。如果 TLB 不命中,則會呼叫 tlb_fill
> (target-i386/op_helper.c)。tlb_fill 會呼叫 cpu_x86_handle_mmu_fault 查找客戶頁表。
> 如果命中,代表該 guest virtual address 所在的頁已存在,tlb_fill 會將該頁項目
> 填入 TLB 以便後續查找。如果不命中,代表發生頁缺失,QEMU 會回復 guest CPUState,
> 並拉起 guest exception index (env->exception_index) 通知 guest 頁缺失發生。最後
> 交由 guest 頁缺失 handler 將該頁載入。
> 
  我先給出一個 precise exception handling 的大致流程,之後再透過閱讀代碼有更深的
體會。底下給出關鍵的資料結構 TranslationBlock,它負責掌管 guest binary 和 host
binary 的關係,其中 pc 代表此 basic block 起始的 guest pc,tc_ptr 指向翻譯好的
host binary 在 code cache 中的位址。

                                                                     code cache 
          guest binary                   TranslationBlock           (host 
binary)

0x0000e4c0:  sub    $0x4,%esp       <--  pc (2)
0x0000e4c3:  mov    0x8(%esp),%eax
0x0000e4c7:  mov    %al,(%esp)                     tc_ptr  -->  0x40bbeff0:  
mov 0x10(%r14),%ebp
0x0000e4ca:  movzbl (%esp),%eax                                 0x40bbeff4:  
sub $0x4,%ebp
0x0000e4ce:  mov    0xc(%esp),%edx
0x0000e4d2:  mov    %al,%fs:(%edx)                                      ... 略 
...
0x0000e4d5:  add    $0x4,%esp
0x0000e4d8:  ret                                                0x4011813b: 
callq  0x54d38a 
                                               (3) offset  -->  0x40118140: mov 
   0x10(%r14),%ebp (1)

                                                                        ... 略 
...

當 QEMU 發現例外是發生在 code cache 裡,這代表需要處理 precise exception。首先,
QEMU 會透過 host pc (0x4011813f) 查出相對應的 TranslationBlock - (1)。接下來,
QEMU 會回復 guest CPUState。主要概念是這樣,透過之前查找到的 TranslationBlock
的 pc,我們從該 pc 所指的 guest binary 重新再翻譯一次,同時產生額外的資訊以便回
復 guest CPUState - (2)。那要如何得知我們已經翻譯到發生 exception 的 guest
binary? 這裡的重點在於,我們將產生的 host binary 寫在 tc_ptr 所指位址,也就是
把原來的 host binary 覆寫掉。另外,QEMU 會先記錄一個 offset,它是發生例外的
host pc 與原本 tb_ptr 之間的距離。我們會觀察 offset 是否落在原本 tc_ptr 和目前
tc_ptr 之間,如果是的話,這代表我們已經翻譯到發生 exception 的 guest binary。
我們便可以回復 guest CPUState - (3)。

接下來各小節的主題分別是:

  * Precise Exception Handling 3/5 - (1)
 
  * Precise Exception Handling 4/5 - (2) (3)

  * Precise Exception Handling 5/5 - 驗證我們對 QEMU 的理解。

> 接下來,我們來看代碼。;)

-- 
Wei-Ren Chen (陳韋任)
Computer Systems Lab, Institute of Information Science,
Academia Sinica, Taiwan (R.O.C.)
Tel:886-2-2788-3799 #1667
Homepage: http://people.cs.nctu.edu.tw/~chenwj

Other related posts: