內存虛擬化之影子頁表


概述

對於客戶機操作系統來說,存在兩種常用的虛擬化方法,即full-virtualization(完全虛擬化)、para-virtualization(並行虛擬化)。由於本文討論影子頁表,因此只針對內存進行考慮,影子頁表是完全虛擬化的做法,所謂完全虛擬化,是指客戶機操作系統不感知自身處於虛擬環境,因此不需要修改客戶機操作系統源碼。對於虛擬化環境來說,存在四種地址,GVA(Guest virtual address,客戶機虛擬地址)、GPA(Guest physical address,客戶機物理地址)、HVA(Host virtual address,宿主機虛擬地址)、HPA(Host physical address,宿主機物理地址)。對於客戶機應用程序來說,它想訪問一個具體的物理地址需要兩級頁表轉換,即GVA到GPA和GPA到HPA,本文暫不考慮宿主機應用程序,因此忽略HVA。
當硬件不提供支持內存虛擬化(例如EPT)的擴展時,硬件只有一個頁表基址寄存器(例如x86下的CR3或者ARM的TTBR寄存器組),硬件無法感知此時是做GVA到GPA的轉換還是GPA到HPA的轉換,事實上,硬件只能完成一級頁表轉換,因此影子頁表的本意是在VMM中創建一個客戶機頁表的影子頁表,能夠一步完成從GVA到HPA的轉換,如下圖所示,展示了這一過程。

影子頁表的做法

首先,明確幾個相關概念,以Linux 32位為例,尋址時需要32的地址號,我們知道這32位可以分為3個部分,最后12位是頁偏移量,中間10位稱為PT(Page Table,頁表),最前面的10位稱為PD(Page Descriptor,頁目錄)。在尋址時,首先根據前20位找到對應的物理頁,在根據最后12位的偏移量找到具體內容,因此一般把前20位稱為物理頁幀號,引入影子頁表后,就會引入三種物理頁幀號,分別是GFN(Guest Frane Number,客戶機頁幀號),MFN(Machine Frane Number,機器物理頁幀號)和SMFN(Shadow Machine Frane Number,影子宿主機物理頁幀號),事實上,當我們得到一個GFN的時候,我們更希望得到這個GFN對應的SMFN,這就是影子頁表性能很差的原因之一,需要做一個GFN到SMFN的轉換,為了提升這部分性能,目前只要是通過hash的方式來做這個轉換,在轉換時還要根據影子頁表的類型(主要是當前頁表位於第幾級,記為type),上述過程可以記為SMFN=hash(GFN,type),其實這里GFN和MFN是一樣的,因此也可以記為SMFN=hash(MFN,type)。
客戶機操作系統的頁表不是靜態的,在運行時需要修改客戶機操作系統的頁表,而客戶機頁表的修改需要同時修改VMM中對應的影子頁表,因此客戶機頁表的修改需要被VMM截獲,為了達到每次客戶機頁表的修改都可以通知VMM,將客戶機頁表設置為只讀權限,因此每次修改時都會產生page fault,進入到VMM中,由VMM代替客戶機操作系統修改其頁表,然后更新自身的影子頁表中GVA到HPA的映射關系。這就是影子頁表性能很差的原因之二,因為每次修改的開銷相比如非虛擬化環境有很多額外操作。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM