官术网_书友最值得收藏!

2.1 通用虛擬化架構

2.1.1 虛擬化的基本概念

現代計算機系統是一個龐大的整體,整個系統的復雜性是不言而喻的。因而,計算機系統被分成自下而上的多個層次。每一個層次都向上一層次呈現一個抽象,并且每一層只需知道下一層抽象的接口,不需要了解其內部運作機制。本質上,虛擬化就是由位于下一層的軟件模塊,通過向上一層軟件模塊提供一個與它原先所期待的運行環境完全一致的接口的方法,抽象出一個虛擬的軟件或硬件接口,使得上層軟件可以直接運行在虛擬的環境上。

首先介紹虛擬化中兩個重要的名詞:宿主和客戶。在虛擬化中,物理資源通常有一個定語,稱為宿主(Host),而虛擬出來的資源通常有一個定語,稱為客戶(Guest)。根據資源的不同,這兩個名詞的后面可以接不同的名詞。例如,如果是將一個物理計算機虛擬為一個或多個虛擬計算機,則這個物理計算機通常被稱為宿主機(Host Machine),而其上運行的虛擬機被稱為客戶機(Guest Machine)。宿主機上如果運行有操作系統,則該操作系統通常被稱為宿主機操作系統(Host OS),而虛擬機中運行的操作系統被稱為客戶機操作系統(Guest OS)。

系統虛擬化是指將一個物理計算機系統虛擬化為一個或多個虛擬計算機系統。每個虛擬計算機系統(簡稱為虛擬機)都擁有自己的虛擬硬件(如CPU、內存和設備等),來提供一個獨立的虛擬機執行環境。通過虛擬化層的模擬,虛擬機中的操作系統認為自己仍然獨占系統硬件在運行。每個虛擬機中的操作系統可以完全不同,并且它們的執行環境是完全獨立的。這個虛擬化層被稱為虛擬機監控器(Virtual Machine Monitor,VMM),如圖2-1所示。

圖2-1 系統虛擬化

從本質上來說,虛擬計算機系統和物理計算機系統可以是兩個完全不同的ISA(指令集架構)的系統。例如,可以在一個x86物理計算機上運行一個安騰的虛擬計算機。但是,不同的ISA使得虛擬機的每一條指令都需要在物理機上模擬執行,從而造成性能上的極大降低。當然,相同體系結構的系統虛擬化通常會使VMM實現起來比較簡單,也有比較好的性能。虛擬機的大部分指令可以在處理器上直接運行,只有那些需要虛擬化的指令才會由VMM進行處理。

1974年,杰拉爾德·J.波佩克(Gerald J. Popek)和羅伯特·P.戈德堡(Robert P. Goldberg)提出可以將虛擬機看作物理機的一種高效隔離的復制。上面的定義蘊涵了三層含義(同質、高效和資源受控),這也是虛擬機所具有的三個典型特征。

●同質,是指虛擬機的運行環境和物理機的運行環境在本質上需要是相同的,但是在表現上可以有一些差異。例如,虛擬機所看到的處理器個數可以和物理機上實際的處理器個數不同,處理器主頻也可以與物理機不同,但是物理機上的處理器和虛擬機中的處理器必須是同一種類型。

●高效,是指虛擬機中運行的軟件需要具備在物理機上直接運行的性能。為了做到這一點,軟件在虛擬機中運行時,大多數的指令要直接在硬件上執行,只有少量指令需要經過VMM處理或模擬。

●資源受控,是指VMM需要對系統資源有完全控制能力和管理權限,包括資源的分配、監控和回收。

2.1.2 虛擬化技術的基本原理

傳統的虛擬化技術一般是通過“陷入再模擬”的方式實現的,而這種方式依賴于處理器的支持。也就是說,處理器本身是否是一個可虛擬化架構決定了虛擬化實現的方式,那么什么是可虛擬化架構(Virtualizable Architecture)呢?

一般來說,虛擬環境由三個部分組成,即硬件、VMM和虛擬機,如圖2-2所示。在沒有虛擬化的情況下,操作系統直接運行在硬件上,管理著底層物理硬件,這就構成了一個完整的計算機系統,也就是所謂的物理機。在虛擬環境里,虛擬機監控器搶占了操作系統的位置,變成了真實物理硬件的管理者,同時向上層的軟件呈現出虛擬的硬件平臺,“欺騙”著上層的操作系統。而此時操作系統運行在虛擬平臺上,仍然管理著它認為是“物理硬件”的虛擬硬件,不知道下面發生了什么,這就是圖2-2中的虛擬機。

圖2-2 虛擬環境的組成

或許硬件體系結構會有所限制,或許VMM的實現方式會有所不同,但如果虛擬機不具備2.1.1節介紹的三個典型特征,那么這個虛擬機是失敗的,VMM的“騙術”是不高明的。

