• 正文
    • 1. 前言
    • 2. Split-mode虛擬化
    • 3. CPU虛擬化
    • 4. 內(nèi)存虛擬化
    • 5. I/O虛擬化
    • 6. 中斷虛擬化
    • 7. 計(jì)時(shí)器虛擬化
    • 8. ARM體系結(jié)構(gòu)的改進(jìn)
  • 相關(guān)推薦
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

KVM/ARM——基于ARM虛擬化擴(kuò)展的VMM

01/29 09:55
1472
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

1. 前言

ARM架構(gòu)為了支持虛擬化做了些擴(kuò)展,稱(chēng)為虛擬化擴(kuò)展(Virtualization Extensions)。原先為VT-x創(chuàng)建的KVM(Linux-based Kernel Virtual Machine)適配了ARM體系結(jié)構(gòu),引入了KVM/ARM (the Linux ARM hypervisor)。KVM/ARM沒(méi)有在hypervisor中引入復(fù)雜的核心功能,而是利用了Linux內(nèi)核中現(xiàn)有的功能進(jìn)行適配。KVM/ARM與Linux集成,在可移植性和硬件支持方面會(huì)有所收益。其實(shí)也可以開(kāi)發(fā)獨(dú)立的bare metal hypervisor,這樣可能會(huì)有更好地性能,但這種方法在ARM上不太好使。

在下面,我們將描述KVM/ARM的設(shè)計(jì)如何使得它可以從現(xiàn)有kernel的集成中獲益,同時(shí)利用硬件虛擬化特性。

2. Split-mode虛擬化

KVM/ARM利用了現(xiàn)有的kernel功能,例如調(diào)度器(scheduler),但KVM/ARM如果直接在EL2中運(yùn)行Linux kernel,會(huì)存在兩個(gè)問(wèn)題。

第一,linux中與底層體系結(jié)構(gòu)相關(guān)的代碼是為在kernel模式下工作而編寫(xiě)的,不經(jīng)過(guò)修改就不能在EL2中運(yùn)行,因?yàn)镋L2是一個(gè)完全不同于普通kernel模式的CPU模式。Linux kernel社區(qū)不太可能接受在EL2中運(yùn)行kernel所需的重大更改。更重要的是,為了保持與沒(méi)有EL2的硬件的兼容性并將Linux作為Guest OS運(yùn)行,必須編寫(xiě)低級(jí)代碼以在兩種模式下工作,這可能會(huì)導(dǎo)致緩慢而復(fù)雜的代碼路徑。舉個(gè)簡(jiǎn)單的例子,頁(yè)表錯(cuò)誤處理程序需要獲取導(dǎo)致頁(yè)表錯(cuò)誤的虛擬地址。在EL2中,這個(gè)地址存儲(chǔ)在與kernel模式不同的寄存器中。

第二,在EL2中運(yùn)行整個(gè)內(nèi)核會(huì)對(duì)本機(jī)性能產(chǎn)生不利影響。例如,EL2有自己獨(dú)立的地址空間,但是kernel模式使用兩個(gè)頁(yè)表基本寄存器(TTBR)在user地址空間和kernel地址空間之間提供熟悉的3GB/1GB分割,而EL2使用單個(gè)頁(yè)表寄存器,因此不能直接訪(fǎng)問(wèn)地址空間的user空間部分。經(jīng)常使用的訪(fǎng)問(wèn)user內(nèi)存的函數(shù)需要kernel顯式地將用戶(hù)空間數(shù)據(jù)映射到kernel地址空間,然后執(zhí)行必要的拆解和TLB維護(hù)操作,從而導(dǎo)致ARM的性能不好。

