內存虛擬化硬件基礎——EPT

前言

  • EPT(Extended Page Table)是Intel爲實現內存虛擬化專門增加的硬件特性。
  • 實現內存虛擬化,主要解決的問題是,當CPU運行在VMX非根模式下,它對所有物理內存的讀寫,需要通過VMM的模擬來實現的。
  • 非根模式下的CPU,仍然要支持實模式,保護模式,保護模式下的三種分頁模式以及各種地址轉換的表,比如頁目錄指針表(PDPT),頁目錄表(PD),頁表(PT)等等。當涉及到物理內存的讀寫時,如果是根模式就直接讀寫,但這裏是非根模式,它是要模擬一個CPU,所有對於主機上資源的訪問都要被監控或者被模擬,包括物理內存。因此傳統的設計思路是非根模式下CPU對物理內存的訪問被認定爲敏感指令,會退回到根模式交給VMM處理,VMM負責將這段物理內存轉化成主機上真實的物理內存然後返還給虛機CPU使用。
  • 傳統的設計思路有兩個問題:一是非根模式下的CPU訪問物理內存很頻繁,會頻繁的觸發CPU模式切換,開銷非常大;二是退回到根模式後,VMM對客戶機物理地址的模擬要經過GPA -> HVA -> HPA三個階段的地址轉換,軟件實現效率低。
  • 影子頁表解決了第二個問題,它的出發點是減少地址轉換。基本原理是:當處於非根模式下的CPU有修改CR3的動作時(通常是下一個進程被調度的時候),意味着有頁目錄地址會被加載到CR3(如果是32-bit分頁模式),這時VMM截獲這個動作,退回到根模式,VMM中維護了一個hash鏈表,專用於存放CR3中頁目錄地址對應的影子地址,VMM拿到頁目錄地址後計算該地址的hash值並作爲key放到hash表中,然後申請一個主機上的物理地址作爲頁目錄的地址放到CR3寄存器中,同時主機上的物理地址也被存放到hash表中,CR3原有的應該被保存的頁目錄地址被VMM保存起來,當虛擬機進程被調度出去的時候,CR3中應該被保存的頁目錄地址要放回到進程控制塊中,這時VMM會截獲這個動作並提供之前保存的頁目錄地址。VMM在CR3寄存器被修改的過程中,偷天換日,將本應該放到CR3中的地址拿走,替換成自己申請的地址,當客戶機要從CR3中取回這個地址時替換回去。影子頁表的示意圖如下,由於每個進程都有自己的地址空間,因此都有一個CR3的內存值,所以影子頁表的Hash鏈表中,一個Node節點對應存放一個進程的頁目錄地址。
    在這裏插入圖片描述
  • KVM通過監聽CR3寄存器讀寫,爲每一個在VMX模式下使用CR3加載頁表的進程,在主機上維護了對應的頁目錄和頁表(注意,影子頁表的說法並不準確,因爲主機上除了頁表,還維護了頁目錄,這些都是影子)。CR3指向的是進程的一個內存地址空間,所以主機需要爲VMX模式下的所有進程,都維護這樣一份影子頁目錄和影子頁表,放在hash表中,當進程被調度,頁表被加載時,從hash表中找到對應的影子頁目錄的地址放到CR3中。影子頁表通過增加內存維護成本,減少地址轉換的路徑。有一定效果,但每個進程的頁表和頁目錄的維護成本也不小,因此進一步引入了EPT機制
  • EPT克服了影子頁表使用軟件維護GVA->HPA地址轉換的缺點,它使用硬件來維護GPA->HPA,因此效率大大提高。而且,影子頁表雖然縮短了地址轉換路徑,但每次虛機進程訪問CR3時,都會引起VMX的模式切換,開銷很大。影子頁表在每次加載和卸載的時候都會引起模式切換,而EPT減少了這種開銷,EPT只在缺頁的時候才引起VMX模式切換,一旦頁表建立好之後,EPT就不再有模式切換的開銷,虛機內存的訪問一直在客戶態。

EPT轉換開關

  • EPT是Intel爲支持虛擬化的開發的硬件特性,因此使能開關應該在虛擬化相關的域中,secondary processor-based VM-execution contro是VM-execution的一個控制字段,它位於VMCS(Virtual Machine Control State)中,它是一個32bit的字段,其中一個bit就是EPT使能位。