虛擬機的三個典型特征也決定了不是任何系統都是可虛擬化的。給定一個系統,其對應的體系結構是否可虛擬化,要看能否在該系統上虛擬化出具備上述三個典型特征的虛擬機。

為了進一步研究可虛擬化的條件,先從指令開始介紹。大多數的現代計算機體系結構都有兩個或兩個以上的特權級,用來分隔系統軟件和應用軟件。系統中有一些操作和管理關鍵系統資源的指令會被定為特權指令(Privileged Instruction),這些指令只有在最高特權級上才能夠正確執行。如果在非最高特權級上運行特權指令,會引發一個異常,處理器會陷入最高特權級,交由系統軟件來處理。在不同的運行級上,不僅指令的執行效果是不同的,而且也并不是每個特權指令都會引發異常。假如一個x86平臺的用戶違反了規范,在用戶態修改EFLAGS寄存器的中斷開關位,這一修改將不會產生任何效果,也不會引起異常陷入,而是會被硬件直接忽略掉。

在虛擬化世界里,還有一類指令,被稱為敏感指令(Sensitive Instruction),簡言之就是操作特權資源的指令,包括:修改虛擬機的運行模式或者物理機的狀態;讀寫敏感的寄存器或內存,例如時鐘或者中斷寄存器;訪問存儲保護系統、內存系統或地址重定位系統以及所有的I/O指令。

顯而易見,所有的特權指令都是敏感指令,然而并不是所有的敏感指令都是特權指令。

VMM為了完全控制系統資源,它不允許直接執行虛擬機上操作系統(即客戶機操作系統)的敏感指令。也就是說,敏感指令必須在VMM的監控審查下進行,或者經由VMM來完成。如果一個系統上所有敏感指令都是特權指令,則能用一個很簡單的方法來實現虛擬環境:將VMM運行在系統的最高特權級上,而將客戶機操作系統運行在非最高特權級上,當客戶機操作系統因執行敏感指令(此時,也就是特權指令)而陷入VMM時,VMM模擬執行引起異常的敏感指令,這種方法被稱為陷入再模擬。

總而言之,判斷一個架構是否可虛擬化,其核心就在于該架構對敏感指令的支持。如果在某個架構上所有敏感指令都是特權指令,則它是可虛擬化架構;否則,如果它無法支持在所有的敏感指令上觸發異常,則它不是一個可虛擬化架構,我們稱其存在“虛擬化漏洞”。

我們已經知道,通過陷入再模擬敏感指令的執行來實現虛擬機的方法是有前提條件的:所有的敏感指令必須都是特權指令。否則,要么系統的控制信息會被虛擬機修改或訪問,要么VMM會遺漏需要模擬的操作,影響虛擬化的正確性。如果一個架構存在敏感指令不屬于特權指令,那么它就存在虛擬化漏洞。有些計算機架構是存在虛擬化漏洞的,就是說它們不能很高效地支持系統虛擬化。

雖然虛擬化漏洞有可能存在,但是可以用一些方法來填補或避免這些漏洞。最簡單、最直接的方法是,如果所有虛擬化都通過模擬來實現,例如解釋執行,即取一條指令,模擬出這條指令執行的效果,繼續取下一條指令,那么就不存在所謂陷入不陷入的問題,從而避免了虛擬化漏洞。這種方法不但適用于模擬與物理機具有相同體系結構的虛擬機,而且能模擬不同體系結構的虛擬機。雖然這種方法保證了所有指令(包括敏感指令)執行受到VMM的監督審查,但是它不會對每條指令區別對待,其最大的缺點是性能太差,是不符合虛擬機“高效”特點的,導致其性能下降為原來的十分之一甚至幾十分之一。

既要填補虛擬化漏洞,又要保證虛擬化的性能,只能采取一些輔助的手段。可以直接在硬件層面填補虛擬化漏洞,也可以通過軟件的方法避免虛擬機中使用無法陷入的敏感指令。這些方法都不僅保證了敏感指令的執行受到VMM的監督審查,而且保證了非敏感指令可以不經過VMM而直接執行,從而相比解釋執行來說,性能得到了極大的提高。

從以上對可虛擬化架構的分析不難看出,某些處理器在設計之初并沒有充分考慮虛擬化的需求,不具備一個完備的可虛擬化架構。如何填補這些架構上的缺陷直接促成了三種主要虛擬化方式的產生,即基于軟件的完全虛擬化(Full Virtualization)、硬件輔助虛擬化(Hardware Assisted Virtualization)和半虛擬化(Paravirtualization)。不論采取何種虛擬化方式,VMM對物理資源的虛擬可以歸結為三種主要類型:處理器虛擬化、內存虛擬化和I/O虛擬化。