綜上所述,KVM/ARM引入了split-mode虛擬化,這種一種新的hypervisor設(shè)計(jì)方法,它將核心hypervisor分開(kāi),以便它可以跨不同的特權(quán)CPU模式運(yùn)行,從而利用每種CPU模式提供的特定優(yōu)勢(shì)和功能。KVM/ARM使用split-mode虛擬化來(lái)利用EL2支持的ARM硬件虛擬化,同時(shí)利用在kernel模式下運(yùn)行的現(xiàn)有Linux kernel服務(wù)。Split-mode虛擬化允許KVM/ARM與Linux kernel集成,而無(wú)需對(duì)現(xiàn)有代碼庫(kù)進(jìn)行重大修改。

這是通過(guò)將hypervisor分成兩個(gè)組件來(lái)實(shí)現(xiàn)的:lowvisorhighvisor,如圖1所示。

圖1 KVM/ARM系統(tǒng)架構(gòu)

Lowvisor的設(shè)計(jì)是利用EL2中提供的硬件虛擬化支持來(lái)提供三個(gè)關(guān)鍵功能。首先,lowvisor通過(guò)適當(dāng)?shù)挠布渲脕?lái)設(shè)置正確的執(zhí)行上下文,并在不同的執(zhí)行上下文之間實(shí)施保護(hù)和隔離。Lowvisor直接與硬件保護(hù)功能交互,因此非常關(guān)鍵,且代碼庫(kù)需要保持絕對(duì)最小。其次,lowvisor從VM執(zhí)行上下文切到到host執(zhí)行上下文,反之亦然。Host執(zhí)行上下文用于運(yùn)行hypervisor和host Linux kernel。我們將執(zhí)行上下文稱(chēng)為一個(gè)世界,將從一個(gè)世界切換到另一個(gè)世界稱(chēng)為世界切換(world switch),因?yàn)橄到y(tǒng)的整個(gè)狀態(tài)都發(fā)生了變化。由于lowvisor是唯一在EL2中運(yùn)行的組件,因此只有它可以負(fù)責(zé)執(zhí)行世界切換所需的硬件重新配置。第三,lowvisor提供了一個(gè)虛擬化Trap處理程序,它處理必須Trap到hypervisor的中斷和異常。所有發(fā)送到hypervisor的Trap必須首先發(fā)送到lowvisor。在世界切換到highvisor完成后,lowvisor只執(zhí)行所需的最少量的處理,并將要完成的大部分工作推遲到highvisor。

Highvisor作為host linux kernel的一部分在kernel模式下運(yùn)行。因此,它可以直接利用現(xiàn)有的linux功能,例如調(diào)度器,并且可以利用標(biāo)準(zhǔn)的kernel軟件數(shù)據(jù)結(jié)構(gòu)和機(jī)制來(lái)實(shí)現(xiàn)其功能,例如locking機(jī)制和memory分配功能。它使高層功能更容易在highvisor中實(shí)現(xiàn)。例如,雖然lowvisor提供低級(jí)Trap處理程序和低級(jí)機(jī)制來(lái)從一個(gè)世界切換到另一個(gè)世界,但highvisor處理來(lái)自VM和的stage-2頁(yè)表錯(cuò)誤并執(zhí)行指令仿真。請(qǐng)注意,部分VM以kernel模式運(yùn)行,就像highvisor一樣,但是啟用了stage-2轉(zhuǎn)換和Trap到EL2。

因?yàn)閔ypervisor在kernel模式和EL2之間是分開(kāi)的,所以在VM和highvisor之間的切換涉及到多個(gè)模式轉(zhuǎn)換。在運(yùn)行VM時(shí),向highvisor發(fā)出Trap將首先向EL2中l(wèi)owvisor發(fā)出Trap。然后lowvisor將發(fā)起另一個(gè)Trap去運(yùn)行highvisor。類(lèi)似地,從highvisor切換到VM需要從kernel模式切換到EL2,然后切換到VM。因此,在切換到或切換出highvisor時(shí),split-mode虛擬化會(huì)產(chǎn)生雙重Trap成本。在ARM上,執(zhí)行這些模式轉(zhuǎn)換到EL2或從EL2轉(zhuǎn)換的唯一方法就是通過(guò)Trap。不過(guò),這個(gè)額外的Trap在ARM上并不是一個(gè)顯著的性能成本。

