本篇博文主要介紹虛擬化的基本思想以及在arm平臺(tái)如何做虛擬化,arm提供的硬件feature等等。 虛擬化技術(shù)簡(jiǎn)介虛擬化技術(shù)虛擬化是一個(gè)概念,單從這個(gè)概念的角度來看,只要是用某一種物品去模擬另一種物品都可以稱為虛擬化,甚至于有些飯店用豆腐做出肉的味道,我認(rèn)為這也可以稱為一種虛擬化。但是這里我們主要討論的是計(jì)算機(jī)領(lǐng)域的虛擬化,我們這樣定義虛擬化“虛擬化是將單一物理設(shè)備模擬為相互隔離的多個(gè)虛擬設(shè)備,同時(shí)保證這些虛擬設(shè)備的高效性”。這個(gè)概念的定義里還包含了對(duì)虛擬化的要求,也就是這里的隔離性(isolated)和有效性(efficient)。我們常說的hypervisor,有些書也把它稱為VMM(virtual machine monitor)則是一個(gè)直接運(yùn)行在物理硬件上的軟件,它的功能就是管理物理硬件,以便在不同的虛擬機(jī)之間共享這些物理資源(cpu,內(nèi)存,外設(shè)等等),既然hypervisor直接給物理外設(shè)打交道,那它當(dāng)然需要運(yùn)行在特權(quán)模式了,在過去沒有virtualization extesion的情況下,guest os和guest application只能都運(yùn)行在de-privileged模式,如下圖所示。
Popek和Goldberg提出構(gòu)建hypervisor的要求:敏感指令是特權(quán)指令的子集。這種標(biāo)準(zhǔn)現(xiàn)在被稱為classically virtualized(經(jīng)典可虛擬化模型),雖然在不滿足這個(gè)要求的情況下也可以做虛擬化(二進(jìn)制翻譯技術(shù),后面會(huì)介紹),但是如果滿足這個(gè)要求,實(shí)現(xiàn)起來會(huì)容易很多。下面介紹現(xiàn)有的虛擬化技術(shù):
虛擬化技術(shù)的比較Pure virtualization and binary rewritingpure virtualization和binary rewriting都是不修改機(jī)器的API的,所以任何guest os都可以直接運(yùn)行在虛擬化環(huán)境。但是,由于所有的特權(quán)指令都會(huì)導(dǎo)致trap,所以在虛擬環(huán)境下特權(quán)指令的執(zhí)行開銷要遠(yuǎn)遠(yuǎn)高于在native環(huán)境下。以前,x86和ARM都不符合classically virtualized時(shí),VMWare采用binary rewriting在x86架構(gòu)上實(shí)現(xiàn)虛擬化,經(jīng)過優(yōu)化后的性能開銷小于10%,但是這項(xiàng)技術(shù)十分復(fù)雜。由于實(shí)現(xiàn)起來的復(fù)雜,就會(huì)增加運(yùn)行在特權(quán)模式下的代碼,這會(huì)增加attack surface和hypervisor出現(xiàn)bug的幾率,所以會(huì)降低整個(gè)系統(tǒng)的安全性和隔離性。 Para-virtualizationPara-virtualization雖然是一個(gè)新詞,在2002年中的Denali virtual machine monitor被提出來。但是這種設(shè)計(jì)理念早在1970的IBM的CMS系統(tǒng)就出現(xiàn)了,當(dāng)時(shí)使用DIAG指令調(diào)用到hypervisor里去,并且一直到現(xiàn)在還有很多研究機(jī)構(gòu)在使用這種理念,如Mach,Xen和L4。 Virtual memory in virtualization environment為什么要把內(nèi)存管理部分單獨(dú)拿出來討論一下呢?因?yàn)檫@部分很復(fù)雜,其實(shí)之前我們討論的內(nèi)容主要都是cpu運(yùn)行的問題,比如各種指令和各種模式之間的切換。關(guān)于內(nèi)存,我們先討論沒有引入guest os時(shí)的虛擬內(nèi)存管理,然后再討論引入guest os之后的變化。 這個(gè)圖表現(xiàn)的很清晰,但是想實(shí)現(xiàn)是非常難的,因?yàn)橹挥幸粋€(gè)頁表基址寄存器,所以硬件無法識(shí)別是從guest va到guest pa的轉(zhuǎn)換還是va到pa的轉(zhuǎn)換,在沒有硬件支持的情況下,只能通過影子頁表才能實(shí)現(xiàn),影子頁表的原理也是把兩步轉(zhuǎn)換(guest va->guest pa->pa)轉(zhuǎn)換為一步,中間的同步用hash來做。影子頁表在構(gòu)建的時(shí)候,每次對(duì)guest page table的訪問都需要trap,由hypervisor把guest pa轉(zhuǎn)換成實(shí)際物理地址。如果讀者想了解這一塊內(nèi)容,我建議深入學(xué)習(xí)一下KVM以前關(guān)于影子頁表的實(shí)現(xiàn)(由于x86的硬件支持,目前KVM已經(jīng)放棄影子頁表),這里我們沒辦法深入探討影子頁表,但了解它大致是怎么一回事兒之后,我們可以分析以下它的性能。首先,它的性能一定非常不好,因?yàn)槊看螌?duì)guest page table的訪問都需要trap,而且每次guest page table的修改還需要同步到影子頁表上面,雖然用hash的方式能提速,但是相比于native環(huán)境性能差距比較大(NOVA做過一個(gè)實(shí)驗(yàn),光訪問頁表的性能損失大約是23%),而且實(shí)現(xiàn)起來非常復(fù)雜。Intel和ARM對(duì)這一部分都提供了硬件支持,由硬件來完成這里提到的兩級(jí)頁表轉(zhuǎn)換。其實(shí)根據(jù)程序運(yùn)行時(shí)的局部性原理,如果每次訪問都能TLB hit的話,這種二級(jí)頁表轉(zhuǎn)換和一級(jí)頁表轉(zhuǎn)換差別不大,但是當(dāng)TLB miss的時(shí)候,需要訪問two stage的頁表訪問的性能還是差別比較大的,盡管這部分由硬件來做。舉個(gè)例子,比如KVM在Linux-64位的情況下,是4級(jí)頁表轉(zhuǎn)換,從va到pa需要訪問5次頁表,那么引入two stage之后,就需要5*5=25次訪問頁表,讀者可以思考一下這里為什么是相乘的關(guān)系。 ARM介紹我們首先介紹ARM架構(gòu)里的各個(gè)部分,介紹它們的目的是為了理解當(dāng)arm引入virtualization extension之后對(duì)它們的影響。 ARM總體介紹arm是一種精簡(jiǎn)指令集(reduced instruction set computer,RISC)架構(gòu),精簡(jiǎn)(reduced)的意思是每條匯編指令獨(dú)自完成所有的工作,而與之相對(duì)的復(fù)雜指令集則不是,它的一條匯編指令可能會(huì)翻譯成好幾條機(jī)器指令。大部分精簡(jiǎn)指令集的指令都在單個(gè)時(shí)鐘周期內(nèi)完成,它采用一種讀取和存儲(chǔ)分開的架構(gòu)(load-store architecture),數(shù)據(jù)處理指令和I/O指令是分開的,數(shù)據(jù)處理指令是操作一個(gè)寄存器的值,和復(fù)雜指令集不同,關(guān)于復(fù)雜指令集的對(duì)應(yīng)操作讀者請(qǐng)自行查閱資料?,F(xiàn)在arm已經(jīng)推出v8架構(gòu),關(guān)于v8架構(gòu)我還不太熟,所以這里以v7作為介紹(后續(xù)有時(shí)間我會(huì)研究下v8,在這里進(jìn)行補(bǔ)充)。v7架構(gòu)包含16個(gè)32bit的通用寄存器,還有一些寄存器是和特定的處理器模式相關(guān)的,還有各種協(xié)處理器的寄存器,這些寄存器將會(huì)在后面展開敘述。 ARM協(xié)處理器介紹ARM協(xié)處理器是ARM架構(gòu)的重要擴(kuò)展,ARM架構(gòu)允許最多16個(gè)協(xié)處理器,其中cp15被保留完成各種控制。cp15作用非常強(qiáng)大,它控制整個(gè)系統(tǒng)配置,cache和TLB的管理,MMU的控制和系統(tǒng)性能監(jiān)控,我們這里主要討論cp15的內(nèi)存管理功能。 處理器模式和TrustZoneARM v7包含8種處理器模式(在v8已經(jīng)變成4種exception level了,從EL0到El3),其中包含1種非特權(quán)模式和7種特權(quán)模式:
顯然,除了應(yīng)用程序運(yùn)行在user模式以外,其他全部運(yùn)行在特權(quán)模式。ARM的virtualization extension需要處理器支持TrustZone extension,我們來看一下TrustZone是什么。TrustZone將處理器的執(zhí)行狀態(tài)分為兩個(gè)世界:
這里的兩個(gè)世界和處理器模式是重疊的,軟件可以在任何模式、任何世界上運(yùn)行。那么secure world和non-secure world的區(qū)別在哪呢?這里的secure又從何而來?是這樣的,secure world有自己獨(dú)有的內(nèi)存和外設(shè),這部分內(nèi)容只有運(yùn)行在secure world的軟件可以訪問,運(yùn)行在non-secure world的軟件是不可以訪問的。這里引入了一個(gè)新的處理器模式,monitor mode,它運(yùn)行在secure world,被用于做雙系統(tǒng)(secure and non-secure world)之間的切換,如下圖所示。 我們可以基于TrustZone去做虛擬化,因?yàn)樗軌蚋綦x內(nèi)存、中斷并且確保non-secure world的特權(quán)軟件也不可能訪問或者修改運(yùn)行在secure world的軟件的配置信息。然后這樣做的缺陷是,在non-secure world只能運(yùn)行一個(gè)guest os,在secure world運(yùn)行一個(gè)hypervisor。Green Hill的INTEGRITY就是這樣做的,感興趣的讀者可以去Google一下。 中斷控制器GIC(generic interrupt controller)是ARM里的中斷控制器,現(xiàn)在也已經(jīng)支持virtualization extension。GIC可以分為兩部分:
當(dāng)外設(shè)產(chǎn)生中斷的時(shí)候,這個(gè)中斷首先發(fā)送給Distributor,Distributor將這個(gè)中斷發(fā)送給對(duì)應(yīng)的cpu interface。當(dāng)cpu interface接受到這個(gè)中斷的時(shí)候,它會(huì)檢查這個(gè)中斷是否enable,如果enable再去比較這個(gè)中斷的優(yōu)先級(jí)和當(dāng)前正在處理的中斷的優(yōu)先級(jí),進(jìn)而決定處理器是否立即處理這個(gè)中斷。 Virtualization Issues with the ARM Architecture標(biāo)準(zhǔn)的ARM架構(gòu)是不符合可虛擬化模型的,有很多敏感指令在非特權(quán)模式下執(zhí)行卻不會(huì)產(chǎn)生trap。比如CPS指令,這條指令的作用是改變處理器狀態(tài),當(dāng)這條指令在用戶態(tài)執(zhí)行時(shí)不會(huì)產(chǎn)生trap,甚至沒有任何效果,可以認(rèn)為是簡(jiǎn)單的跳過。即使所有的敏感指令都會(huì)產(chǎn)生trap,在ARM架構(gòu)上用上述的trap-and-emulate技術(shù)也是很困難的,因?yàn)锳RM的敏感指令非常多,只要和特權(quán)資源交互的指令都是敏感指令,比如虛擬內(nèi)存子系統(tǒng),中斷控制子系統(tǒng)和協(xié)處理器,用上述方式的話開銷太大,對(duì)系統(tǒng)性能有很大沖擊。比如,arm-v7架構(gòu)不支持頁表訪問的虛擬化,那么就需要影子頁表,每次訪問guest pa都需要trap,同樣地,中斷控制器也需要被仿真,當(dāng)中斷很頻繁的時(shí)候(timer tick),這種仿真的開銷也是非常大的,為了克服這種種弊端,ARM推出了virtualization extension。 ARM對(duì)虛擬化的硬件支持在討論arm新增加的virtualization extension之前,我們知道對(duì)硬件虛擬化的支持主要有intel的VT-x和AMD的AMD-V,它們兩個(gè)十分類似,所以這里我們只介紹VT-x,看看它對(duì)虛擬化做了怎樣的支持(為后面做對(duì)比)。
接下來我們看看ARM對(duì)虛擬化的支持,這里討論的虛擬化支持主要是針對(duì)v7架構(gòu),并且需要實(shí)現(xiàn)上文提到的TrustZone。利用硬件擴(kuò)展實(shí)現(xiàn)pure virtualization的總體架構(gòu)如下圖所示:
上述內(nèi)容是對(duì)虛擬化擴(kuò)展的一個(gè)總體介紹,具體來說,ARM新增了以下幾個(gè)feature:
讀者可以自行對(duì)比Intel和ARM對(duì)虛擬化支持的相同點(diǎn)和不同點(diǎn),分析他們?yōu)槭裁催@樣做。接下來展開敘述上文提到的中斷控制部分。 中斷控制ARM創(chuàng)建了一個(gè)新的硬件模塊,virtual CPU interface,類比我們前面在介紹GIC時(shí)提到過的CPU interface,這個(gè)硬件模塊可以直接被map到guest os里,從而避免使用trap-and-emulate去仿真CPU interface,guest os可以直接操作這個(gè)virtual CPU interface,例如開、關(guān)中斷。當(dāng)然關(guān)于GIC的另一個(gè)部分,Distributor,我們?nèi)匀恍枰ㄟ^trap-and-emulate去仿真,但是它對(duì)性能的影響不大,因?yàn)樗皇窃诔跏蓟臅r(shí)候負(fù)責(zé)enable中斷,之后就不再修改了。
這里面還涉及一個(gè)硬件擴(kuò)展,論文上把它稱為“priority drop”。正常情況下,當(dāng)一個(gè)中斷正在處理的時(shí)候,低優(yōu)先級(jí)的中斷是不能夠搶占處理器的,但是在虛擬化環(huán)境卻不是這樣,比方說有兩個(gè)guest os,我們暫且稱之為os1和os2,假設(shè)os1正在處理一個(gè)高優(yōu)先級(jí)中斷,這時(shí)又有一個(gè)中斷是給os2處理的,這個(gè)中斷的優(yōu)先級(jí)低于os1的中斷的優(yōu)先級(jí),但是它們應(yīng)該互不影響才對(duì)。ARM加入這個(gè)硬件擴(kuò)展就是為了處理上述問題,每個(gè)guest os都有自己的優(yōu)先級(jí)屏蔽策略,互不影響。 |
|