1.處理器虛擬化

處理器虛擬化是VMM中最核心的部分,因為訪問內存或者I/O的指令本身就是敏感指令,所以內存虛擬化與I/O虛擬化都依賴于處理器虛擬化的正確實現。

VMM運行在最高特權級,可以控制物理處理器上的所有關鍵資源;而客戶機操作系統運行在非最高特權級,所以其敏感指令會陷入VMM中通過軟件的方式進行模擬。處理器虛擬化的關鍵在于正確模擬指令的行為。當VMM接管物理處理器后,客戶機操作系統試圖訪問關鍵資源的指令就成為敏感指令,VMM會通過各種手段保證這些敏感指令的執行能夠觸發異常,從而陷入VMM進行模擬,VMM會通過準確模擬物理處理器的行為,而將其訪問定位到與物理寄存器對應的虛擬的寄存器上。虛擬寄存器往往實現為VMM內存中的數據結構。VMM同時負責虛擬處理器的調度和切換,以保證在給定時間內,每個虛擬處理器上的當前進程可以在物理處理器上運行一段時間。但凡切換必然涉及保留現場,這個現場就是上下文狀態。VMM只有保存和恢復好上下文,才能讓虛擬機看起來好像從未被中斷過。既然談及虛擬處理器,那么什么是虛擬處理器呢?虛擬處理器的本質是其需要模擬完成的一組功能集合。虛擬處理器的功能可以由物理處理器和VMM共同完成。對于非敏感指令,物理處理器直接解碼處理其請求,并將相關的效果直接反映到物理寄存器上;而對于敏感指令,VMM負責陷入再模擬,從程序的角度來看就是一組數據結構與相關處理代碼的集合。數據結構用于存儲虛擬寄存器的內容,而相關處理代碼負責按照物理處理器的行為將結果反映到虛擬寄存器上。至此,我們基本了解了處理器虛擬化,其宗旨就是讓虛擬機里執行的敏感指令陷入下來之后能被VMM模擬,而不要直接作用于真實硬件上。

當然,模擬的前提是能夠陷入,VMM陷入利用了處理器的保護機制,并利用中斷和異常來完成,它有以下幾種方式。

●基于處理器保護機制觸發的異常,處理器會在執行敏感指令之前,檢查其執行條件是否滿足,一旦特權級別、運行模式或內存映射(Memory Mapping)關系等條件不滿足,VMM得到陷入然后進行處理。

●虛擬機主動觸發異常,也就是通常所說的陷阱。當條件滿足時,處理器會在觸發陷阱的指令執行完畢后,再拋出一個異常。虛擬機可以通過陷阱指令來主動請求陷入VMM中去。

●異步中斷,包括處理器內部的中斷源和外部的設備中斷源。這些中斷源可以是周期性產生中斷的時間源,也可以是根據設備狀態產生中斷的大多數外設。一旦中斷信號到達處理器,處理器會強行中斷當前指令,然后跳到VMM注冊的中斷服務程序。

中斷和異常機制是處理器提供給系統程序的重要功能,異常保證了系統程序對處理器關鍵資源的絕對控制,而中斷提供了系統程序與外設之間更有效的一種交互方式。所以,VMM在實現處理器虛擬化時,必須正確模擬中斷與異常的行為。

VMM對于異常的虛擬化需要完全遵照物理處理器對于各種異常條件的定義,再根據虛擬處理器當時的內容來判斷是否需要模擬出一個虛擬的異常,并將其注入虛擬環境中。VMM通常會在硬件異常處理程序和指令模擬代碼中進行異常虛擬化的檢查。無論是哪一條路徑,VMM需要區分兩種原因:一是虛擬機自身對運行環境和上下文的設置違背了指令正確執行的條件;二是虛擬機運行在非最高特權級別,由于虛擬化的原因觸發的異常。

虛擬中斷的觸發來自虛擬設備的模擬程序。當設備模擬器發現虛擬設備狀態滿足中斷產生的條件時,會將這個虛擬中斷通知給中斷控制器的模擬程序。然后,VMM會在特定的時候檢測虛擬中斷控制器的狀態,來決定是否模擬一個中斷的注入。這里的虛擬中斷源包括:處理器內部中斷源的模擬、外部虛擬設備的模擬、直接分配給虛擬機使用的真實設備的中斷和自定義的中斷類型。

不管怎樣,當VMM決定向虛擬機注入一個中斷或異常時,它需要嚴格模擬物理處理器的行為來改變客戶指令流的路徑,而且要包括一些必需的上下文保護與恢復。VMM需要首先判斷當前虛擬機的執行環境是否允許接受中斷或異常的注入,假如客戶機操作系統正好禁止了中斷的發生,這時VMM就只能把中斷事件先暫時緩存起來,直到某個時刻客戶機操作系統重新允許了中斷的發生,VMM才立即切入來模擬一個中斷的注入。當中斷事件不能被及時注入時,VMM還要進一步考慮中斷合并、中斷取消、同類型中斷大量阻塞的情況以及正確性與效率等方面的因素。