KVM/ARM使用內(nèi)存映射接口根據(jù)需要在highvisor和lowvisor之間共享數(shù)據(jù)。由于內(nèi)存管理可能很復(fù)雜,它利用了linux中現(xiàn)有內(nèi)存管理子系統(tǒng)的功能來(lái)管理highvisor和lowvisor的內(nèi)存。但是管理lowvisor的內(nèi)存涉及到額外的挑戰(zhàn),它需要管理EL2的單獨(dú)地址空間。一種簡(jiǎn)單的方法是重用host kernel的頁(yè)表,并在EL2中使用它們來(lái)使地址空間相同。不過(guò)這樣有問(wèn)題,因?yàn)镋L2使用和kernel模式不同的頁(yè)表格式。因此,highvisor顯式地管理EL2頁(yè)表,將在EL2中執(zhí)行的任何代碼以及highvisor和lowvisor之間共享的任何數(shù)據(jù)結(jié)構(gòu)映射到EL2和kernel模式中的相同虛擬地址。

3. CPU虛擬化

為了虛擬化CPU,KVM/ARM必須向VM提供一個(gè)接口,該接口本質(zhì)上與底層的實(shí)際硬件相同,同時(shí)確保hypervisor仍然控制硬件。它包括確保在虛擬機(jī)中運(yùn)行的軟件必須與在物理CPU上運(yùn)行的軟件具有對(duì)相同寄存器狀態(tài)的一致訪(fǎng)問(wèn),以及確保切換VM運(yùn)行中,與hypervisor及其host kernel相關(guān)聯(lián)的物理硬件狀態(tài)是一致的。為了不影響VM隔離,寄存器狀態(tài)可以簡(jiǎn)單地通過(guò)保存VM狀態(tài)和從VM切換到host時(shí)從內(nèi)存恢復(fù)主機(jī)狀態(tài)進(jìn)行上下文切換,反之亦然。KVM/ARM將對(duì)所有其它敏感狀態(tài)的訪(fǎng)問(wèn)配置為T(mén)rap到EL2,因此hypervisor可以模擬它。

表1為在kernel模式和user模式下運(yùn)行的軟件可以看到的寄存器狀態(tài),以及KVM/ARM對(duì)每個(gè)寄存器組的虛擬化方法。Lowvisor有自己專(zhuān)用的配置寄存器,僅供EL2使用。只要硬件支持,在世界切換期間,KVM/ARM上下文會(huì)切換寄存器,因?yàn)樗试SVM直接訪(fǎng)問(wèn)硬件。例如,VM可以直接對(duì)stage-1頁(yè)表基本寄存器進(jìn)行編程,而不需要Trap到hypervisor,這在大多數(shù)Guest OS中是相當(dāng)常見(jiàn)的操作。KVM/ARM在敏感指令和訪(fǎng)問(wèn)硬件狀態(tài)時(shí)執(zhí)行Trap和模擬,這些狀態(tài)可能會(huì)影響hypervisor或?qū)⒂嘘P(guān)硬件的信息泄漏給VM,違反了虛擬化原理。例如。如果VM執(zhí)行導(dǎo)致CPU斷電的WFI指令,KVM/ARM會(huì)Trap,這樣的操作應(yīng)該只由hypervisor執(zhí)行,以保持對(duì)硬件的控制。

表1 VM和Host的狀態(tài)

在kernel或user模式下運(yùn)行虛擬機(jī)與在kernel或user模式下運(yùn)行hypervisor之間的區(qū)別取決于EL2在世界切換期間如何配置virtualization extensions。從host切換到VM的過(guò)程如下:

將所有host GP寄存器存到EL2的堆棧中;

給VM配置vGIC;

給VM配置timers;

將所有host特定的配置寄存器存到EL2堆棧中;

