隨著近年多核系統(tǒng)、集群、網(wǎng)格甚至云計(jì)算的廣泛部署,虛擬化技術(shù)在商業(yè)應(yīng)用上的優(yōu)勢(shì)日益體現(xiàn),不僅降低了 IT 成本,而且還增強(qiáng)了系統(tǒng)安全性和可靠性,虛擬化的概念也逐漸深入到人們?nèi)粘5墓ぷ髋c生活中。本文針對(duì) x86 平臺(tái),首先給出虛擬化技術(shù)的基本概念和分類(lèi),然后闡述純軟件虛擬化的實(shí)現(xiàn)原理和面臨的挑戰(zhàn),最后詳細(xì)介紹 Intel-VT 硬件輔助虛擬化技術(shù)。
虛擬化技術(shù)簡(jiǎn)介
什么是虛擬化
虛擬化(Virtualization)技術(shù)最早出現(xiàn)在 20 世紀(jì) 60 年代的 IBM 大型機(jī)系統(tǒng),在70年代的 System 370 系列中逐漸流行起來(lái),這些機(jī)器通過(guò)一種叫虛擬機(jī)監(jiān)控器(Virtual Machine Monitor,VMM)的程序在物理硬件之上生成許多可以運(yùn)行獨(dú)立操作系統(tǒng)軟件的虛擬機(jī)(Virtual Machine)實(shí)例。隨著近年多核系統(tǒng)、集群、網(wǎng)格甚至云計(jì)算的廣泛部署,虛擬化技術(shù)在商業(yè)應(yīng)用上的優(yōu)勢(shì)日益體現(xiàn),不僅降低了 IT 成本,而且還增強(qiáng)了系統(tǒng)安全性和可靠性,虛擬化的概念也逐漸深入到人們?nèi)粘5墓ぷ髋c生活中。
虛擬化是一個(gè)廣義的術(shù)語(yǔ),對(duì)于不同的人來(lái)說(shuō)可能意味著不同的東西,這要取決他們所處的環(huán)境。在計(jì)算機(jī)科學(xué)領(lǐng)域中,虛擬化代表著對(duì)計(jì)算資源的抽象,而不僅僅局限于虛擬機(jī)的概念。例如對(duì)物理內(nèi)存的抽象,產(chǎn)生了虛擬內(nèi)存技術(shù),使得應(yīng)用程序認(rèn)為其自身?yè)碛羞B續(xù)可用的地址空間(Address Space),而實(shí)際上,應(yīng)用程序的代碼和數(shù)據(jù)可能是被分隔成多個(gè)碎片頁(yè)或段),甚至被交換到磁盤(pán)、閃存等外部存儲(chǔ)器上,即使物理內(nèi)存不足,應(yīng)用程序也能順利執(zhí)行。
虛擬化技術(shù)的分類(lèi)
虛擬化技術(shù)主要分為以下幾個(gè)大類(lèi) [1]:
- 平臺(tái)虛擬化(Platform Virtualization),針對(duì)計(jì)算機(jī)和操作系統(tǒng)的虛擬化。
- 資源虛擬化(Resource Virtualization),針對(duì)特定的系統(tǒng)資源的虛擬化,比如內(nèi)存、存儲(chǔ)、網(wǎng)絡(luò)資源等。
- 應(yīng)用程序虛擬化(Application Virtualization),包括仿真、模擬、解釋技術(shù)等。
我們通常所說(shuō)的虛擬化主要是指平臺(tái)虛擬化技術(shù),通過(guò)使用控制程序(Control Program,也被稱(chēng)為 Virtual Machine Monitor 或 Hypervisor),隱藏特定計(jì)算平臺(tái)的實(shí)際物理特性,為用戶提供抽象的、統(tǒng)一的、模擬的計(jì)算環(huán)境(稱(chēng)為虛擬機(jī))。虛擬機(jī)中運(yùn)行的操作系統(tǒng)被稱(chēng)為客戶機(jī)操作系統(tǒng)(Guest OS),運(yùn)行虛擬機(jī)監(jiān)控器的操作系統(tǒng)被稱(chēng)為主機(jī)操作系統(tǒng)(Host OS),當(dāng)然某些虛擬機(jī)監(jiān)控器可以脫離操作系統(tǒng)直接運(yùn)行在硬件之上(如 VMWARE 的 ESX 產(chǎn)品)。運(yùn)行虛擬機(jī)的真實(shí)系統(tǒng)我們稱(chēng)之為主機(jī)系統(tǒng)。
平臺(tái)虛擬化技術(shù)又可以細(xì)分為如下幾個(gè)子類(lèi):
- 全虛擬化(Full Virtualization)
全虛擬化是指虛擬機(jī)模擬了完整的底層硬件,包括處理器、物理內(nèi)存、時(shí)鐘、外設(shè)等,使得為原始硬件設(shè)計(jì)的操作系統(tǒng)或其它系統(tǒng)軟件完全不做任何修改就可以在虛擬機(jī)中運(yùn)行。操作系統(tǒng)與真實(shí)硬件之間的交互可以看成是通過(guò)一個(gè)預(yù)先規(guī)定的硬件接口進(jìn)行的。全虛擬化 VMM 以完整模擬硬件的方式提供全部接口(同時(shí)還必須模擬特權(quán)指令的執(zhí)行過(guò)程)。舉例而言,x86 體系結(jié)構(gòu)中,對(duì)于操作系統(tǒng)切換進(jìn)程頁(yè)表的操作,真實(shí)硬件通過(guò)提供一個(gè)特權(quán) CR3 寄存器來(lái)實(shí)現(xiàn)該接口,操作系統(tǒng)只需執(zhí)行 "mov pgtable,%%cr3" 匯編指令即可。全虛擬化 VMM 必須完整地模擬該接口執(zhí)行的全過(guò)程。如果硬件不提供虛擬化的特殊支持,那么這個(gè)模擬過(guò)程將會(huì)十分復(fù)雜:一般而言,VMM 必須運(yùn)行在最高優(yōu)先級(jí)來(lái)完全控制主機(jī)系統(tǒng),而 Guest OS 需要降級(jí)運(yùn)行,從而不能執(zhí)行特權(quán)操作。當(dāng) Guest OS 執(zhí)行前面的特權(quán)匯編指令時(shí),主機(jī)系統(tǒng)產(chǎn)生異常(General Protection Exception),執(zhí)行控制權(quán)重新從 Guest OS 轉(zhuǎn)到 VMM 手中。VMM 事先分配一個(gè)變量作為影子 CR3 寄存器給 Guest OS,將 pgtable 代表的客戶機(jī)物理地址(Guest Physical Address)填入影子 CR3 寄存器,然后 VMM 還需要 pgtable 翻譯成主機(jī)物理地址(Host Physical Address)并填入物理 CR3 寄存器,最后返回到 Guest OS中。隨后 VMM 還將處理復(fù)雜的 Guest OS 缺頁(yè)異常(Page Fault)。比較著名的全虛擬化 VMM 有 Microsoft Virtual PC、VMware Workstation、Sun Virtual Box、Parallels Desktop for Mac 和 QEMU。
- 超虛擬化(Paravirtualization)
這是一種修改 Guest OS 部分訪問(wèn)特權(quán)狀態(tài)的代碼以便直接與 VMM 交互的技術(shù)。在超虛擬化虛擬機(jī)中,部分硬件接口以軟件的形式提供給客戶機(jī)操作系統(tǒng),這可以通過(guò) Hypercall(VMM 提供給 Guest OS 的直接調(diào)用,與系統(tǒng)調(diào)用類(lèi)似)的方式來(lái)提供。例如,Guest OS 把切換頁(yè)表的代碼修改為調(diào)用 Hypercall 來(lái)直接完成修改影子 CR3 寄存器和翻譯地址的工作。由于不需要產(chǎn)生額外的異常和模擬部分硬件執(zhí)行流程,超虛擬化可以大幅度提高性能,比較著名的 VMM 有 Denali、Xen。
- 硬件輔助虛擬化(Hardware-Assisted Virtualization)
硬件輔助虛擬化是指借助硬件(主要是主機(jī)處理器)的支持來(lái)實(shí)現(xiàn)高效的全虛擬化。例如有了 Intel-VT 技術(shù)的支持,Guest OS 和 VMM 的執(zhí)行環(huán)境自動(dòng)地完全隔離開(kāi)來(lái),Guest OS 有自己的“全套寄存器”,可以直接運(yùn)行在最高級(jí)別。因此在上面的例子中,Guest OS 能夠執(zhí)行修改頁(yè)表的匯編指令。Intel-VT 和 AMD-V 是目前 x86 體系結(jié)構(gòu)上可用的兩種硬件輔助虛擬化技術(shù)。
- 部分虛擬化(Partial Virtualization)
VMM 只模擬部分底層硬件,因此客戶機(jī)操作系統(tǒng)不做修改是無(wú)法在虛擬機(jī)中運(yùn)行的,其它程序可能也需要進(jìn)行修改。在歷史上,部分虛擬化是通往全虛擬化道路上的重要里程碑,最早出現(xiàn)在第一代的分時(shí)系統(tǒng) CTSS 和 IBM M44/44X 實(shí)驗(yàn)性的分頁(yè)系統(tǒng)中。
- 操作系統(tǒng)級(jí)虛擬化(Operating System Level Virtualization)
在傳統(tǒng)操作系統(tǒng)中,所有用戶的進(jìn)程本質(zhì)上是在同一個(gè)操作系統(tǒng)的實(shí)例中運(yùn)行,因此內(nèi)核或應(yīng)用程序的缺陷可能影響到其它進(jìn)程。操作系統(tǒng)級(jí)虛擬化是一種在服務(wù)器操作系統(tǒng)中使用的輕量級(jí)的虛擬化技術(shù),內(nèi)核通過(guò)創(chuàng)建多個(gè)虛擬的操作系統(tǒng)實(shí)例(內(nèi)核和庫(kù))來(lái)隔離不同的進(jìn)程,不同實(shí)例中的進(jìn)程完全不了解對(duì)方的存在。比較著名的有 Solaris Container [2],F(xiàn)reeBSD Jail 和 OpenVZ 等。
這種分類(lèi)并不是絕對(duì)的,一個(gè)優(yōu)秀的虛擬化軟件往往融合了多項(xiàng)技術(shù)。例如 VMware Workstation 是一個(gè)著名的全虛擬化的 VMM,但是它使用了一種被稱(chēng)為動(dòng)態(tài)二進(jìn)制翻譯的技術(shù)把對(duì)特權(quán)狀態(tài)的訪問(wèn)轉(zhuǎn)換成對(duì)影子狀態(tài)的操作,從而避免了低效的 Trap-And-Emulate 的處理方式,這與超虛擬化相似,只不過(guò)超虛擬化是靜態(tài)地修改程序代碼。對(duì)于超虛擬化而言,如果能利用硬件特性,那么虛擬機(jī)的管理將會(huì)大大簡(jiǎn)化,同時(shí)還能保持較高的性能。
本文討論的虛擬化技術(shù)只針對(duì) x86 平臺(tái)(含 AMD 64),并假定虛擬機(jī)中運(yùn)行的 Guest OS 也是為 x86 平臺(tái)設(shè)計(jì)的。
純軟件虛擬化技術(shù)的原理及面臨的挑戰(zhàn)
虛擬機(jī)監(jiān)控器應(yīng)當(dāng)具備的條件
1974 年,Popek 和 Goldberg 在《Formal Requirements for Virtualizable Third Generation Architectures》[3] 論文中提出了一組稱(chēng)為虛擬化準(zhǔn)則的充分條件,滿足這些條件的控制程序可以被稱(chēng)為虛擬機(jī)監(jiān)控器(Virtual Machine Monitor,簡(jiǎn)稱(chēng) VMM):
- 資源控制??刂瞥绦虮仨毮軌蚬芾硭械南到y(tǒng)資源。
- 等價(jià)性。在控制程序管理下運(yùn)行的程序(包括操作系統(tǒng)),除時(shí)序和資源可用性之外的行為應(yīng)該與沒(méi)有控制程序時(shí)的完全一致,且預(yù)先編寫(xiě)的特權(quán)指令可以自由地執(zhí)行。
- 效率性。絕大多數(shù)的客戶機(jī)指令應(yīng)該由主機(jī)硬件直接執(zhí)行而無(wú)需控制程序的參與。
盡管基于簡(jiǎn)化的假設(shè),但上述條件仍為評(píng)判一個(gè)計(jì)算機(jī)體系結(jié)構(gòu)是否能夠有效支持虛擬化提供了一個(gè)便利方法,也為設(shè)計(jì)可虛擬化計(jì)算機(jī)架構(gòu)給出了指導(dǎo)原則。
原理簡(jiǎn)介
我們知道,傳統(tǒng)的 x86 體系結(jié)構(gòu)缺乏必要的硬件支持,任何虛擬機(jī)監(jiān)控器都無(wú)法直接滿足上述條件,所以不是一個(gè)可虛擬化架構(gòu),但是我們可以使用純軟件實(shí)現(xiàn)的方式構(gòu)造虛擬機(jī)監(jiān)控器。
虛擬機(jī)是對(duì)真實(shí)計(jì)算環(huán)境的抽象和模擬,VMM 需要為每個(gè)虛擬機(jī)分配一套數(shù)據(jù)結(jié)構(gòu)來(lái)管理它們狀態(tài),包括虛擬處理器的全套寄存器,物理內(nèi)存的使用情況,虛擬設(shè)備的狀態(tài)等等。VMM 調(diào)度虛擬機(jī)時(shí),將其部分狀態(tài)恢復(fù)到主機(jī)系統(tǒng)中。并非所有的狀態(tài)都需要恢復(fù),例如主機(jī) CR3 寄存器中存放的是 VMM 設(shè)置的頁(yè)表物理地址,而不是 Guest OS 設(shè)置的值。主機(jī)處理器直接運(yùn)行 Guest OS 的機(jī)器指令,由于 Guest OS運(yùn)行在低特權(quán)級(jí)別,當(dāng)訪問(wèn)主機(jī)系統(tǒng)的特權(quán)狀態(tài)(如寫(xiě) GDT 寄存器)時(shí),權(quán)限不足導(dǎo)致主機(jī)處理器產(chǎn)生異常,將運(yùn)行權(quán)自動(dòng)交還給 VMM。此外,外部中斷的到來(lái)也會(huì)導(dǎo)致 VMM 的運(yùn)行。VMM 可能需要先將 該虛擬機(jī)的當(dāng)前狀態(tài)寫(xiě)回到狀態(tài)數(shù)據(jù)結(jié)構(gòu)中,分析虛擬機(jī)被掛起的原因,然后代表 Guest OS 執(zhí)行相應(yīng)的特權(quán)操作。最簡(jiǎn)單的情況,如Guest OS 對(duì) CR3 寄存器的修改,只需要更新虛擬機(jī)的狀態(tài)數(shù)據(jù)結(jié)構(gòu)即可。一般而言,大部分情況下,VMM 需要經(jīng)過(guò)復(fù)雜的流程才能完成原本簡(jiǎn)單的操作。最后 VMM 將運(yùn)行權(quán)還給 Guest OS,Guest OS 從上次被中斷的地方繼續(xù)執(zhí)行,或處理 VMM “塞”入的虛擬中斷和異常。這種經(jīng)典的虛擬機(jī)運(yùn)行方式被稱(chēng)為 Trap-And-Emulate,虛擬機(jī)對(duì)于 Guest OS 完全透明,Guest OS 不需要任何修改,但是 VMM 的設(shè)計(jì)會(huì)比較復(fù)雜,系統(tǒng)整體性能受到明顯的損害。
面臨的挑戰(zhàn)
在設(shè)計(jì)純軟件 VMM 的時(shí)候,需要解決如下挑戰(zhàn) [4]:
- 確保 VMM 控制所有的系統(tǒng)資源。
x86 處理器有 4 個(gè)特權(quán)級(jí)別,Ring 0 ~ Ring 3,只有運(yùn)行在 Ring 0 ~ 2 級(jí)時(shí),處理器才可以訪問(wèn)特權(quán)資源或執(zhí)行特權(quán)指令;運(yùn)行在 Ring 0 級(jí)時(shí),處理器可以訪問(wèn)所有的特權(quán)狀態(tài)。x86 平臺(tái)上的操作系統(tǒng)一般只使用 Ring 0 和 Ring 3 這兩個(gè)級(jí)別,操作系統(tǒng)運(yùn)行在 Ring 0 級(jí),用戶進(jìn)程運(yùn)行在 Ring 3 級(jí)。為了滿足上面的第一個(gè)充分條件-資源控制,VMM 自己必須運(yùn)行在 Ring 0 級(jí),同時(shí)為了避免 Guest OS 控制系統(tǒng)資源,Guest OS 不得不降低自身的運(yùn)行級(jí)別,運(yùn)行在 Ring 1 或 Ring 3 級(jí)(Ring 2 不使用)。
- 特權(quán)級(jí)壓縮(Ring Compression)。
VMM 使用分頁(yè)或段限制的方式保護(hù)物理內(nèi)存的訪問(wèn),但是 64 位模式下段限制不起作用,而分頁(yè)又不區(qū)分 Ring 0, 1, 2。為了統(tǒng)一和簡(jiǎn)化 VMM的設(shè)計(jì),Guest OS 只能和 Guest 進(jìn)程一樣運(yùn)行在 Ring 3 級(jí)。VMM 必須監(jiān)視 Guest OS 對(duì) GDT、IDT 等特權(quán)資源的設(shè)置,防止 Guest OS 運(yùn)行在 Ring 0級(jí),同時(shí)又要保護(hù)降級(jí)后的 Guest OS 不受 Guest 進(jìn)程的主動(dòng)攻擊或無(wú)意破壞。
- 特權(quán)級(jí)別名(Ring Alias)。
特權(quán)級(jí)別名是指 Guest OS 在虛擬機(jī)中運(yùn)行的級(jí)別并不是它所期望的。VMM 必須保證 Guest OS 不能獲知正在虛擬機(jī)中運(yùn)行這一事實(shí),否則可能打破等價(jià)性條件。例如,x86 處理器的特權(quán)級(jí)別存放在 CS 代碼段寄存器內(nèi),Guest OS 可以使用非特權(quán) push 指令將 CS 寄存器壓棧,然后 pop 出來(lái)檢查該值。又如,Guest OS 在低特權(quán)級(jí)別時(shí)讀取特權(quán)寄存器 GDT、LDT、IDT 和 TR,并不發(fā)生異常,從而可能發(fā)現(xiàn)這些值與自己期望的不一樣。為了解決這個(gè)挑戰(zhàn),VMM 可以使用動(dòng)態(tài)二進(jìn)制翻譯的技術(shù),例如預(yù)先把 “push %%cs” 指令替換,在棧上存放一個(gè)影子 CS 寄存器值;又如,可以把讀取 GDT 寄存器的操作“sgdt dest”改為“movl fake_gdt, dest”。
- 地址空間壓縮(Address Space Compression)。
地址空間壓縮是指 VMM 必須在Guest OS 的地址空間中保留一部分供其使用。例如,中斷描述表寄存器(IDT Register)中存放的是中斷描述表的線性地址,如果 Guest OS 運(yùn)行過(guò)程中來(lái)了外部中斷或觸發(fā)處理器異常,必須保證運(yùn)行權(quán)馬上轉(zhuǎn)移到 VMM 中,因此 VMM 需要將 Guest OS 的一部分線性地址空間映射成自己的中斷描述表的主機(jī)物理地址。VMM 可以完全運(yùn)行在 Guest OS 的地址空間中,也可以擁有獨(dú)立的地址空間,后者的話,VMM 只占用 Guest OS 很少的地址空間,用于存放中斷描述表和全局描述符表(GDT)等重要的特權(quán)狀態(tài)。無(wú)論如何哪種情況,VMM 應(yīng)該防止 Guest OS 直接讀取和修改這部分地址空間。
- 處理 Guest OS 的缺頁(yè)異常。
內(nèi)存是一種非常重要的系統(tǒng)資源,VMM 必須全權(quán)管理,Guest OS 理解的物理地址只是客戶機(jī)物理地址(Guest Physical Address),并不是最終的主機(jī)物理地址(Host Physical Address)。當(dāng) Guest OS 發(fā)生缺頁(yè)異常時(shí),VMM 需要知道缺頁(yè)異常的原因,是 Guest 進(jìn)程試圖訪問(wèn)沒(méi)有權(quán)限的地址,或是客戶機(jī)線性地址(Guest Linear Address)尚未翻譯成 Guest Physical Address,還是客戶機(jī)物理地址尚未翻譯成主機(jī)物理地址。一種可行的解決方法是 VMM 為 Guest OS 的每個(gè)進(jìn)程的頁(yè)表構(gòu)造一個(gè)影子頁(yè)表,維護(hù) Guest Linear Address 到 Host Physical Address 的映射,主機(jī) CR3 寄存器存放這個(gè)影子頁(yè)表的物理內(nèi)存地址。VMM 同時(shí)維護(hù)一個(gè) Guest OS 全局的 Guest Physical Address 到 Host Physical Address 的映射表。發(fā)生缺頁(yè)異常的地址總是Guest Linear Address,VMM 先去 Guest OS 中的頁(yè)表檢查原因,如果頁(yè)表項(xiàng)已經(jīng)建立,即對(duì)應(yīng)的Guest Physical Address 存在,說(shuō)明尚未建立到 Host Physical Address的映射,那么 VMM 分配一頁(yè)物理內(nèi)存,將影子頁(yè)表和映射表更新;否則,VMM 返回到 Guest OS,由 Guest OS 自己處理該異常。
- 處理 Guest OS 中的系統(tǒng)調(diào)用。
系統(tǒng)調(diào)用是操作系統(tǒng)提供給用戶的服務(wù)例程,使用非常頻繁。最新的操作系統(tǒng)一般使用 SYSENTER/SYSEXIT 指令對(duì)來(lái)實(shí)現(xiàn)快速系統(tǒng)調(diào)用。SYSENTER 指令通過(guò)IA32_SYSENTER_CS,IA32_SYSENTER_EIP 和 IA32_SYSENTER_ESP 這 3 個(gè) MSR(Model Specific Register)寄存器直接轉(zhuǎn)到 Ring 0級(jí);而 SYSEXIT 指令不在 Ring 0 級(jí)執(zhí)行的話將觸發(fā)異常。因此,如果 VMM 只能采取 Trap-And-Emulate 的方式處理這 2 條指令的話,整體性能將會(huì)受到極大損害。
- 轉(zhuǎn)發(fā)虛擬的中斷和異常。
所有的外部中斷和主機(jī)處理器的異常直接由 VMM 接管,VMM 構(gòu)造必需的虛擬中斷和異常,然后轉(zhuǎn)發(fā)給 Guest OS。VMM 需要模擬硬件和操作系統(tǒng)對(duì)中斷和異常的完整處理流程,例如 VMM 先要在 Guest OS 當(dāng)前的內(nèi)核棧上壓入一些信息,然后找到 Guest OS 相應(yīng)處理例程的地址,并跳轉(zhuǎn)過(guò)去。VMM 必須對(duì)不同的 Guest OS 的內(nèi)部工作流程比較清楚,這增加了 VMM 的實(shí)現(xiàn)難度。同時(shí),Guest OS 可能頻繁地屏蔽中斷和啟用中斷,這兩個(gè)操作訪問(wèn)特權(quán)寄存器 EFLAGS,必須由 VMM 模擬完成,性能因此會(huì)受到損害。 Guest OS 重新啟用中斷時(shí),VMM 需要及時(shí)地獲知這一情況,并將積累的虛擬中斷轉(zhuǎn)發(fā)。
- Guest OS 頻繁訪問(wèn)特權(quán)資源。
Guest OS對(duì)特權(quán)資源的每次訪問(wèn)都會(huì)觸發(fā)處理器異常,然后由 VMM 模擬執(zhí)行,如果訪問(wèn)過(guò)于頻繁,則系統(tǒng)整體性能將會(huì)受到極大損害。比如對(duì)中斷的屏蔽和啟用,cli(Clear Interrupts)指令在 Pentium 4 處理器上需要花費(fèi) 60 個(gè)時(shí)鐘周期(cycle)。又如,處理器本地高級(jí)可編程中斷處理器(Local APIC)上有一個(gè)操作系統(tǒng)可修改的任務(wù)優(yōu)先級(jí)寄存器(Task-Priority Register),IO-APIC 將外部中斷轉(zhuǎn)發(fā)到 TPR 值最低的處理器上(期望該處理器正在執(zhí)行低優(yōu)先級(jí)的線程),從而優(yōu)化中斷的處理。TPR 是一個(gè)特權(quán)寄存器,某些操作系統(tǒng)會(huì)頻繁設(shè)置(Linux Kernel只在初始化階段為每個(gè)處理器的 TPR 設(shè)置相同的值)。
軟件 VMM 所遇到的以上挑戰(zhàn)從本質(zhì)上來(lái)說(shuō)是因?yàn)?Guest OS 無(wú)法運(yùn)行在它所期望的最高特權(quán)級(jí),傳統(tǒng)的 Trap-And-Emulate 處理方式雖然以透明的方式基本解決上述挑戰(zhàn),但是帶來(lái)極大的設(shè)計(jì)復(fù)雜性和性能下降。當(dāng)前比較先進(jìn)的虛擬化軟件結(jié)合使用二進(jìn)制翻譯和超虛擬化的技術(shù),核心思想是動(dòng)態(tài)或靜態(tài)地改變 Guest OS 對(duì)特權(quán)狀態(tài)訪問(wèn)的操作,盡量減少產(chǎn)生不必要的硬件異常,同時(shí)簡(jiǎn)化 VMM 的設(shè)計(jì)。
Intel-VT 硬件輔助虛擬化技術(shù)詳解
2005 年冬天,英特爾帶來(lái)了業(yè)內(nèi)首個(gè)面向臺(tái)式機(jī)的硬件輔助虛擬化技術(shù) Intel-VT 及相關(guān)的處理器產(chǎn)品,從而拉開(kāi)了 IA 架構(gòu)虛擬化技術(shù)應(yīng)用的新時(shí)代大幕。支持虛擬化技術(shù)的處理器帶有特別優(yōu)化過(guò)的指令集來(lái)自動(dòng)控制虛擬化過(guò)程,從而極大簡(jiǎn)化 VMM 的設(shè)計(jì),VMM 的性能也能得到很大提高。其中 IA-32 處理器的虛擬化技術(shù)稱(chēng)為 VT-x,安騰處理器的虛擬化技術(shù)稱(chēng)為 VT-i。AMD 公司也推出了自己的虛擬化解決方案,稱(chēng)為 AMD-V。盡管 Intel-VT 和 AMD-V 并不完全相同,但是基本思想和數(shù)據(jù)結(jié)構(gòu)卻是相似的,本文只討論 Intel-VT-x 技術(shù)。
新增的兩種操作模式
VT-x 為 IA 32 處理器增加了兩種操作模式:VMX root operation 和 VMX non-root operation。VMM 自己運(yùn)行在 VMX root operation 模式,VMX non-root operation 模式則由 Guest OS 使用。兩種操作模式都支持 Ring 0 ~ Ring 3 這 4 個(gè)特權(quán)級(jí),因此 VMM 和 Guest OS 都可以自由選擇它們所期望的運(yùn)行級(jí)別。
這兩種操作模式可以互相轉(zhuǎn)換。運(yùn)行在 VMX root operation 模式下的 VMM 通過(guò)顯式調(diào)用 VMLAUNCH 或 VMRESUME 指令切換到 VMX non-root operation 模式,硬件自動(dòng)加載 Guest OS的上下文,于是 Guest OS 獲得運(yùn)行,這種轉(zhuǎn)換稱(chēng)為 VM entry。Guest OS 運(yùn)行過(guò)程中遇到需要 VMM 處理的事件,例如外部中斷或缺頁(yè)異常,或者主動(dòng)調(diào)用 VMCALL 指令調(diào)用 VMM 的服務(wù)的時(shí)候(與系統(tǒng)調(diào)用類(lèi)似),硬件自動(dòng)掛起 Guest OS,切換到 VMX root operation 模式,恢復(fù) VMM 的運(yùn)行,這種轉(zhuǎn)換稱(chēng)為 VM exit。VMX root operation 模式下軟件的行為與在沒(méi)有 VT-x 技術(shù)的處理器上的行為基本一致;而VMX non-root operation 模式則有很大不同,最主要的區(qū)別是此時(shí)運(yùn)行某些指令或遇到某些事件時(shí),發(fā)生 VM exit。
虛擬機(jī)控制塊
VMM 和 Guest OS 共享底層的處理器資源,因此硬件需要一個(gè)物理內(nèi)存區(qū)域來(lái)自動(dòng)保存或恢復(fù)彼此執(zhí)行的上下文。這個(gè)區(qū)域稱(chēng)為虛擬機(jī)控制塊(VMCS),包括客戶機(jī)狀態(tài)區(qū)(Guest State Area),主機(jī)狀態(tài)區(qū)(Host State Area)和執(zhí)行控制區(qū)。VM entry 時(shí),硬件自動(dòng)從客戶機(jī)狀態(tài)區(qū)加載 Guest OS 的上下文。并不需要保存 VMM 的上下文,原因與中斷處理程序類(lèi)似,因?yàn)?VMM 如果開(kāi)始運(yùn)行,就不會(huì)受到 Guest OS的干擾,只有 VMM 將工作徹底處理完畢才可能自行切換到 Guest OS。而 VMM 的下次運(yùn)行必然是處理一個(gè)新的事件,因此每次 VMM entry 時(shí), VMM 都從一個(gè)通用事件處理函數(shù)開(kāi)始執(zhí)行;VM exit 時(shí),硬件自動(dòng)將 Guest OS 的上下文保存在客戶機(jī)狀態(tài)區(qū),從主機(jī)狀態(tài)區(qū)中加載 VMM 的通用事件處理函數(shù)的地址,VMM 開(kāi)始執(zhí)行。而執(zhí)行控制區(qū)存放的則是可以操控 VM entry 和 exit 的標(biāo)志位,例如標(biāo)記哪些事件可以導(dǎo)致 VM exit,VM entry 時(shí)準(zhǔn)備自動(dòng)給 Guest OS “塞”入哪種中斷等等。
客戶機(jī)狀態(tài)區(qū)和主機(jī)狀態(tài)區(qū)都應(yīng)該包含部分物理寄存器的信息,例如控制寄存器 CR0,CR3,CR4;ESP 和 EIP(如果處理器支持 64 位擴(kuò)展,則為 RSP,RIP);CS,SS,DS,ES,F(xiàn)S,GS 等段寄存器及其描述項(xiàng);TR,GDTR,IDTR 寄存器;IA32_SYSENTER_CS,IA32_SYSENTER_ESP,IA32_SYSENTER_EIP 和 IA32_PERF_GLOBAL_CTRL 等 MSR 寄存器。客戶機(jī)狀態(tài)區(qū)并不包括通用寄存器的內(nèi)容,VMM 自行決定是否在 VM exit 的時(shí)候保存它們,從而提高了系統(tǒng)性能??蛻魴C(jī)狀態(tài)區(qū)還包括非物理寄存器的內(nèi)容,比如一個(gè) 32 位的 Active State 值表明 Guest OS 執(zhí)行時(shí)處理器所處的活躍狀態(tài),如果正常執(zhí)行指令就是處于 Active 狀態(tài),如果觸發(fā)了三重故障(Triple Fault)或其它嚴(yán)重錯(cuò)誤就處于 Shutdown 狀態(tài),等等。
前文已經(jīng)提過(guò),執(zhí)行控制區(qū)用于存放可以操控 VM entry 和 VM exit 的標(biāo)志位,包括:
- External-interrupt exiting:用于設(shè)置是否外部中斷可以觸發(fā) VM exit,而不論 Guest OS 是否屏蔽了中斷。
- Interrupt-window exiting:如果設(shè)置,當(dāng) Guest OS 解除中斷屏蔽時(shí),觸發(fā) VM exit。
- Use TPR shadow:通過(guò) CR8 訪問(wèn) Task Priority Register(TPR)的時(shí)候,使用 VMCS 中的影子 TPR,可以避免觸發(fā) VM exit。同時(shí)執(zhí)行控制區(qū)還有一個(gè) TPR 閾值的設(shè)置,只有當(dāng) Guest OS 設(shè)置的 TR 值小于該閾值時(shí),才觸發(fā) VM exit。
- CR masks and shadows:每個(gè)控制寄存器的每一位都有對(duì)應(yīng)的掩碼,控制 Guest OS 是否可以直接寫(xiě)相應(yīng)的位,或是觸發(fā) VM exit。同時(shí) VMCS 中包括影子控制寄存器,Guest OS 讀取控制寄存器時(shí),硬件將影子控制寄存器的值返回給 Guest OS。
VMCS 還包括一組位圖以提供更好的適應(yīng)性:
- Exception bitmap:選擇哪些異??梢杂|發(fā) VM exit,
- I/O bitmap:對(duì)哪些 16 位的 I/O 端口的訪問(wèn)觸發(fā) VM exit。
- MSR bitmaps:與控制寄存器掩碼相似,每個(gè) MSR 寄存器都有一組“讀”的位圖掩碼和一組“寫(xiě)”的位圖掩碼。
每次發(fā)生 VM exit時(shí),硬件自動(dòng)在 VMCS 中存入豐富的信息,方便 VMM 甄別事件的種類(lèi)和原因。VM entry 時(shí),VMM 可以方便地為 Guest OS 注入事件(中斷和異常),因?yàn)?VMCS 中存有 Guest OS 的中斷描述表(IDT)的地址,因此硬件能夠自動(dòng)地調(diào)用 Guest OS 的處理程序。
更詳細(xì)的信息請(qǐng)參閱 Intel 開(kāi)發(fā)手冊(cè) [5]。
解決純軟件虛擬化技術(shù)面臨的挑戰(zhàn)
首先,由于新的操作模式的引入,VMM 和 Guest OS 的執(zhí)行由硬件自動(dòng)隔離開(kāi)來(lái),任何關(guān)鍵的事件都可以將系統(tǒng)控制權(quán)自動(dòng)轉(zhuǎn)移到 VMM,因此 VMM 能夠完全控制系統(tǒng)的全部資源。
其次,Guest OS 可以運(yùn)行在它所期望的最高特權(quán)級(jí)別,因此特權(quán)級(jí)壓縮和特權(quán)級(jí)別名的問(wèn)題迎刃而解,而且 Guest OS 中的系統(tǒng)調(diào)用也不會(huì)觸發(fā) VM exit。
硬件使用物理地址訪問(wèn)虛擬機(jī)控制塊(VMCS),而 VMCS 保存了 VMM 和 Guest OS 各自的 IDTR 和 CR3 寄存器,因此 VMM 可以擁有獨(dú)立的地址空間,Guest OS 能夠完全控制自己的地址空間,地址空間壓縮的問(wèn)題也不存在了。
中斷和異常虛擬化的問(wèn)題也得到了很好的解決。VMM 只用簡(jiǎn)單地設(shè)置需要轉(zhuǎn)發(fā)的虛擬中斷或異常,在 VM entry 時(shí),硬件自動(dòng)調(diào)用 Guest OS 的中斷和異常處理程序,大大簡(jiǎn)化 VMM 的設(shè)計(jì)。同時(shí),Guest OS 對(duì)中斷的屏蔽及解除可以不觸發(fā) VM exit,從而提高了性能。而且 VMM 還可以設(shè)置當(dāng) Guest OS 解除中斷屏蔽時(shí)觸發(fā) VM exit,因此能夠及時(shí)地轉(zhuǎn)發(fā)積累的虛擬中斷和異常。
未來(lái)虛擬化技術(shù)的發(fā)展
我們可以看到,硬件輔助虛擬化技術(shù)必然是未來(lái)的方向。Intel-VT目前還處在處理器級(jí)虛擬化技術(shù)的初級(jí)階段,尚需在如下方面進(jìn)行發(fā)展:
- 提高操作模式間的轉(zhuǎn)換速度。
兩種操作模式間的轉(zhuǎn)換發(fā)生之如此頻繁,如果不能有效減少其轉(zhuǎn)換速度,即使充分利用硬件特性,虛擬機(jī)的整體性能也會(huì)大打折扣。早期的支持硬件輔助虛擬化技術(shù)的 Pentium 4 處理器需要花費(fèi) 2409 個(gè)時(shí)鐘周期處理 VM entry,花費(fèi) 508 個(gè)時(shí)鐘周期處理由缺頁(yè)異常觸發(fā)的 VM exit,代價(jià)相當(dāng)高。隨著 Intel 技術(shù)的不斷完善,在新的 Core 架構(gòu)上,相應(yīng)時(shí)間已經(jīng)減少到 937 和 446 個(gè)時(shí)鐘周期。未來(lái)硬件廠商還需要進(jìn)一步提高模式的轉(zhuǎn)換速度,并提供更多的硬件特性來(lái)減少不必要的轉(zhuǎn)換。
- 優(yōu)化翻譯后援緩沖器(TLB)的性能。
每次 VM entry 和 VM exit 發(fā)生時(shí),由于需要重新加載 CR3 寄存器,因此 TLB(Translation Lookaside Buffer)被完全清空。虛擬化系統(tǒng)中操作模式的轉(zhuǎn)換發(fā)生頻率相當(dāng)高,因此系統(tǒng)的整體性能受到明顯損害。一種可行的方案是為 VMM 和每個(gè)虛擬機(jī)分配一個(gè)全局唯一 ID,TLB 的每一項(xiàng)附加該 ID 信息來(lái)索引線性地址的翻譯。
- 提供內(nèi)存管理單元(MMU)虛擬化的硬件支持。
即使使用 Intel-VT 技術(shù),VMM 還是得用老辦法來(lái)處理 Guest OS 中發(fā)生的缺頁(yè)異常以及Guest OS 的客戶機(jī)物理地址到主機(jī)物理地址的翻譯,本質(zhì)原因是 VMM 完全控制主機(jī)物理內(nèi)存,因此 Guest OS 中的線性地址的翻譯同時(shí)牽涉到 VMM 和 Guest OS 的地址空間,而硬件只能看到其中的一個(gè)。Intel 和 AMD 提出了各自的解決方案,分別叫做 EPT(Extended Page Table)和 Nested Paging。這兩種技術(shù)的基本思想是,無(wú)論何時(shí)遇到客戶機(jī)物理地址,硬件自動(dòng)搜索 VMM 提供的關(guān)于該 Guest OS 的一個(gè)頁(yè)表,翻譯成主機(jī)物理地址,或產(chǎn)生缺頁(yè)異常來(lái)觸發(fā) VM exit。
- 支持高效的 I/O 虛擬化。
I/O 虛擬化需要考慮性能、可用性、可擴(kuò)展性、可靠性和成本等多種因素。最簡(jiǎn)單的方式是 VMM為虛擬機(jī)模擬一個(gè)常見(jiàn)的 I/O 設(shè)備,該設(shè)備的功能由 VMM 用軟件或復(fù)用主機(jī) I/O 設(shè)備的方法實(shí)現(xiàn)。例如 Virtual PC 虛擬機(jī)提供的是一種比較古老的 S3 Trio64顯卡。這種方式提高了兼容性,并充分利用 Guest OS 自帶的設(shè)備驅(qū)動(dòng)程序,但是虛擬的 I/O 設(shè)備功能有限且性能低下。為了提高性能,VMM 可以直接將主機(jī) I/O 設(shè)備分配給虛擬機(jī),這會(huì)帶來(lái)兩個(gè)主要挑戰(zhàn):1. 如果多個(gè)虛擬機(jī)可以復(fù)用同一個(gè)設(shè)備,VMM 必須保證它們對(duì)設(shè)備的訪問(wèn)不會(huì)互相干擾。2. 如果 Guest OS 使用 DMA 的方式訪問(wèn) I/O 設(shè)備,由于 Guest OS 給出的地址并不是主機(jī)物理地址,VMM 必須保證在啟動(dòng) DMA 操作前將該地址正確轉(zhuǎn)換。Intel 和 AMD 分別提出了各自的解決方案,分別稱(chēng)為 Direct I/O(VT-d)和 IOMMU,希望用硬件的手段解決這些問(wèn)題,降低 VMM 實(shí)現(xiàn)的難度。

 |

|
結(jié)束語(yǔ)
本文針對(duì) x86 平臺(tái),介紹虛擬化技術(shù)的基本知識(shí),希望對(duì)讀者的工作和學(xué)習(xí)有所裨益,更多詳細(xì)信息請(qǐng)參閱參考資料一節(jié)。
參考資料
|