總起來說,中斷/異常的虛擬化由中斷/異常源的定義、中斷/異常源與VMM處理器虛擬化模塊間的交互機制以及最終模擬注入的過程所組成。虛擬機與VMM通過中斷和異常發生的交互機制如圖2-3所示。

在CPU虛擬化方面,Intel VT提供了面向x86的英特爾虛擬化技術(Intel Virtualization Technology for x86,簡稱Intel VT-x)。Intel VT中的VT-x技術擴展了傳統的IA32處理器架構,為IA32架構的處理器虛擬化提供了硬件支持。VT-x架構的基本思想如圖2-4所示。

圖2-3 虛擬機與VMM通過中斷和異常發生的交互機制

圖2-4 VT-x架構的基本思想

首先,VT-x引入了兩種操作模式,統稱為VMX操作模式。

●根操作模式(VMX Root Operation):VMM運行所處的模式,以下簡稱為根模式。

●非根操作模式(VMX Non-Root Operation):客戶機運行所處的模式,以下簡稱為非根模式。

這兩種操作模式與IA32特權級0~特權級3是正交的,即每種操作模式下都有相應的特權級0~特權級3。

VT-x中,非根模式下敏感指令引起的“陷入”被稱為VM Exit。VM Exit發生時,CPU自動從非根模式切換為根模式。相應地,VT-x也定義了VM Entry,該操作由VMM發起,通常是調度某個客戶機運行,此時CPU從根模式切換為非根模式。

其次,為了更好地支持CPU虛擬化,VT-x引入了虛擬機控制結構(Virtual-Machine Control Structure,VMCS)。VMCS保存虛擬CPU需要的相關狀態,例如CPU在根模式和非根模式下的特權寄存器的值。VMCS主要供CPU使用,CPU在發生VM Exit和VM Entry時都會自動查詢和更新VMCS。VMM可以通過指令來配置VMCS,進而影響CPU的行為。

最后,VT-x還引入了一組新的指令,VMLAUNCH/VMRESUME用于發起VM-Entry,VMREAD/VMWRITE用于配置VMCS等。

在進行CPU虛擬化時,使用vCPU描述符來描述虛擬CPU(Virtual CPU),它本質上是一個結構體,通常由以下幾部分構成。

●vCPU標識信息:用于標識vCPU的一些屬性,例如vCPU的ID號、vCPU屬于哪個客戶機等。

●虛擬寄存器信息:虛擬的寄存器資源,在使用Intel VT-x的情況下,這些內容包含在VMCS中,例如客戶機狀態域保存的內容。

●vCPU狀態信息:類似于進程的狀態信息,標識該vCPU當前所處的狀態,例如睡眠、運行等,主要供調度器使用。

●額外寄存器/部件信息:主要指未包含在VMCS中的一些寄存器或CPU部件,例如浮點寄存器和虛擬的LAPIC等。

●其他信息:用于VMM進行優化或存儲額外信息的字段,例如存放該vCPU私有數據的指針等。

由此可見,在Intel VT-x情況下,vCPU可以劃分成兩個部分:一個是以VMCS為主由硬件使用和更新的部分,主要指虛擬寄存器;另一個是除VMCS之外,由VMM使用和更新的部分,主要指VMCS以外的部分。圖2-5展示了vCPU的構成。

當VMM創建客戶機時,首先要為客戶機創建vCPU,整個客戶機的運行實際上是VMM調度不同的vCPU運行。

圖2-5 vCPU的構成

創建vCPU實際上是創建vCPU描述符,由于本質上vCPU描述符是一個結構體,因此創建vCPU描述符簡單來說就是分配相應大小的內存。

vCPU描述符被創建之后,需要初始化才能使用。物理CPU在上電之后,硬件會自動將CPU初始化為特定的狀態。vCPU的初始化也是一個類似的過程,將vCPU描述符的各個部分置成可用的狀態。通常初始化包含如下內容。

●分配vCPU標識:首先要標識該vCPU屬于哪個客戶機,再為該vCPU分配一個在客戶機范圍內唯一的標識。

●初始化虛擬寄存器組:主要指初始化VMCS相關域。這些寄存器的初始化值通常是根據物理CPU上電后各寄存器的值設定的。

●初始化vCPU狀態信息:設置vCPU在被調度前需要配置的必要標志,具體情況依據調度器的實現決定。

●初始化額外部件:將未被VMCS包含的虛擬寄存器初始化為物理CPU上電后的值,并配置虛擬LAPIC等部件。