將VM的配置寄存器加載到硬件,這個(gè)操作不會(huì)影響當(dāng)前執(zhí)行,因?yàn)镋L2使用它自己的配置寄存器,這些寄存器從host狀態(tài)中分離出來(lái)。

配置EL2以Trap浮點(diǎn)操作(VFP寄存器的lazy context switching),trap中斷,trap CPU halt指令(WFI/WFE),trap SMC指令,Trap特定配置寄存器訪(fǎng)問(wèn)和trao調(diào)試寄存器訪(fǎng)問(wèn);

將虛擬機(jī)特定的ID寫(xiě)入shadow ID寄存器中,這由ARM虛擬化擴(kuò)展定義,并由虛擬機(jī)訪(fǎng)問(wèn),以代替ID寄存器中的硬件值;

設(shè)置stage-2頁(yè)表基寄存器(VTTBR)并啟用stage-2地址轉(zhuǎn)換;

恢復(fù)所有g(shù)uest GP寄存器;

進(jìn)入user模式或kernel模式;

CPU將留在虛擬機(jī)世界,直到有event發(fā)生,觸發(fā)進(jìn)入EL2的trap。這樣的事件可能由上面提到的任何Trap、stage-2頁(yè)表錯(cuò)誤或硬件中斷引起。由于event需要highvisor的服務(wù),要么模擬虛擬機(jī)預(yù)期的硬件行為,要么服務(wù)于設(shè)備中斷,KVM/ARM必須執(zhí)行另一個(gè)世界切換到highvisor和它的host。這需要先到lowvisor,然后再到highvisor。從VM世界切換到host世界需要以下步驟:

保存所有VM GP寄存器;

關(guān)閉stage-2轉(zhuǎn)換;

配置EL2不Trap任何寄存器訪(fǎng)問(wèn)和指令;

保存所有VM特定的配置寄存器;

加載host的配置寄存器到硬件;

配置host的timers;

保存VM特定的vGIC狀態(tài);

恢復(fù)所有host GP寄存器

進(jìn)入kernel模式;

4. 內(nèi)存虛擬化

如圖2所示,ARM提供了stage-2頁(yè)表來(lái)將Guest物理地址轉(zhuǎn)換為host物理地址。KVM/ARM通過(guò)啟用stage-2轉(zhuǎn)換,為在虛擬機(jī)中運(yùn)行時(shí)為所有內(nèi)存訪(fǎng)問(wèn)提供內(nèi)存虛擬化。Stage-2轉(zhuǎn)換只能在EL2中配置,它的使用對(duì)VM是完全透明的。Highvisor管理stage-2翻譯頁(yè)表,只允許訪(fǎng)問(wèn)專(zhuān)門(mén)為VM分配的內(nèi)存。其它訪(fǎng)問(wèn)將導(dǎo)致stage-2頁(yè)表錯(cuò)誤,從而Trap到hypervisor。該機(jī)制確保虛擬機(jī)不能訪(fǎng)問(wèn)hypervisor或其它虛擬機(jī)的內(nèi)存,包括任何敏感數(shù)據(jù)。在highvisor和lowvisor中運(yùn)行時(shí)禁用stage-2轉(zhuǎn)換,因?yàn)閔ighvisor完全控制整個(gè)系統(tǒng)并直接管理host物理地址。當(dāng)hypervisor切換到VM時(shí),它啟用stage-2轉(zhuǎn)換并相應(yīng)地配置stage-2頁(yè)表基寄存器。盡管highvisor和VM共享相同的CPU模式,但stage-2轉(zhuǎn)換確保highvisor不受VM的任何訪(fǎng)問(wèn)。

圖2 ARM的兩級(jí)頁(yè)表