EPT轉換時機

  • EPT使能之後,客戶態模式下所有物理地址都被識別成guest-physical address,CPU對這些地址的訪問需要通過EPT轉換成主機上的物理地址。EPT地址轉換時機就是CPU訪問GPA的時侯。爲了讓客戶機的程序感覺不到自己處於客戶態,EPT需要支持實模式,保護模式和保護模式下所有的分頁模式,所有這些模式下對物理地址的訪問,都要觸發GPA地址轉換。實模式下,進程的所有線性地址都是GPA;保護模式下,進程頁表的物理地址,頁目錄地址,頁表地址,這些都是GPA。
  • 以保護模式下32-bit分頁模式爲例(CR0.PG = 1)爲例,介紹客戶態模式下物理頁查詢過程中的地址轉換,假設MMU的輸入是一個32bit的進程線性地址:
  1. MMU首先從CR3中取出頁目錄地址,訪問該頁目錄的內容,此時頁目錄地址被認爲是GPA,會觸發EPT頁表的查詢,返回的HPA指向頁目錄。MMU取32-bit線性地址的高10位作爲索引,在頁目錄中查找並獲取頁表地址
  2. MMU拿到頁表地址後,訪問該頁表內容,此地址也被認爲是GPA,會觸發EPT頁表查詢,返回一個HPA指向頁表。MMU取32-bit線性地址的中間10位作爲索引,在頁表中查找對應的條目,獲取物理頁地址
  3. MMU拿到物理頁地址後,訪問該頁內的偏移,再次觸發EPT頁表查詢,返回HPA指向主機的物理頁。MMU取32-bit線性地址的最低12位作爲偏移,讀寫物理頁的內容。
    注意,EPT轉換隻有在客戶態真正訪問GPA內容時才發生。MMU單單獲取GPA時不會觸發地址轉換。

EPT轉換原理

EPT頁結構

  • Intel處理器設計了EPT的頁結構用來將保存GPA到HPA的映射,因此說EPT是硬件支持的,EPT的頁結構如下圖的咖啡色部分,整個頁結構有4級,和4-level分頁模式的結構一模一樣,只有存放PML4 Table物理地址的地方不一樣,4-level將PML4 Table的地址存放在CR3寄存器中;EPT沒有,EPT中PML4 Table的地址被稱爲EPTP,它存放在VMCS中的VM-execution 控制字段。VMM用VMCS來配置VM的運行環境以及控制VM的運行。進入客戶態之前,VMM首先通過特殊指令VMPTRLD加載VMCS內存地址的指針,其中就包括EPTP字段,因此理論上EPTP是針對每個虛機而言的,EPT對每個虛機是可以配置的。有人會問,客戶態的所有物理地址都是GPA,那麼存放EPT物理地址的EPTP是什麼地址呢?個人理解,這個地址不是GPA,它非常特殊,因爲它是在未進入客戶態之前由VMM加載的,不可能是GPA,應該是主機上的地址HPA。
    在這裏插入圖片描述

EPT地址轉換

  • EPT地址轉換的輸入有兩個,一個是客戶機的物理地址GPA(Guest Physical Address),一個是PML4 Table的物理地址,指向了EPT的頁結構。當運行在客戶態下的CPU訪問CR3指向的頁結構時,如果涉及到對物理內存的內容的訪問,就會觸發EPT地址轉換,Intel硬件接管這個任務,完成轉換,步驟如下:
  1. 根據VMCS中的EPTP字段找到頁結構的起始地址:PML4 Table的地址,加載對應的PML4 Table內容,PML4 Table中由512個條目,將GPA的高9位作爲索引,在PML4 Table中索引PDPT(Page Directory Pointer Table)的地址。
  2. 根據PDPT地址加載PDPT內容,也是512個條目,將GPA的次9位作爲索引,在PDPT中索引PDT(Page Directory Table)的地址。
  3. 根據PDT地址加載PDT內容,同樣是512個條目,將GPA從高到低的第3個9位作爲索引,在PDT中索引頁表的地址。
  4. 根據頁表的地址加載其內容,同樣是512個條目,將GPA從高到底的第4個9位作爲索引,在頁表中找到頁的地址。
  5. 根據頁地址,加載頁的內容,將GPA的低12位作爲索引,在頁中找到最終要訪問的頁的內容。
  • 對EPT頁結構中的訪問出錯可能導致頁故障從而引發VM-exit,分下面兩種情況:
  1. EPT violation,這種情況典型場景就是頁結構不存在,類似於主機上的缺頁故障(#PF Page Fault),發生這種故障後CPU會退回到內核態,同時會在VM-exit qualification字段記錄EPT violation故障的詳細信息。EPT頁結構和主機上普通的頁結構類似,頁表都是故障觸發,逐漸填充頁結構的過程。在客戶態模式下,這是EPT violation故障;在主機上,這就是缺頁故障。怎樣判斷頁結構不存在呢?通過查看每個描述頁結構條目的低3位(read/write/execute),如果低3位全都爲0,就表示指向的下一級頁結構不存在(not-present)。這是非頁表的情況,如果是頁表(Page Table),它的條目的最低位是Present位,可以單獨用來表示指向的頁是否存在。
  2. EPT misconfiguration,另一種會導致頁故障的情況,它是在頁結構存在的情況下(頁結構低3位的任何一位非0),發現頁結構的內容設置不恰當而產生的故障,這種情況是EPT的頁結構真的出了配置上的問題而產生的故障,對於EPT misconfiguration,並不會記錄詳細信息。VM-exit qualification字段爲未定義值。
    注意,故障不同於異常,硬件故障後會跳轉到相應的處理例程,在處理完之後會重新運行出故障時的指令而非下一條,EPT violation和主機頁表中的Page Fault一樣,都屬於故障。對於使用EPT頁表或者主機頁表的用戶程序來說,當訪問到不存在的頁結構觸發了故障後,硬件會處理然後重新執行,用戶程序是感覺不到的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章