●初始化其他信息:根據VMM的實現初始化vCPU的私有數據。

vCPU被創建并初始化之后,就可以通過調度程序被調度運行。調度程序會根據一定的策略算法來選擇vCPU,然后將vCPU切換到物理CPU上運行。前面提到,在Intel VT-x的支持下,vCPU的上下文可以分為兩部分。故上下文的切換也分為硬件自動切換(VMCS部分)和VMM軟件切換(非VMCS部分)兩個部分。

圖2-6描述了VT-x支持的CPU上下文切換的過程,可以歸納為下列幾個步驟。

●VMM保存自己的上下文,主要是保存VMCS不保存的寄存器,即宿主機狀態域以外的部分。

●VMM將保存在vCPU中由軟件切換的上下文加載到物理CPU中。

●VMM執行VMRESUME/VMLAUNCH指令,觸發VM-Entry,此時CPU自動將vCPU上下文中VMCS部分加載到物理CPU,CPU切換到非根模式。

圖2-6 VM-Entry中的上下文切換

此時,物理CPU已經處于客戶機的運行環境,rip/eip也指向了客戶機的指令,這樣vCPU就被成功調度并運行了。

當然,vCPU作為調度單位不可能永遠運行,vCPU退出在VT-x中表現為發生VM-Exit。對vCPU退出的處理是VMM進行CPU虛擬化的核心,例如模擬各種特權指令。

圖2-7描述了VMM處理vCPU退出的典型流程,可以歸納為下列幾個步驟。

●發生VM Exit,CPU自動進行一部分上下文的切換。

●當CPU切換到根模式開始執行VM Exit的處理函數后,進行另一部分上下文的切換。

圖2-7 VM Exit的處理

圖2-7列舉了一些較為典型的vCPU退出的原因。總起來說,vCPU退出的原因大體上有三類:訪問了特權資源、引發了異常或發生了中斷。

VMM在處理完vCPU的退出后,會負責將vCPU投入再運行。從VT-x的角度來看,需要額外考慮以下幾點。

●如果vCPU繼續在相同的物理CPU上運行,可以用VMRESUME來實現VM-Entry。VMRESUME比VMLAUNCH更輕量級,執行效率更高。

●如果由于某種原因(如負載均衡),vCPU被調度程序遷移到了另一個物理CPU上,那么VMM需要將vCPU對應的VMCS遷移到另一個物理CPU,這通常可以由一個IPI中斷實現;遷移完成后,在重新綁定的物理CPU上執行VMLAUNCH發起VM-Entry。

由此可見,整個虛擬化的內容就是在VMM→客戶機→VMM→……中完成的。這里再細化一下,客戶機的順利運行就是在vCPU運行→vCPU退出→vCPU再運行→……的過程中完成的。

2.內存虛擬化

在介紹完處理器虛擬化的基本原理之后,接著來看一下內存虛擬化。首先操作系統對物理內存有兩個主要認識:物理地址從0開始和內存地址連續性。而內存虛擬化的產生主要源于VMM與客戶機操作系統對物理內存的認識存在沖突,造成了物理內存的真正擁有者——VMM必須對客戶機操作系統所訪問的內存進行一定程度上的虛擬化。VMM的任務就是模擬使得虛擬出來的內存仍然符合客戶機操作系統對內存的假定和認識。

因此,在虛擬環境里,內存虛擬化面臨的問題是:物理內存要被多個客戶機操作系統同時使用,但物理內存只有一份,物理起始地址0也只有一個,無法同時滿足所有客戶機操作系統內存從0開始的要求;由于使用內存分區方式,把物理內存分給多個客戶機操作系統使用,客戶機操作系統的內存連續性要求雖能得到解決,但是內存的使用效率非常低。在面臨這些問題的情況下,VMM所要做的就是“欺騙”客戶機操作系統,以滿足客戶機操作系統對內存的上述兩點要求,這種欺騙過程就是內存虛擬化。

內存虛擬化的核心在于引入一層新的地址空間——客戶機物理地址空間。

在圖2-8中,VMM負責管理和分配每個虛擬機的物理內存,客戶機操作系統所看到的是一個虛構的客戶機物理地址空間,其指令目標地址也是一個客戶機物理地址。這樣的地址在無虛擬化的情況下,其實就是實際物理地址。但是,在有虛擬化的情況下,這樣的地址是不能被直接發送到系統總線上去的,需要VMM負責將客戶機物理地址轉換成一個實際物理地址后,再交由物理處理器來執行。

圖2-8 內存虛擬化示意圖

值得一提的是,為了更有效地利用空閑的物理內存,尤其是系統長期運行后產生的碎片,VMM通常會以比較小的粒度(如4KB)進行分配,這就導致給定一個虛擬機的物理內存實際上是不連續的,其具體位置完全取決于VMM的內存分配算法。

由于引入了客戶機物理地址空間,內存虛擬化就主要處理以下兩個方面的問題。

●給定一個虛擬機,維護客戶機物理地址到宿主機物理地址之間的映射關系。

●截獲虛擬機對客戶機物理地址的訪問,并根據所記錄的映射關系將其轉換成宿主機物理地址。

第一個問題相對比較簡單,因為只是一個數據結構的映射問題。在實現過程中,客戶機操作系統采用客戶頁表維護該虛擬機里進程所使用的虛擬地址到客戶機物理地址的動態映射關系,可以用一個簡單的公式表示:GPA=f1(GVA)。其中,GVA是客戶機虛擬地址(Guest Virtual Address),GPA是客戶機物理地址(Guest Physical Address)。而VMM負責維護客戶機物理地址到宿主機物理地址之間的動態映射關系,可以用一個簡單的公式表示:HPA=f2(GPA)。這里,HPA是宿主機物理地址(Host Physical Address)。虛擬機里一個進程所使用的客戶機虛擬地址要變成物理處理器可以執行的宿主機物理地址,需要經過兩層轉換,即HPA=f2f1(GVA))。

VMM內存虛擬化任務就是跟蹤客戶頁表,當其發生變化時,及時地切入,構造一個有效的客戶機虛擬地址到宿主機物理地址間的映射關系,并將其添加到物理處理器所遍歷的真實頁表上。

第二個問題從實現上來說更加復雜、更具有挑戰性,也是衡量一個虛擬機的性能最重要的因素。另外,地址轉換一定要發生在物理處理器處理目標指令之前,否則一旦客戶機物理地址被直接發送到系統總線上,就會對整個虛擬環境,包括其他虛擬機以及VMM自身,造成嚴重的破壞和巨大的漏洞。

一個最簡單的方法就是設法讓虛擬機對客戶機物理地址空間的每一次訪問都觸發異常,然后由VMM來查詢地址轉換表模擬其訪問。這種方法的完備性和正確性沒有任何問題,但是性能上絕對是最差的。為了解決這個問題,VT-x提供了擴展頁表(Extended Page Table,EPT)技術,直接在硬件上支持GVA→GPA→HPA的兩次地址轉換,大大降低了內存虛擬化的難度,也進一步提高了內存虛擬化的性能。

3.I/O虛擬化

現實中的外設資源也是有限的,為了滿足多個客戶機操作系統的需求,VMM必須通過I/O虛擬化的方式來復用有限的外設資源。VMM截獲客戶操作系統對設備的訪問請求,然后通過軟件的方式來模擬真實設備。模擬軟件本身作為物理驅動程序眾多客戶端中的一個,有效地實現了物理資源的復用。由于從處理器的角度看,外設是通過一組I/O資源(端口I/O或者內存映射I/O)來進行訪問的,因此設備相關的虛擬化又被稱為I/O虛擬化。基于設備類型的多樣化,以及不同VMM所構建的虛擬環境上的差異,I/O虛擬化的方式和特點紛繁復雜,不一而足。

I/O端口、內存映射I/O(Memory-Mapped I/O,MMIO)與中斷模塊組成了一個典型外設呈現給軟件的基本資源。I/O虛擬化并不需要完整地虛擬化出所有外設的所有接口,怎樣做完全取決于設備與VMM的策略以及客戶機操作系統的需求。其中主要涉及虛擬芯片組、虛擬PCI總線布局、虛擬系統設備(如PIC、IO-APIC、PIT和RTC等)以及虛擬基本輸入輸出設備(如顯卡、網卡和硬盤等)。VMM提供某種方式,讓客戶機操作系統發現虛擬設備以加載相關的驅動程序,然后VMM設法截獲客戶機操作系統對虛擬設備的訪問并進行模擬,這樣完成I/O虛擬化。虛擬化完畢后,只要客戶機操作系統中有驅動程序遵守該虛擬設備的接口定義,它就可以被客戶機操作系統使用。

至于虛擬化方式,虛擬設備可以與物理設備具有完全相同的接口定義,從而允許客戶機操作系統中的原有驅動程序無須修改就能驅動這個虛擬設備。在這種情況下,物理設備具備哪些資源,設備模擬器需要呈現出同樣的資源。另一種方式是把客戶機操作系統中特定的驅動程序進行簡化,并將客戶機操作系統中的驅動程序稱為前端(Front-End,FE)設備驅動,而將VMM中的驅動程序稱為后端(Back-End,BE)設備驅動。簡化就是前端程序將來自其他模塊的請求通過客戶機之間的特殊通信機制直接發送給后端程序,而后端程序在處理完請求后再發回通知給前者。這種方式是基于請求/事務的,能在很大程度上減少上下文切換的頻率,提供更大的優化空間,可以把這種方式看作上一種方式的衍生。還有一種方式,如果直接將物理設備分配給某個客戶機操作系統,由客戶機操作系統直接訪問目標設備,VMM不需要為這種方式提供模擬,客戶機操作系統中原有的驅動程序也可以無縫地操作目標設備,這種I/O虛擬化的方式從性能上來說是最優的。目前與此相關的技術有Intel VT-d和PCI組織制定的SR-IOV等。

本節主要針對x86架構闡述了虛擬化技術的基本原理,至于其他指令集架構,如Arm6[1]等,限于篇幅,在此不再贅述,感興趣的讀者可以參考相關資料。

2.1.3 虛擬化的主要方式

前面提及了三種主要的虛擬化方式,下面來簡要介紹三種不同方式的原理。

1.基于軟件的完全虛擬化

我們知道,所有的虛擬化形式都可以用模擬技術來實現。在模擬技術中,最簡單最直接的模擬技術是解釋執行,即取一條指令出來,模擬出這條指令執行的效果,再繼續取下一條指令,周而復始。由于是一條一條地取指令而不會漏過每一條指令,在某種程度上即每條指令都“陷入”了,所以解決了陷入再模擬的問題,進而避免了虛擬化漏洞。這種方法通常可以被用于不同體系結構的虛擬化中,也就是在一種硬件體系結構上模擬出另一種不同硬件體系結構的運行環境。而在同一種體系結構的模擬中,情況會變得更容易,因為大多數指令是不需要被模擬執行而直接放在真實的硬件上執行的,于是一條指令一條指令地解釋執行在這里就沒有必要了。可以采用改進的代碼掃描與修補(scan-and-patch)技術和二進制代碼翻譯技術來完成CPU虛擬化,基于影子頁表來完成內存虛擬化,以及借助設備模型并對其軟件接口進行攔截和模擬來完成I/O虛擬化,從而盡可能地提高虛擬化的性能。

2.硬件輔助虛擬化

硬件輔助虛擬化技術,顧名思義,就是在CPU、芯片組及I/O設備等硬件中加入專門針對虛擬化技術的支持,使系統軟件可以更容易、更高效地實現虛擬化功能。只要為硬件本身加入足夠的虛擬化功能,就可以截獲操作系統對敏感指令的執行或者對敏感資源的訪問,從而通過異常的方式報告給VMM,這樣就解決了虛擬化的問題。Intel的VT-x技術就是這一方向的代表。VT-x技術在處理器上引入了一個新的執行模式,用于運行虛擬機。當虛擬機運行在這個特殊模式中時,它仍然面對的是一套完整的處理器寄存器集合和執行環境,只是任何特權操作都會被處理器截獲并報告給VMM。VMM本身運行在正常模式下,在接收到處理器的報告后,通過對目標指令的解碼,找到對應的虛擬化模塊進行模擬,并把最終的效果反映在特殊模式下的環境中。硬件虛擬化是一種完備的虛擬化方法,因為內存和外設的訪問本身也由指令來承載,對處理器指令級別的截獲就意味著VMM可以模擬一個與真實主機完全相同的環境。在這個環境中,任何操作系統只要能夠在現實中的等同主機上運行,就可以在這個虛擬機環境中無縫地運行。

3.半虛擬化

在計算機硬件不能改變的情況下,VMM提供給虛擬機的硬件抽象是可以修改的。這里所說的硬件抽象,是指硬件平臺掩去了內部的具體實現,暴露給軟件的抽象接口。半虛擬化(Paravirtualization)技術的主要思想就是通過修改暴露給虛擬機的硬件抽象以及上層操作系統,使操作系統與VMM配合工作,避開虛擬化漏洞,從而實現系統虛擬化。半虛擬化技術修改了硬件抽象,操作系統也需要做相應的修改,這些修改主要包括指令集、外部中斷、內存空間及內存管理方式、I/O設備驅動、時鐘等。事實上,不同的半虛擬化系統為了實現不同的目的,對于硬件抽象層和操作系統的修改都是不同的。當然,虛擬硬件抽象與實際硬件的差別越大,客戶機操作系統和應用程序需要做的修改也越多。從操作系統的角度來看,半虛擬化的硬件抽象是一種與x86架構有所不同的體系結構,因此,對操作系統的修改就是對這種體系結構進行移植的過程。修改后的操作系統能夠意識到虛擬環境的存在。

2.1.4 VMM的分類

通過1.2節的介紹,相信讀者已經對VMM模型的分類有了初步的認識,這里進一步對各模型中模塊的功能進行深入剖析。我們知道,根據虛擬化技術實現結構的不同,通常將虛擬機監控器分為以下兩類。