KVM/ARM是一個(gè)split-mode虛擬化來(lái)利用現(xiàn)有的kernel內(nèi)存分配、頁(yè)表引用計(jì)數(shù)和頁(yè)表操作代碼。KVM/ARM通過(guò)考慮出錯(cuò)的gPA來(lái)處理stage-2頁(yè)表出錯(cuò),以及該地址是否屬于VM內(nèi)存映射,KVM/ARM通過(guò)簡(jiǎn)單地調(diào)用一個(gè)現(xiàn)有的kernel函數(shù)(如get_user_pages)為VM分配一個(gè)頁(yè)表,并將分配的頁(yè)表映射到stage-2頁(yè)表中的VM。

5. I/O虛擬化

KVM/ARM利用現(xiàn)有的QEMU和Virtio user空間設(shè)備模擬來(lái)提供I/O虛擬化。在硬件層面上,ARM架構(gòu)上的所有I/O機(jī)制都是基于對(duì)MMIO設(shè)備區(qū)域的load/store操作。除了直接分配給VM的設(shè)備,所有硬件MMIO區(qū)域不能被虛擬機(jī)訪(fǎng)問(wèn)。KVM/ARM使用stage-2轉(zhuǎn)換來(lái)確保不能從虛擬機(jī)直接訪(fǎng)問(wèn)物理設(shè)備。在為VM分配的RAM區(qū)域之外的任何訪(fǎng)問(wèn)都將被hypervisor Trap,hypervisor可以根據(jù)fault地址將訪(fǎng)問(wèn)路由到QEMU中的特定模擬設(shè)備。

6. 中斷虛擬化

KVM/ARM利用其與Linux的集成來(lái)重用現(xiàn)有的設(shè)備驅(qū)動(dòng)程序和相關(guān)功能,包括處理中斷。當(dāng)在虛擬機(jī)中運(yùn)行時(shí),KVM/ARM配置CPU將所有硬件中斷Trap到EL2。在每個(gè)中斷中,它執(zhí)行到hypervisor的世界切換,host處理中斷,這樣hypervisor就可以保留完全控制硬件資源。當(dāng)在host和highvisor中運(yùn)行時(shí),中斷直接Trap到kernel模式,避免通過(guò)EL2的開(kāi)銷(xiāo)。在這兩種情況下,所有硬件中斷處理都是通過(guò)重用Linux現(xiàn)有的中斷處理功能在host中完成的。

但是,虛擬機(jī)必須以虛擬中斷的形式接收來(lái)自模擬設(shè)備的通知,multicore Guest OSs必須能夠從一個(gè)虛擬core發(fā)送虛擬IPIs到另一個(gè)虛擬xore。KVM/ARM通過(guò)vGIC向虛擬機(jī)注入虛擬中斷,減少EL2的Trap數(shù)量。通過(guò)編程vGIC hypervisor CPU控制接口中的list registers,虛擬中斷被提升到虛擬CPU。KVM/ARM配置stage-2頁(yè)表,來(lái)防止虛擬機(jī)訪(fǎng)問(wèn)控制接口,只允許訪(fǎng)問(wèn)vGIC虛擬CPU接口,保證只有hypervisor可以編程控制接口,虛擬機(jī)可以直接訪(fǎng)問(wèn)vGIC虛擬接口。然而,Guest OS仍然會(huì)嘗試訪(fǎng)問(wèn)GIC分發(fā)器來(lái)配置GIC,并講IPI從一個(gè)虛擬core發(fā)送到另一個(gè)虛擬core。這樣的訪(fǎng)問(wèn)將Trap到hypervisor,hypervisor必須模擬分發(fā)程序。

KVM/ARM引入了虛擬分發(fā)器,這是GIC分發(fā)器的一個(gè)軟件模型,作為highvisor的一部分。虛擬分發(fā)器向User空間公開(kāi)接口,因此user空間中的模擬設(shè)備可以向虛擬分發(fā)器發(fā)起虛擬中斷,并向VM公開(kāi)與物理GIC分發(fā)器相同的MMIO接口。虛擬分發(fā)器保存關(guān)于每個(gè)中斷狀態(tài)的內(nèi)部軟件狀態(tài),并在調(diào)度VM時(shí)使用此狀態(tài),編程list registers以注入虛擬中斷。例如,如果虛擬CPU0向虛擬CPU1發(fā)送一個(gè)IPI,分發(fā)程序?qū)⒕幊烫摂MCPU1的list registers以引發(fā)一個(gè)虛擬IPI中斷給虛擬CPU1。

