1. 程式人生 > >KVM原理與架構系列之四 記憶體虛擬化篇

KVM原理與架構系列之四 記憶體虛擬化篇

記憶體虛擬化

1. 客戶機實體地址空間

在物理機上,虛擬地址通過Guest頁表即可轉換為實體地址。但是在虛擬化環境中,由於VMMVM都需要獨立的地址空間,則產生了衝突。

為實現記憶體虛擬化,讓客戶機使用一個隔離的、從零開始且具有連續的記憶體空間,KVM 引入一層新的地址空間,即客戶機實體地址空間 (Guest Physical Address, GPA),該地址空間並不是真正的實體地址空間,它只是宿主機(Host主機)虛擬地址空間在Guest地址空間的一個對映。

Guest來說,客戶機實體地址空間都是從零開始的連續地址空間,但對於宿主機來說,客戶機的實體地址空間並不一定是連續的,客戶機實體地址空間有可能對映在若干個不連續的宿主機地址區間,如下圖所示:


由於物理MMU只能通過Host機的實體地址(Host Physical Address, HPA)進行定址,所以實現記憶體虛擬化,關鍵是需要將Guest機的虛擬地址(Guest Virtual Address, GVA)轉換為HPA。傳統的實現方案中,這個過程需要經歷:GVAàGPAàHVAàHPA的轉換過程,需要對地址進行多次轉換,而且需要KVM的介入,效率非常低。為提供GVAHPA的地址轉換效率,KVM提供了兩種地址轉換方式:

1、影子頁表(Shadow Page Table),是純軟體的實現方式

2、基於硬體特性的地址轉換。如基於Intel EPT(Extended Page Table
,擴充套件頁表),或AMD NPT(Nested Page Table,巢狀頁表)

2. 影子頁表

2.1 基本原理

由於記憶體虛擬化在將GVA轉換為HPA的過程中,需要經歷多次轉換,無法直接使用Guest機頁表和CR3。使用影子頁表(Shadow Page Table)可以實現客戶機虛擬地址(GVA)到宿主機實體地址(HPA)的直接轉換,與傳統方式的轉換過程對比如下:


      影子頁表中記錄的是GVAHPA的對應關係,每個頁表項指向的都是宿主機的實體地址。由於客戶機中每個程序都有自己的虛擬地址空間,所以 KVM 需要為客戶機中的每個程序頁表都要維護一套相應的影子頁表。

Guest機訪問記憶體時,VMM在物理MMU中載入的是Guest機當前頁表所對應的影子頁表,從而實現GVAHPA的直接轉換。

 Guest機中的每一個頁表項都有一個影子頁表項與之相對應。為了快速檢索Guest機頁表所對應的的影子頁表,KVM 為每個客戶機都維護了一個雜湊表,影子頁表和Guest機頁表通過此雜湊表進行對映,基本原理如下:

對於每一個Guest機來說,Guest機的頁目錄/頁表都有唯一的GPA,通過頁目錄/頁表的GPA就可以在雜湊連結串列中快速地找到對應的影子頁目錄/頁表。在檢索雜湊表時,KVM Guest頁目錄/頁表的客戶機實體地址低10位作為鍵值進行索引,根據其鍵值定位到對應的連結串列,然後遍歷此連結串列找到對應的影子頁目錄/頁表。當然,如果沒有找到對應的影子頁目錄/頁表,則說明影子頁表項和Guest頁表項的對應關係還沒有建立 ,此時KVM 會為其分配新的物理頁,並建立起Guest頁目錄/頁表和對應的影子頁目錄/頁表之間的對映。

         

2.2 影子頁表的建立與更新

影子頁表的建立和更新過程交織在一起,影子頁表的建立和更新主要發生在如下3中情況下:

1.Guest OS修改Guest CR3暫存器。由於相關指令為敏感指令,所以相關操作會被VMM截獲,此時VMM會根據相關情況進行影子頁表的維護。比如,當客戶機切換程序時,客戶機作業系統會把待切換程序的頁表基址載入 CR3,而該特權指令將被VMM截獲,進行新的處理,即在雜湊表中找到與此頁表基址對應的影子頁表基址,載入客戶機 CR3,使客戶機在恢復執行時 CR3 實際指向的是新切換程序對應的影子頁表。

2.Guest機頁表和影子頁表不一致而觸發的缺頁異常,此時也會VM-ExitVMM,進而可進行相關維護操作。

3.Guest OS中執行INVLPG指令重新整理TLB時,由於INVLPG指令為敏感指令,所以該操作也會被VMM進行截獲,並進行影子頁表相關維護操作。

其中,第2中情況發生機率最高,相關處理也最複雜。如下做重點描述。不同的缺頁異常,處理方式不用,常見的缺頁異常包括如下3類:

1.影子頁表初始化時產生的缺頁異常。在虛擬機器執行之初,VMM中與Guest機頁表對應的影子頁表都沒有建立,而物理CR3中載入的卻是影子頁目錄地址,所以,此時任何的記憶體操作都會引發異常,如果此時Guest機的相應頁表已經建立,那麼處理這種異常即是建立相應的影子頁表即可;如果Guest機的頁表項尚未建立,那就是Guest機自身的缺頁異常,即為如下的第2中情況。

2.Guest機上的缺頁異常。如果Guest OS尚未給這個GVA分配Guest機物理頁,即相應的Guest機頁表項尚未建立,此時將引發缺頁異常。另外,當Guest機訪問的Guest頁表項存在位(Present Bit)0,或相關訪問許可權不匹配時,也將引發缺頁異常。

3.VMMHost機物理頁換出到硬碟上時引發的缺頁異常。

影子頁表缺頁異常的預設處理流程:

         

VMM截獲缺頁異常(VM-Exit),並檢查此異常是否由Guest即自身引發,如果是,則將直接返回Guest OS(Vm-Entry),然後由Guest OS自身的page fault流程處理;如果不是,則為影子頁表和Guest機頁表不一致導致,這樣的異常也叫“影子缺頁異常”,此時,VMM會根據Guest機頁表同步影子頁表,過程如下:

1.VMM根據Guest機頁表項建立影子頁目錄和頁表結構

2. VMM根據發生缺頁異常的GVA,在Guest機頁表的相應表項中得到對應的GPA

3.VMM根據GPA,在GPAHPA的對映表中(通過之前描述的HASH表建立),得到相應的HPA,再將HPA填入到影子頁表的相應表項中。

影子頁表和Guest機頁表不是時刻同步的,只有在需要時才進行通過,從某種角度看,影子頁表可以看做是Guest頁表的TLB,常稱為虛擬TLB(VTLB)

影子頁表解決了傳統IA32架構下的記憶體虛擬化問題,由於影子頁表可被載入物理 MMU 為客戶機直接定址使用, 所以客戶機的大多數記憶體訪問都可以在沒有KVM 介入的情況下正常執行,沒有額外的地址轉換開銷,也就大大提高了客戶機執行的效率。但也有比較明顯的缺點:

1.實現複雜。影子頁表同步需要考慮各種情況。

2.記憶體開銷大。需要為每個Guest機程序維護一個影子頁表。

3. EPT 頁表

3.1 基本原理

 為解決影子頁表的問題,IntelAMD都提供了相應的硬體技術,直接在硬體上支援GPAHPA的轉換,從而大大降低了記憶體虛擬化的難度,並提升了相關效能。本文主要描述Intel EPT技術。

 EPT 技術在原有Guest機頁表對GVAGPA轉換的基礎上,又引入了 EPT 頁表來實現GPAHPA轉換,這兩次地址轉換都是由硬體自動完成,可高效的實現地址轉換。Guest執行時,Guest頁表被載入 CR3,而 EPT 頁表被載入專門的 EPT 頁表指標暫存器 EPTPGVAHPA的具體轉換過程如下(以經典的2級頁表為例)
         

完整的地址翻譯流程描述為:

1. Guest OS載入Guest程序的gCR3gCR3中存放的是Guest程序頁目錄表的GPA

2. 處於非根模式的CPUMMU查詢硬體EPT TLB,如果有所請求的GPAHPA的對映,則使用其對應的HPA作為Guest頁目錄表的基址。

3. 如沒有所請求的GPAHPA的對映,則查詢EPT,獲得gCR3所對映的HPA,並將其作為Guest頁目錄表的基址。

4. 根據GVA獲得頁目錄偏移(圖中的Dir Offset),獲得用於索引Guest頁表的基址,該地址為GPA

5. 再由VCPUMMU查詢硬體EPT TLB,如果有所請求的GPAHPA的對映,則使用其對應的HPA作為Guest頁表的基址。

6. 如沒有所請求的GPAHPA的對映,則查詢EPT,將其轉換為HPA,使用該HPA再加上GVA中的頁表偏移(圖中的Table Offset),即可得到PTE(頁表項)GPA

7. 再由VCPUMMU查詢硬體EPT TLB,如果有所請求的GPAHPA的對映,則其對應的HPA加上GVA中的Offset即為最終的宿主機實體地址(HPA)

8. 如沒有所請求的GPAHPA的對映,則查詢EPT,將其轉換為HPA,使用該HPA加上GVA中的Offset即為最終的宿主機實體地址(HPA)

 EPT頁表實現GPAHPA的轉換的原理,與Guest頁表實現GVAGPA的轉換原理相同,需要經歷多級頁表的查詢,圖中沒有詳細畫出。假設Guest機有m級頁表,宿主機EPTn級,在TLBmiss的最壞情況下,會產生m*n次記憶體訪問,完成一次客戶機的地址翻譯,EPT硬體通過增大硬體EPT TLB來儘量減少記憶體訪問。

3.2 EPT缺頁異常處理

GPAHPA轉換的過程中,由於缺頁、寫許可權不足等原因也會導致客戶機退出,產生 EPT 異常。對於 EPT 缺頁異常,處理過程大致如下:

1.KVM 首先根據引起異常的GHA,對映到對應的HVA

2. 然後為此虛擬地址分配新的物理頁;

3.最後 KVM 再更新 EPT 頁表,建立起引起異常的GPAHPA的對映。

EPT 頁表相對於影子頁表,其實現方式大大簡化,主要地址轉換工作都由硬體自動完成,而且Guest內部的缺頁異常也不會導致VM-Exit,因此Guest執行效能更好,開銷更小。

本文非原創,尊重他人勞動成果,轉載自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=14528823&id=4203732