1.原生型虛擬機監控器(Native Hypervisor)

在原生型虛擬機監控器中,VMM可以被看作一個完備的操作系統,不過和傳統操作系統不同的是,VMM是為虛擬化而設計的,因此還具備虛擬化功能。從架構上來看,首先,所有的物理資源(如處理器、內存和I/O設備等)都歸VMM所有,因此,VMM承擔著管理物理資源的責任;其次,VMM需要向上提供虛擬機,用于運行客戶機操作系統,因此,VMM還負責虛擬環境的創建和管理。此類型通常被稱為一型虛擬機監控器(Type-1 Hypervisor),又被稱為裸機虛擬機監控器(Bare-metal Hypervisor)。

圖2-9展示了此類模型中較為典型的監控模型(Hypervisor Model)架構,其中處理器管理代碼(Processor,P)負責物理處理器的管理和虛擬化,內存管理代碼(Memory,M)負責物理內存的管理和虛擬化,設備模型(Device Model,DM)負責I/O設備的虛擬化,設備驅動(Device Driver,DR)則負責I/O設備的驅動,即物理設備的管理。VMM直接管理所有的物理資源,包括處理器、內存和I/O設備,因此,設備驅動是VMM的一部分。此外,處理器管理代碼、內存管理代碼和設備模型也是VMM的一部分。典型的產品為VMware ESXi[2]

圖2-9 監控模型架構

對于上述模型來說,設備驅動開發的工作量是一個很大的挑戰。一種改進實現是,VMM會主動讓出大部分I/O設備的控制權,把它們交由一個運行在特權虛擬機中的特權操作系統來控制。相應地,VMM虛擬化的職責也被分擔。處理器和內存的虛擬化依然由VMM來完成,而I/O的虛擬化則由VMM和特權操作系統共同合作來完成。包含特權系統的原生型虛擬機監控器架構,由于其本質上仍屬于一型虛擬機監控器,同時兼具后面即將介紹的另一類模型的某些特征,因此是兩種模式的匯合體,我們權且將其稱為混合模型。

圖2-10展示了混合模型(Hybrid Model)的架構。在這一模型中,I/O設備由特權操作系統控制,因此,設備驅動模塊位于特權操作系統內核空間中。其他物理資源的管理和虛擬化由VMM完成,因此,處理器管理代碼和內存管理代碼處在VMM中。I/O設備虛擬化由VMM和特權操作系統共同完成,因此,設備模型模塊位于特權操作系統用戶空間中,并且通過相應的通信機制與VMM合作。典型的產品有Microsoft Hyper-V8[3]、Xen9[4]

2.宿主型虛擬機監控器(Hosted Hypervisor)

與原生型虛擬機監控器不同,在宿主模型中,物理資源由宿主機操作系統管理。宿主機操作系統是傳統操作系統,如Windows、Linux等,這些傳統操作系統并不是為虛擬化而設計的,因此本身并不具備虛擬化功能,實際的虛擬化功能由VMM來提供。VMM通常是宿主機操作系統獨立的內核模塊,有些實現中還包括用戶態進程,如負責I/O虛擬化的用戶態設備模型。VMM通過調用宿主機操作系統的服務來獲得資源,實現處理器、內存和I/O設備的虛擬化。VMM創建虛擬機之后,通常將虛擬機作為宿主機操作系統的一個進程參與調度。此類型通常被稱為二型虛擬機監控器(Type-2 Hypervisor)。

圖2-10 混合模型架構

圖2-11展示了宿主模型(Host-based Model)的架構。由于宿主機操作系統控制所有的物理資源,包括I/O設備,因此,設備驅動位于宿主機操作系統中。VMM則被拆分為兩部分協同運作:內核態VMM和用戶態VMM。內核態VMM包含了處理器虛擬化模塊和內存虛擬化模塊。設備模型實際上也是VMM的一部分,在圖中位于用戶態VMM中,在具體實現時,既可以將設備模型放在用戶態,也可以將其放在內核態。典型的產品有VMware Workstation、VMware Fusion、KVM[5]、Intel HAXM[6]

圖2-11 宿主模型架構

主站蜘蛛池模板: 莎车县| 平南县| 波密县| 拉萨市| 绿春县| 华阴市| 囊谦县| 深州市| 东至县| 东阿县| 东丰县| 铁岭市| 抚顺市| 澜沧| 大安市| 正定县| 祥云县| 绥阳县| 恩施市| 莒南县| 惠安县| 酉阳| 大荔县| 杭锦旗| 新巴尔虎右旗| 门头沟区| 隆子县| 江安县| 滨海县| 嘉黎县| 鄯善县| 高安市| 宁明县| 黄大仙区| 吉安县| 西安市| 枞阳县| 澄迈县| 安化县| 庄浪县| 竹山县|