理想情況下,虛擬分發(fā)程序只在必要時(shí)訪(fǎng)問(wèn)硬件list registers,因?yàn)樵O(shè)備MMIO操作通常比cache內(nèi)存訪(fǎng)問(wèn)慢得多。當(dāng)調(diào)度不同的VM在物理core上運(yùn)行時(shí),需要list registers的完整上下文切換,但當(dāng)簡(jiǎn)單地在VM和hypervisor之間切換時(shí),則不一定需要上下文切換。例如,如果沒(méi)有掛起的虛擬中斷,則不需要訪(fǎng)問(wèn)任何list register。注意,一旦hypervisor在切換到VM時(shí)將一個(gè)虛擬中斷寫(xiě)入一個(gè)list register,那么在切換會(huì)hypervisor時(shí),它還必須讀回這個(gè)list register,因?yàn)閘ist register描述了虛擬中斷的狀態(tài)。KVM/ARM的初始未優(yōu)化版本使用了一種簡(jiǎn)單的方法,該方法完全切換所有vGIC狀態(tài),包括每個(gè)世界開(kāi)關(guān)上的list register。

7. 計(jì)時(shí)器虛擬化

讀取計(jì)數(shù)器和編程計(jì)時(shí)器是許多操作系統(tǒng)中用于進(jìn)程調(diào)度和定期輪詢(xún)?cè)O(shè)備狀態(tài)的常見(jiàn)操作。例如,Linux讀取一個(gè)計(jì)數(shù)器來(lái)確定進(jìn)程是否已經(jīng)過(guò)期,并編程計(jì)數(shù)器來(lái)確保進(jìn)程沒(méi)有超出其允許的時(shí)間片段。由于各種原因,應(yīng)用程序工作負(fù)載也經(jīng)常使用計(jì)時(shí)器。為每個(gè)這樣的操作Trap到hypervisor可能會(huì)導(dǎo)致明顯的性能開(kāi)銷(xiāo),并且允許VM直接訪(fǎng)問(wèn)計(jì)時(shí)硬件通常意味著放棄對(duì)硬件資源的定時(shí)控制,因?yàn)閂M可以禁用計(jì)時(shí)器并在較長(zhǎng)的時(shí)間內(nèi)控制CPU。

KVM/ARM利用ARM的通用定時(shí)器的硬件虛擬化特性來(lái)允許虛擬機(jī)直接訪(fǎng)問(wèn)可讀計(jì)數(shù)器和編程計(jì)時(shí)器,而不會(huì)引起Trap到EL2,同時(shí)確保hypervisor仍然控制硬件。由于使用EL2控制對(duì)物理計(jì)時(shí)器的訪(fǎng)問(wèn),因此任何控制EL2模式的軟件都可以訪(fǎng)問(wèn)物理計(jì)時(shí)器。KVM/ARM通過(guò)使用hypervisor中的物理計(jì)時(shí)器和不允許從虛擬機(jī)訪(fǎng)問(wèn)物理計(jì)時(shí)器來(lái)維護(hù)硬件控制。作為Guest OS運(yùn)行的Linux kernel只能訪(fǎng)問(wèn)虛擬計(jì)時(shí)器,因此可以直接訪(fǎng)問(wèn)計(jì)時(shí)器硬件,而不會(huì)被hypervisor Trap住。

不過(guò)由于體系結(jié)構(gòu)的限制,虛擬計(jì)時(shí)器不能直接引發(fā)虛擬中斷,而總是引發(fā)硬件中斷,而硬件中斷會(huì)Trap到hypervisor。KVM/ARM檢測(cè)虛擬機(jī)的虛擬計(jì)時(shí)器是否到期,并向虛擬機(jī)注入相應(yīng)的虛擬中斷,在highvisor中執(zhí)行所有硬件ACK和EOI操作。硬件只為每個(gè)物理CPU提供一個(gè)虛擬計(jì)時(shí)器,多個(gè)虛擬CPU可以再這個(gè)硬件實(shí)例上復(fù)用。為了在這種情況下支持虛擬計(jì)時(shí)器,KVM/ARM在虛擬機(jī)進(jìn)入hypervisor時(shí)檢測(cè)未過(guò)期的計(jì)時(shí)器,并利用現(xiàn)有的OS功能在虛擬計(jì)時(shí)器本來(lái)觸發(fā)的時(shí)候編程一個(gè)軟件計(jì)時(shí)器,讓虛擬機(jī)處于運(yùn)行狀態(tài)。當(dāng)這樣的軟件計(jì)時(shí)器觸發(fā)時(shí),將執(zhí)行一個(gè)回調(diào)函數(shù),該函數(shù)使用上面描述的虛擬分發(fā)器向VM引發(fā)一個(gè)虛擬計(jì)時(shí)器中斷。

8. ARM體系結(jié)構(gòu)的改進(jìn)

根據(jù)KVM/ARM開(kāi)發(fā)人員的經(jīng)驗(yàn),對(duì)ARM架構(gòu)進(jìn)行了一系列改進(jìn),以避免對(duì)KVM/ARM等type-2 hypervisor進(jìn)行split-mode虛擬化的需要。這些改進(jìn)包括Virtualization Host Extensions(VHE),它現(xiàn)在是ARM 64-bit架構(gòu)新版本ARMv8.1的一部分。VHE允許將設(shè)計(jì)在EL1中運(yùn)行的OS運(yùn)行在EL2中,而無(wú)需對(duì)OS源代碼進(jìn)行實(shí)質(zhì)性修改。

VHE是通過(guò)添加一個(gè)新的控制位E2H來(lái)提供的,該位在系統(tǒng)啟動(dòng)時(shí)安裝使用VHE的type-2 hypervisor是設(shè)置的。如果該位沒(méi)有設(shè)置,ARMv8.1在硬件虛擬化方面與ARMv8相同,保留了與現(xiàn)有hypervisor的向后兼容性。如果該位設(shè)置了,那么VHE將開(kāi)啟三個(gè)主要特性。

首先,VHE擴(kuò)展了EL2,向CPU添加額外的物理寄存器狀態(tài),這樣EL1中可用的任何寄存器和功能也可以在EL2中使用。例如,EL1有兩個(gè)寄存器:TTBR0_EL1和TTBR1_EL1。第一個(gè)用于查找頁(yè)表中較低VA范圍內(nèi)的虛擬地址,第二個(gè)用于較高VA范圍內(nèi)的虛擬地址。它提供了一種在user空間和kernel空間之間分隔虛擬空間的方便、高效地方法。但是,如果沒(méi)有VHE,EL2只有一個(gè)頁(yè)表基寄存器TTBR0_EL2,這使得在EL2中運(yùn)行時(shí)支持EL1的分隔VA空間存在問(wèn)題。對(duì)于VHE,EL2將有第二個(gè)頁(yè)表基寄存器TTBR1_EL2,從而可以支持分隔VA空間EL2的方式與EL1相同。用于啟用與host集成的type-2 hypervisor操作系統(tǒng)去支持在EL2種分割VA空間,這是運(yùn)行EL2種的host OS所必需的,以便管理user空間和kernel之間的VA空間。

其次,VHE提供了一種機(jī)制來(lái)透明地訪(fǎng)問(wèn)額外的EL2寄存器狀態(tài)。簡(jiǎn)單地提供額外的EL2寄存器不足以在EL2中運(yùn)行未修改的OS,因?yàn)楝F(xiàn)有的操作系統(tǒng)被寫(xiě)入訪(fǎng)問(wèn)EL1寄存器。例如,Linux使用了TTBR1_EL1,不影響EL2種運(yùn)行的translation系統(tǒng)。提供額外的寄存器TTBR1_EL2仍然需要修改Linux,以便分別在EL2中運(yùn)行時(shí)使用TTBR1_EL2而不是TTBR1_EL1。為了避免迫使OS供應(yīng)商給軟件增加這種額外的復(fù)雜性,VHE允許未經(jīng)修改的軟件在EL2種執(zhí)行,并使用EL1寄存器訪(fǎng)問(wèn)函數(shù)指令編碼透明的訪(fǎng)問(wèn)EL2寄存器。例如,當(dāng)前的操作系統(tǒng)軟件用指令MRS x1,TTBR1_EL1讀取TTBR1_EL1寄存器。對(duì)于VHE,軟件仍然執(zhí)行相同的指令,但是硬件實(shí)際訪(fǎng)問(wèn)的是TTBR1_EL2寄存器。只要設(shè)置了E2H bit,訪(fǎng)問(wèn)EL1寄存器實(shí)際上訪(fǎng)問(wèn)了EL2寄存器,從而透明地重寫(xiě)了對(duì)EL2的寄存器訪(fǎng)問(wèn)。添加了一組新的特殊指令來(lái)訪(fǎng)問(wèn)EL2中EL1寄存器,hypervisor可以使用這些指令在將EL1中運(yùn)行的VM之間進(jìn)行切換。例如,如果hypervisor希望訪(fǎng)問(wèn)Guest的TTBR1_EL1,它將使用指令MRS x1,TTBR_EL21。

第三,VHE擴(kuò)展了EL2的memory translation能力。在ARMv8種,EL2和EL1使用不同的頁(yè)表格式,因此編寫(xiě)在EL1種運(yùn)行的軟件必須經(jīng)過(guò)修改才能在EL2中運(yùn)行。在ARMv8.1中,當(dāng)設(shè)置了E2H位時(shí),EL2頁(yè)表格式現(xiàn)在與EL1格式兼容。因此,以前在EL1中運(yùn)行的OS現(xiàn)在可以在EL2中運(yùn)行而無(wú)需修改,因?yàn)樗梢允褂孟嗤腅L1頁(yè)表格式。

圖3顯示type-1和type-2 hypervisor程序如何映射到具有VHE的體系結(jié)構(gòu)。

圖3 虛擬化擴(kuò)展(VHE)

Type-1 hypervisor(如Xen)可以明確地設(shè)計(jì)為在EL2中運(yùn)行,而無(wú)序任何額外的支持,它不設(shè)置VHE引入的E2H位,并且EL2的行為與ARMv8完全相同。Type-2 hypervisor(如KVM/ARM)在系統(tǒng)啟動(dòng)時(shí)設(shè)置了E2H位,host OS kernel只在EL2中運(yùn)行,不會(huì)在EL1中運(yùn)行。Type-2 hypervisor kernel可以在EL2中不加修改地運(yùn)行,因?yàn)閂HE為每個(gè)EL1寄存器提供了一個(gè)等效的EL2寄存器,并透明地將EL1寄存器訪(fǎng)問(wèn)從EL2重寫(xiě)為EL2寄存器訪(fǎng)問(wèn),而且EL1和EL2之間的頁(yè)表格式現(xiàn)在是兼容的。從host user空間到host kernel的轉(zhuǎn)換直接從EL0到EL2進(jìn)行,例如處理系統(tǒng)調(diào)用,如圖3的箭頭所示。從VM到hypervisor的轉(zhuǎn)換現(xiàn)在無(wú)須上下文切換EL1狀態(tài),因?yàn)閔ypervisor不使用EL1。

相關(guān)推薦

登錄即可解鎖
  • 海量技術(shù)文章
  • 設(shè)計(jì)資源下載
  • 產(chǎn)業(yè)鏈客戶(hù)資源
  • 寫(xiě)文章/發(fā)需求
立即登錄