07-Armv8-A virtualization
快速鏈接:
.
👉👉👉 個(gè)人博客筆記導(dǎo)讀目錄(全部) 👈👈👈
相關(guān)鏈接: (專題:《learn-the-architecture系列》)
- 01-Introducing the Arm architecture
- 02-Armv8-A Instruction Set Architecture
- 03_Introduction_to_AMBA_AXI
- 04-TrustZone for Armv8-A
- 05-Exception model
- 06-GICv3_v4_overview
- 07-Armv8-A virtualization
- 08-Isolation using virtualization in the Secure World_Whitepaper
- 09-LearnTheArchitecture-MemoryManagement
- 10-Armv8-A memory model guide–ongoing
- 11-Memory Management Examples
- 12-Generic Timer
- 13-Introduction to security
- 14-Providing protection for complex software
- 15-Arm-Confidential-Compute-Software-Stack
- 16-Understanding the Armv8.x extensions
目錄
- 前言
- 1.概述
- 2.虛擬化介紹
- 2.1 虛擬化為什么重要
- 2.2 hypervisors的兩種類型
- 2.3 全虛擬化和半虛擬化
- 2.4 虛擬機(jī)和虛擬CPUs
- 3.AArch64中的虛擬化
- 4. Stage 2 translation
- 4.1 What is stage 2 translation?
- 4.2 VMIDs
- 4.3 VMID interaction with ASIDs
- 4.4 Attribute combining and overriding (屬性組合和覆蓋)
- 4.5 Emulating Memory-mapped Input/Output (MMIO)
- 4.6 System Memory Management Units (SMMUs)
- 5 Trapping and emulation of instructions
- 5.1 Presenting virtual values of registers
- 5.2 MIDR and MPIDR
- 6 Virtualizing exceptions
- 6.1 Enabling virtual interrupts
- 6.2 Generating virtual interrupts
- 6.3 Example of forwarding an interrupt to a vCPU
- 6.4 Interrupt masking and virtual interrupts
- 7 Virtualizing the Generic Timers
- 8 Virtualization Host Extensions
- 8.1 Running the Host OS at EL2
- 8.2 Virtual address space
- 8.3 Re-directing register accesses (重新定位寄存器訪問)
- 8.4 Exceptions
- 9 Nested virtualization (嵌套虛擬化)
- 10 Secure virtualization
- 10.1 Secure EL2 and the two Intermediate Physical Address spaces
前言
為什么要學(xué)習(xí)虛擬化?
作為一名安全領(lǐng)域的渣渣 ,有必要去學(xué)習(xí)虛擬化技術(shù),因?yàn)樗矊儆贏RM安全架構(gòu)的一部分。
1.概述
看完之后你將學(xué)會(huì):
- 兩種類型的hypervisor(Type 1 Hypervisor、Type 2 Hypervisor),以及他們?nèi)绾斡成涞紸rm異常等級(jí)。
- 解釋operation trapped以及如何模擬operation
- 能夠列出hypervisor能夠產(chǎn)生的虛擬異常以及產(chǎn)生這些異常的機(jī)制
2.虛擬化介紹
下文的hypervisor泛指:用于創(chuàng)建、管理、調(diào)度虛擬機(jī)的軟件。
2.1 虛擬化為什么重要
虛擬化是一種廣泛使用的技術(shù),幾乎支持所有現(xiàn)代云計(jì)算和企業(yè)基礎(chǔ)架構(gòu)。 開發(fā)人員使用虛擬化在一臺(tái)機(jī)器上運(yùn)行多個(gè)操作系統(tǒng) (OS),并在不破壞主計(jì)算環(huán)境的情況下測(cè)試軟件。
虛擬化在服務(wù)器系統(tǒng)中很流行,大多數(shù)服務(wù)器級(jí)處理器都要求支持虛擬化。 這是因?yàn)樘摂M化為數(shù)據(jù)中心提供了非常理想的功能,包括:
- 隔離性(Isolation)
- 高可用性(High Availability):虛擬機(jī)遷移
- 負(fù)載均衡(Workload balancing):
- 沙箱(Sandboxing)
2.2 hypervisors的兩種類型
-
standalone 或 Type 1 hypervisors
Hypervisor直接在硬件上運(yùn)行,并完全控制硬件平臺(tái)及其所有資源,包括 CPU 和物理內(nèi)存。其上的虛擬機(jī)可以運(yùn)行一個(gè)或多個(gè)完整的guest os.
-
hosted 或 Type 2 hypervisors
(1)完全控制硬件平臺(tái)及其所有資源,包括 CPU 和物理內(nèi)存
(2)如果您以前使用過 Virtual Box 或 VMware Workstation 等軟件,那么這就是您正在運(yùn)行的虛擬機(jī)管理程序類型。 操作系統(tǒng)(稱為主機(jī)操作系統(tǒng))安裝在平臺(tái)上,管理程序在主機(jī)操作系統(tǒng)內(nèi)運(yùn)行,利用現(xiàn)有功能來管理硬件。 管理程序然后可以托管虛擬機(jī),這些虛擬機(jī)本身運(yùn)行操作系統(tǒng)。 我們將其稱為來guest os。
Arm 平臺(tái)上最常用的兩個(gè)開源虛擬機(jī)管理程序是 Xen(type 1)和 KVM(type 2)。 我們將使用這些管理程序來說明本文中的一些要點(diǎn)。 當(dāng)然除此之外還有許多其他的開源或?qū)I(yè)的hypervisor。
2.3 全虛擬化和半虛擬化
VM 的經(jīng)典定義是一個(gè)獨(dú)立的、隔離的計(jì)算環(huán)境,與真實(shí)的物理機(jī)無法區(qū)分。 盡管可以在基于 Arm 的系統(tǒng)上完全模擬真實(shí)機(jī)器,但這通常不是一件有效的事情。 因此,這種模擬并不經(jīng)常進(jìn)行。 例如,模擬真實(shí)的以太網(wǎng)設(shè)備很慢,因?yàn)槊看卧L問由guest os執(zhí)行的模擬寄存器都必須由hypervisor在軟件中處理。 這種處理可能比訪問物理設(shè)備上的寄存器要昂貴得多。
通常用于提高性能的首選替代方案是 enlighten Guest OS。 通過讓guest os知道它正在 VM 中運(yùn)行,并通過提供在hypervisor中模擬并從Guest OS訪問時(shí)具有良好性能的虛擬設(shè)備 ,guest os可以獲得良好的性能,即使對(duì)于IO。
嚴(yán)格來說,全系統(tǒng)虛擬化模擬真實(shí)的物理機(jī)。 另一方面,Xen(開源項(xiàng)目)推廣了術(shù)語“paravirtualization”,其中g(shù)uest os的核心部分被修改為在虛擬硬件平臺(tái)而不是物理機(jī)上運(yùn)行。 進(jìn)行此修改是為了提高性能。
今天,在大多數(shù)具有虛擬化硬件支持的架構(gòu)上,包括 Arm,Guest OS 大部分都未經(jīng)修改地運(yùn)行。 guest os認(rèn)為它在真實(shí)硬件上運(yùn)行,除了塊存儲(chǔ)和網(wǎng)絡(luò)等 I/O 外圍設(shè)備的驅(qū)動(dòng)程序,它們使用半虛擬化設(shè)備和設(shè)備驅(qū)動(dòng)程序。 這種半虛擬化 I/O 設(shè)備的例子是 Virtio 和 Xen PV Bus。
2.4 虛擬機(jī)和虛擬CPUs
了解虛擬機(jī) (VM) 和虛擬 CPU (vCPU) 之間的區(qū)別很重要。 一個(gè) VM 將包含一個(gè)或多個(gè) vCPU,如下圖所示:
當(dāng)我們查看本文中的其他一些章節(jié)時(shí),VM 和 vCPU 之間的區(qū)別將變得很重要。 例如,內(nèi)存頁面可能會(huì)分配給 VM,因此該 VM 中的所有 vCPU 都可以訪問該內(nèi)存頁。 但是,虛擬中斷是針對(duì)特定的 vCPU,并且只能轉(zhuǎn)到該 vCPU。
注意:嚴(yán)格來說,我們應(yīng)該指的是虛擬處理元素 (vPE),而不是 vCPU。 請(qǐng)記住,處理元件 (PE) 是實(shí)現(xiàn) Arm 架構(gòu)的機(jī)器的通用術(shù)語。 本指南使用 vCPU 而不是 vPE,因?yàn)?vCPU 是大多數(shù)人熟悉的術(shù)語。 但是,在體系結(jié)構(gòu)規(guī)范中,使用術(shù)語 vPE
3.AArch64中的虛擬化
運(yùn)行在EL2之上的軟件可以訪問并控制虛擬化功能:
- Stage 2 轉(zhuǎn)換
- EL1/0指令和寄存器訪問
- 產(chǎn)生虛擬化異常
非安全狀態(tài)和安全狀態(tài)的異常等級(jí)如下所示:
在圖中,Secure EL2 顯示為灰色。 這是因?yàn)橹暗脑捠菦]有S-EL2的(armv8.4及其之后是有了的)。 這在有關(guān)安全虛擬化的部分中進(jìn)行了討論
架構(gòu)中還有一些功能支持:
- Secure virtualization
- Hosted, or Type 2, hypervisors
- Nested virtualization(嵌套虛擬化)
4. Stage 2 translation
4.1 What is stage 2 translation?
Stage 2 translation允許hypervisor 控制虛擬機(jī) (VM) 中的內(nèi)存視圖。 具體來說,它允許管理程序控制 VM 可以訪問哪些內(nèi)存映射系統(tǒng)資源,以及這些資源出現(xiàn)在 VM 的地址空間中的位置。
這種控制內(nèi)存訪問的能力對(duì)于isolation和sandboxing很重要。 Stage 2 translation 可用于確保 VM 只能看到分配給它的資源,而看不到分配給其他 VM 或hypervisor的資源。
對(duì)于內(nèi)存地址翻譯,stage 2 translation是轉(zhuǎn)換的第二個(gè)stage。 為了支持這一點(diǎn),需要一組新的頁表,稱為 Stage 2 表,如下所示:
操作系統(tǒng) (OS) 控制一組從虛擬地址空間映射到它認(rèn)為是物理地址空間的轉(zhuǎn)換表。 然而,這個(gè)過程會(huì)經(jīng)歷第二次到真實(shí)物理地址空間的轉(zhuǎn)換。 第二階段由hypervisor控制。
操作系統(tǒng)控制的轉(zhuǎn)換稱為第 1 階段轉(zhuǎn)換,hypervisor控制的轉(zhuǎn)換稱為第 2 階段轉(zhuǎn)換。 操作系統(tǒng)認(rèn)為是物理內(nèi)存的地址空間稱為中間物理地址 (IPA) 空間。
注意:有關(guān)地址翻譯是如何工作的,請(qǐng)參考MMU相關(guān)博文
用于第 2 階段的轉(zhuǎn)換表的格式與用于第 1 階段的格式非常相似。但是,某些屬性在第 2 階段的處理方式不同,像type、normal或device被直接存放到table entry中,而不是通過 MAIR_ELx 寄存器。
4.2 VMIDs
每個(gè) VM 都分配有一個(gè)虛擬機(jī)標(biāo)識(shí)符 (VMID) 。 VMID 用于標(biāo)記translation
lookaside buffer(TLB) 條目,以標(biāo)識(shí)每個(gè)entry屬于哪個(gè) VM。 此標(biāo)記允許多個(gè)不同 VM 的翻譯同時(shí)出現(xiàn)在 TLB 中
VMID 存儲(chǔ)在 VTTBR_EL2 中,可以是 8 位或 16 位。 VMID 由 VTCR_EL2.VS 位控制。 對(duì) 16 位 VMID 的支持是可選的,并且是在 Armv8.1-A 中添加的。
注意:EL2 和 EL3 翻譯機(jī)制的翻譯沒有用 VMID 標(biāo)記,因?yàn)樗鼈儾皇艿?2 階段翻譯的約束。
4.3 VMID interaction with ASIDs
TLB entry也可以使用地址空間標(biāo)識(shí)符 (ASID) 進(jìn)行標(biāo)記。 操作系統(tǒng)為應(yīng)用程序分配了一個(gè) ASID,該應(yīng)用程序中的所有 TLB 條目都使用該 ASID 進(jìn)行標(biāo)記。 這意味著不同應(yīng)用程序的 TLB entry能夠共存于 TLB 中,而沒有一個(gè)應(yīng)用程序使用屬于不同應(yīng)用程序的 TLB entry的可能性。
每個(gè) VM 都有自己的 ASID 命名空間。 例如,兩個(gè) VM 可能都使用 ASID 5,但它們將它們用于不同的事情。 ASID 和 VMID 的組合很重要。
4.4 Attribute combining and overriding (屬性組合和覆蓋)
第 1 階段和第 2 階段映射都包含屬性,如類型和訪問權(quán)限。 內(nèi)存管理單元 (MMU) 將兩個(gè)階段的屬性結(jié)合起來,給出最終的有效值。 MMU 通過選擇更具限制性的階段來完成此操作,如下所示:
在此示例中,device比normal限制更多。 因此,結(jié)果類型為 device。 如果我們顛倒示例,結(jié)果將是相同的.
這種組合屬性的方法適用于大多數(shù)用例,但有時(shí)hypervisor 可能想要覆蓋此行為。 例如,在 VM 的早期啟動(dòng)期間。 對(duì)于這些情況,有一些控制位會(huì)覆蓋normal行為:
- HCR_EL2.CD. This makes all stage 1 attributes Non-cacheable.
- HCR_EL2.DC. This forces stage 1 attributes to be Normal, Write-Back Cacheable.
- HCR_EL2.FWB. This allows stage 2 to override the stage 1 attribute, instead of regular attribute combining
(Note: HCR_EL2.FWB was introduced in Armv8.4-A)
4.5 Emulating Memory-mapped Input/Output (MMIO)
與物理機(jī)上的物理地址空間一樣,VM 中的 IPA 空間包含用于訪問內(nèi)存和外圍設(shè)備的區(qū)域,如下所示:
VM 可以使用peripheral regions訪問physical peripherals(通常稱為直接分配的外圍設(shè)備)和virtual peripherals。
virtual peripherals由hypervisor在軟件中完全模擬,如下圖所示:
assigned peripheral是已分配給 VM 并映射到其 IPA 空間的真實(shí)物理設(shè)備。 這允許在 VM 中運(yùn)行的軟件直接與外圍設(shè)備交互。
virtual peripheral是hypervisor將在軟件中模擬的外圍設(shè)備。 相應(yīng)的第 2 階段table entries 將被標(biāo)記為錯(cuò)誤。 VM 中的軟件認(rèn)為它可以直接與外設(shè)對(duì)話,但每次訪問都會(huì)觸發(fā)第 2 階段fault,hypervisor將在異常處理程序中模擬外設(shè)訪問。
要模擬外設(shè),管理程序不僅需要知道訪問了哪個(gè)外設(shè),還需要知道訪問了該外設(shè)中的哪個(gè)寄存器、訪問是讀還是寫、訪問的大小以及用于傳輸數(shù)據(jù)的寄存器 .
異常模型引入了 FAR_ELx 寄存器。 在處理stage 1 fault時(shí),這些寄存器報(bào)告觸發(fā)異常的虛擬地址。 虛擬地址對(duì)hypervisor沒有幫助,因?yàn)閔ypervisor通常不知道來guest os如何配置其虛擬地址空間。 對(duì)于stage 2 fault,還有一個(gè)額外的寄存器 HPFAR_EL2,它報(bào)告中止地址的 IPA。 由于 IPA 空間由hypervisor控制,因此它可以使用此信息來確定需要模擬的寄存器。
異常模型顯示了 ESR_ELx 寄存器如何報(bào)告有關(guān)異常的信息。 對(duì)于觸發(fā)stage 2 fault的單個(gè)通用寄存器加載或存儲(chǔ),提供了額外的綜合信息。 該信息包括訪問的大小和源或目標(biāo)寄存器,并允許管理程序確定對(duì)虛擬外圍設(shè)備進(jìn)行的訪問類型。
下圖說明了捕獲異常然后模擬訪問的過程:
這個(gè)過程包含以下步驟:
- (1) VM 中的軟件嘗試訪問虛擬外圍設(shè)備。 在本例中,這是一個(gè)虛擬 UART 的接收 FIFO。
- (2) 此訪問在stage 2 translation時(shí)被阻止,導(dǎo)致路由到 EL2 的abort異常向量表
在abort異常向量表的路基中,讀取ESR_EL2獲取訪問的字節(jié)數(shù)、目標(biāo)寄存器以及它是加載還是存儲(chǔ); 讀取HPFAR_EL2獲取IPA地址 - (3) hypervisor使用來自 ESR_EL2 和 HPFAR_EL2 的信息來識(shí)別訪問的虛擬外設(shè)寄存器。 此信息允許hypervisor模擬操作。 然后通過 ERET 返回到 vCPU
4.6 System Memory Management Units (SMMUs)
到目前為止,我們已經(jīng)考慮了來自處理器的不同類型的訪問。 系統(tǒng)中的其他主機(jī),例如 DMA 控制器,可能會(huì)分配給 VM 使用。 我們還需要一些方法來將stage 1的保護(hù)擴(kuò)展到這些 master。
一個(gè)帶有不使用虛擬化的 DMA 控制器的系統(tǒng),如下圖所示:
DMA 控制器將通過驅(qū)動(dòng)程序進(jìn)行編程,通常在內(nèi)核空間中。 該內(nèi)核空間驅(qū)動(dòng)程序可以確保操作系統(tǒng)級(jí)別的內(nèi)存保護(hù)不被破壞。 這意味著一個(gè)應(yīng)用程序無法使用 DMA 訪問它不應(yīng)該看到的內(nèi)存。
我們?cè)倏匆粡堄蠽M的系統(tǒng)框圖:
在這個(gè)系統(tǒng)中,hypervisor使用stage 2來提供 VM 之間的隔離。 軟件查看內(nèi)存的能力受到hypervisor控制的stage 2的限制。 (其實(shí)就是說guest os無法為DMA提供真是的Physical Address, guest os看到的物理地址都是IPA)
允許 VM 中的驅(qū)動(dòng)程序直接與 DMA 控制器交互會(huì)產(chǎn)生兩個(gè)問題:
- (1)、隔離:DMA 控制器不受stage 2轉(zhuǎn)換的約束,可用于破壞 VM 的沙箱。
- (2)、地址空間:通過兩個(gè)階段的轉(zhuǎn)換,內(nèi)核認(rèn)為的 PA 是 IPA。 DMA 控制器仍然需要看到 PA,因此內(nèi)核和 DMA 控制器看到的內(nèi)存是不同的。 為了克服這個(gè)問題,管理程序可以捕獲 VM 和 DMA 控制器之間的每一次交互,提供必要的轉(zhuǎn)換。 當(dāng)內(nèi)存碎片化時(shí),此過程效率低下且有問題。
捕獲和模擬驅(qū)動(dòng)程序訪問的另一種方法是擴(kuò)展stage 2機(jī)制以覆蓋其他主機(jī),例如我們的 DMA 控制器。 發(fā)生這種情況時(shí),這些主設(shè)備還需要一個(gè) MMU。 這被稱為系統(tǒng)內(nèi)存管理單元(SMMU,有時(shí)也稱為 IOMMU) — SMMU就這么誕生了
管理程序?qū)⒇?fù)責(zé)對(duì) SMMU 進(jìn)行編程,以便上游主機(jī)(在我們的示例中為 DMA)看到與分配給它的 VM 相同的內(nèi)存視圖。
這個(gè)過程解決了我們發(fā)現(xiàn)的兩個(gè)問題。 SMMU 可以強(qiáng)制執(zhí)行 VM 之間的隔離,確保不能使用外部主節(jié)點(diǎn)來破壞沙箱。 SMMU 還為 VM 中的軟件和分配給 VM 的外部主控提供一致的內(nèi)存視圖。
虛擬化并不是 SMMU 的唯一用例。 還有許多其他情況不在本文的范圍內(nèi)。
5 Trapping and emulation of instructions
有時(shí),管理程序需要模擬虛擬機(jī) (VM) 內(nèi)的操作。 例如,VM 內(nèi)的軟件可能會(huì)嘗試配置與電源管理或緩存一致性相關(guān)的低級(jí)處理器控制。 通常,您不想讓 VM 直接訪問這些控件,因?yàn)樗鼈兛赡軙?huì)被用來打破隔離或影響系統(tǒng)中的其他 VM。
當(dāng)執(zhí)行給定的操作(例如讀取寄存器)時(shí),捕獲會(huì)導(dǎo)致異常。 管理程序需要能夠在 VM 中捕獲操作(例如配置低級(jí)別控制的操作)并模擬它們,而不影響其他 VM。
該體系結(jié)構(gòu)包括 trap operations ,供您捕獲 VM 中的操作并模擬它們。 Trapped后,執(zhí)行通常被允許的特定操作會(huì)導(dǎo)致更高級(jí)別的異常。 管理程序可以使用這些trapped產(chǎn)生的異常來模擬 VM 中的操作
例如,執(zhí)行等待中斷 (WFI) 指令通常會(huì)使 CPU 進(jìn)入低功耗狀態(tài)。 通過置位 TWI 位,如果 HCR_EL2.TWI==1,則在 EL0 或 EL1 處執(zhí)行 WFI 將導(dǎo)致 EL2 異常, 然后進(jìn)入EL2來模擬這個(gè)WFI指令
注意:Trapped不僅僅用于虛擬化。 還有 EL3 和 EL1 控制的traps。 但是,traps對(duì)虛擬化軟件特別有用。 本文僅討論通常與虛擬化相關(guān)的traps。
在我們的 WFI 示例中,操作系統(tǒng)通常會(huì)執(zhí)行 WFI 作為空閑循環(huán)的一部分。 對(duì)于 VM 中的guest os,管理程序可以捕獲此操作并改為調(diào)度不同的 vCPU,如下圖所示:
5.1 Presenting virtual values of registers
另一個(gè)使用traps的例子是呈現(xiàn)寄存器的虛擬值。 例如,ID_AA64MMFR0_EL1 報(bào)告對(duì)處理器中與內(nèi)存系統(tǒng)相關(guān)的功能的支持。 操作系統(tǒng)可能會(huì)在啟動(dòng)過程中讀取此寄存器,以確定要啟用內(nèi)核中的哪些功能。 管理程序可能希望向客戶操作系統(tǒng)提供一個(gè)不同的值,稱為虛擬值。
為此,管理程序啟用覆蓋寄存器讀取的陷阱。 對(duì)于trapped異常,管理程序確定觸發(fā)了哪個(gè)trap,然后模擬該操作。 在此示例中,管理程序使用 ID_AA64MMFR0_EL1 的虛擬值填充目標(biāo)寄存器,如下所示:
traps也可以用作lazy context switching的一部分。 例如,操作系統(tǒng)通常會(huì)在啟動(dòng)期間初始化內(nèi)存管理單元 (MMU) 配置寄存器(TTBR_EL1、TCR_EL1 和 MAIR_EL1),然后不會(huì)再次對(duì)它們重新編程。 管理程序可以使用它來優(yōu)化其上下文切換例程,方法是僅在上下文切換時(shí)恢復(fù)寄存器而不保存它們。
然而,操作系統(tǒng)可能會(huì)做一些不尋常的事情并在啟動(dòng)后重新編程寄存器。 為避免這導(dǎo)致任何問題,管理程序可以設(shè)置 HCR_EL2.TVM trap。 此設(shè)置會(huì)導(dǎo)致對(duì) MMU 相關(guān)寄存器的任何寫入都會(huì)在 EL2 中生成trap,從而允許管理程序檢測(cè)它是否需要更新其保存的這些寄存器的副本。
解釋: 這兩段其實(shí)就是說,對(duì)于系統(tǒng)寄存器,在每次切換的時(shí)候會(huì)lazy context switching。但是對(duì)于MMU寄存器,可能會(huì)在運(yùn)行時(shí)被修改,所以針對(duì)MMU寄存器的控制,可以設(shè)置 HCR_EL2.TVM,這樣的話在guest os寫MMU寄存器的時(shí)候,就會(huì)產(chǎn)生trap異常)
注: lazy context switching 和 context switching的區(qū)別:
(1)、前者,開機(jī)的時(shí)候記錄下每個(gè)vcpu的context,當(dāng)vcpu切換到VM時(shí),則恢復(fù)這個(gè)vContext
(2)、后者,每次的VM切換,都伴隨著vContext的save和restore
注意:該體系結(jié)構(gòu)使用術(shù)語trapping 和routing來表示獨(dú)立但又相關(guān)的概念。 回顧一下,當(dāng)執(zhí)行給定的操作(例如讀取寄存器)時(shí),trapped會(huì)導(dǎo)致異常。routing是指異常生成后將采取的異常級(jí)別。
5.2 MIDR and MPIDR
使用traps來虛擬化操作需要大量計(jì)算。 該操作向 EL2 生成trapped異常,管理程序確定所需的操作,對(duì)其進(jìn)行模擬,然后返回給guest os。 諸如 ID_AA64MMFR0_EL1 之類的功能寄存器不被操作系統(tǒng)頻繁訪問。 這意味著當(dāng)將對(duì)這些寄存器的訪問捕獲到管理程序中以模擬讀取時(shí),計(jì)算是可以接受的。
對(duì)于更頻繁訪問的寄存器,或在性能關(guān)鍵代碼中,你可能希望避免此類計(jì)算頻繁。 這些寄存器及其值的示例包括:
- MIDR_EL1. The type of processor, for example Cortex-A53
- MPIDR_EL1. The affinity, for example core 1 of processor 2
管理程序可能希望來guest os查看這些寄存器的虛擬值,而不必捕獲每個(gè)單獨(dú)的訪問。 對(duì)于這些寄存器,該架構(gòu)提供了一種捕獲的替代方法:
- VPIDR_EL2. This is the value to return for EL1 reads of MIDR_EL1.
- VMPIDR_EL2. This is the value to return for EL1 reads of MPIDR_EL1
管理程序可以在進(jìn)入 VM 之前設(shè)置這些寄存器。 如果在 VM 中運(yùn)行的軟件讀取 MIDR_EL1 或 MPIDR_EL1,硬件將自動(dòng)返回虛擬值,無需trapped。
注意:VMPIDR_EL2 和 VPIDR_EL2 沒有定義的復(fù)位值。 在第一次進(jìn)入 EL1 之前,它們必須通過啟動(dòng)代碼進(jìn)行初始化。 這一點(diǎn)尤其重要。
6 Virtualizing exceptions
系統(tǒng)中的硬件使用中斷向軟件發(fā)送事件信號(hào)。 例如,GPU 可能會(huì)發(fā)送一個(gè)中斷來表示它已完成刷完一幀。
使用虛擬化的系統(tǒng)更為復(fù)雜。 某些中斷可能由管理程序本身處理。 其他中斷可能來自分配給虛擬機(jī) (VM) 的設(shè)備,需要由該 VM 內(nèi)的軟件處理。 此外,中斷所針對(duì)的 VM 在收到中斷時(shí)可能未運(yùn)行
這意味著需要一些機(jī)制來支持管理程序處理 EL2 中的某些中斷。 還需要將其他中斷轉(zhuǎn)發(fā)到特定 VM 或 VM 中特定虛擬 CPU (vCPU) 的機(jī)制。
為了啟用這些機(jī)制,該架構(gòu)包括對(duì)虛擬中斷的支持:vIRQ、vFIQ 和 vSErrors。 這些虛擬中斷的行為類似于它們的物理中斷(IRQ、FIQ 和 SError),但只能在 EL0 和 EL1 中執(zhí)行時(shí)發(fā)出信號(hào)。 在 EL2 或 EL3 中執(zhí)行時(shí)不可能接收到虛擬中斷。
注意:回顧一下,Armv8.4-A 中引入了對(duì)安全狀態(tài)虛擬化的支持。 對(duì)于要在安全 EL0/1 中發(fā)出信號(hào)的虛擬中斷,需要支持和啟用安全 EL2。 否則虛擬中斷不會(huì)在安全狀態(tài)下發(fā)出信號(hào)。
6.1 Enabling virtual interrupts
要將虛擬中斷發(fā)送到 EL0/1,管理程序必須在 HCR_EL2 中設(shè)置相應(yīng)的路由位。 例如,要啟用 vIRQ 信號(hào),管理程序必須設(shè)置 HCR_EL2.IMO。 此設(shè)置將物理 IRQ 異常路由到 EL2,并啟用向 EL1 發(fā)送虛擬異常信號(hào).
虛擬中斷按中斷類型進(jìn)行控制。 理論上,VM 可以配置為接收物理 FIQ 和虛擬 IRQ。 在實(shí)踐中,這是少見的。 VM 通常配置為僅接收虛擬中斷。
6.2 Generating virtual interrupts
有兩種產(chǎn)生虛擬中斷的機(jī)制:
- (1)、在內(nèi)核內(nèi)部,使用HCR_EL2 中的控件。
- (2)、使用 GICv2 或更高版本的中斷控制器。
先看第一種。 HCR_EL2 中有三個(gè)位控制虛擬中斷的生成:
- VI = Setting this bit registers a vIRQ.
- VF = Setting this bit registers a vFIQ.
- VSE = Setting this bit registers a vSError
設(shè)置這些位之一相當(dāng)于中斷控制器將中斷信號(hào)斷言到 vCPU。 生成的虛擬中斷受制于 PSTATE 屏蔽,就像常規(guī)中斷一樣。
這種機(jī)制使用簡(jiǎn)單,但缺點(diǎn)是它只提供了一種產(chǎn)生中斷本身的方式。 然而,管理程序需要模擬 VM 中中斷控制器的操作。 回顧一下,軟件中的捕獲和模擬操作涉及開銷,最好避免頻繁操作(如中斷)。
第二種選擇是使用 Arm 的通用中斷控制器 (GIC) 來生成虛擬中斷。 從 Arm GICv2 開始,GIC 可以通過提供物理 CPU 接口和虛擬 CPU 接口來發(fā)出物理和虛擬中斷信號(hào),如下圖所示:
這兩個(gè)接口是相同的,除了一個(gè)表示物理中斷,另一個(gè)表示虛擬中斷。 管理程序可以將虛擬 CPU 接口映射到 VM,允許該 VM 中的軟件直接與 GIC 通信。 這種方式的好處是hypervisor只需要設(shè)置虛擬接口,不需要模擬。 這種方法減少了執(zhí)行需要被困在 EL2 的次數(shù),因此減少了虛擬化中斷的開銷。
注意:雖然 Arm GICv2 可用于 Armv8-A 設(shè)計(jì),但更常見的是使用 GICv3 或 GICv4。
6.3 Example of forwarding an interrupt to a vCPU
到目前為止,我們已經(jīng)了解了如何啟用和生成虛擬中斷。 讓我們看一個(gè)示例,該示例顯示了將虛擬中斷轉(zhuǎn)發(fā)到 vCPU。 在此示例中,我們將考慮已分配給 VM 的物理外圍設(shè)備,如下圖所示:
上圖示例的步驟為:
- (1)、 物理外設(shè)產(chǎn)生中斷,發(fā)送信號(hào)到 GIC。
- (2)、 GIC 生成物理中斷異常,IRQ 或 FIQ,通過 HCR_EL2.IMO/FMO 的配置路由到 EL2。 管理程序識(shí)別外圍設(shè)備并確定它已分配給 VM。 它檢查中斷應(yīng)該轉(zhuǎn)發(fā)到哪個(gè) vCPU。
- (3)、 hypervisor配置GIC將物理中斷作為虛擬中斷轉(zhuǎn)發(fā)給vCPU。 然后 GIC 將置位 vIRQ 或 vFIQ 信號(hào),但處理器在 EL2 中執(zhí)行時(shí)將忽略該信號(hào)。
- (4)、 管理程序?qū)⒖刂茩?quán)交還給 vCPU。
- (5)、 現(xiàn)在處理器在 vCPU(EL0 或 EL1)中,可以從 GIC 獲取虛擬中斷。 此虛擬中斷受 PSTATE 異常掩碼的約束。
該示例顯示了作為虛擬中斷轉(zhuǎn)發(fā)的物理中斷。 。 對(duì)于虛擬外設(shè),管理程序可以創(chuàng)建虛擬中斷,而無需將其鏈接到物理中斷。
6.4 Interrupt masking and virtual interrupts
在異常模型中,我們?cè)?PSTATE 中引入了中斷屏蔽位,IRQ 為 PSTATE.I,FIQ 為 PSTATE.F,SError 為 PSTATE.A。 在虛擬化環(huán)境中運(yùn)行時(shí),這些掩碼的工作方式略有不同。
例如,對(duì)于 IRQ,我們已經(jīng)看到設(shè)置 HCR_EL2.IMO 做了兩件事:
- Routes physical IRQs to EL2
- Enables signaling of vIRQs in EL0 and EL1
此設(shè)置還會(huì)更改應(yīng)用 PSTATE.I 掩碼的方式。 而在 EL0 和 EL1 中,如果 HCR_E2.IMO==1,PSTATE.I 對(duì) vIRQ 而非 pIRQ 起作用。
7 Virtualizing the Generic Timers
Arm 架構(gòu)包括通用定時(shí)器,它是每個(gè)處理器中可用的標(biāo)準(zhǔn)化定時(shí)器集。 通用定時(shí)器由一組比較器組成,用于與公共系統(tǒng)計(jì)數(shù)進(jìn)行比較。 當(dāng)比較器的值等于或小于系統(tǒng)計(jì)數(shù)時(shí),比較器產(chǎn)生中斷。 在下圖中,我們可以看到系統(tǒng)中的通用定時(shí)器(橙色),及其比較器和計(jì)數(shù)器模塊的組件。
下圖顯示了一個(gè)示例系統(tǒng),該系統(tǒng)具有托管兩個(gè)虛擬 CPU (vCPU) 的管理程序:
注意:在示例中,我們忽略了運(yùn)行管理程序以在 vCPU 之間進(jìn)行上下文切換的開銷。
在 4 毫秒的物理時(shí)間或wall-clock time,之后,每個(gè) vCPU 已經(jīng)運(yùn)行了 2 毫秒。 如果 vCPU0 在 T=0 時(shí)將其比較器設(shè)置為在 3ms 后生成中斷,您是否希望中斷觸發(fā)?
或者,您是否想要在虛擬時(shí)間 2 毫秒(即 vCPU 所經(jīng)歷的時(shí)間)或wall-clock time的 2 毫秒之后中斷?
Arm 架構(gòu)提供了兩種能力,具體取決于虛擬化的用途。 讓我們看看它是如何做到的。
在 vCPU 上運(yùn)行的軟件可以訪問兩個(gè)計(jì)時(shí)器:
- EL1 Physical Timer
EL1 物理計(jì)時(shí)器與系統(tǒng)計(jì)數(shù)器模塊生成的計(jì)數(shù)進(jìn)行比較。 使用此計(jì)時(shí)器可提wall-clock time - EL1 Virtual Timer
EL1 虛擬計(jì)時(shí)器與虛擬計(jì)數(shù)進(jìn)行比較。 虛擬計(jì)數(shù)是物理計(jì)數(shù)減去偏移量。 管理程序在寄存器中指定當(dāng)前調(diào)度的 vCPU 的偏移量。 這允許它在未安排 vCPU 運(yùn)行時(shí)隱藏時(shí)間的流逝:
為了說明這個(gè)概念,我們可以擴(kuò)展前面的例子,如下圖所示:
在 6 毫秒的時(shí)間內(nèi),每個(gè) vCPU 運(yùn)行 3 毫秒。 虛擬機(jī)管理程序可以使用偏移寄存器來呈現(xiàn)僅顯示 vCPU 運(yùn)行時(shí)間的虛擬計(jì)數(shù)。 或者管理程序可以將偏移量保持為 0,這意味著虛擬時(shí)間與物理時(shí)間相同。
注意:示例顯示系統(tǒng)計(jì)數(shù)的頻率為 1ms。 實(shí)際上,這個(gè)頻率值是不太可能的。 我們建議您將系統(tǒng)計(jì)數(shù)設(shè)置為使用 1MHz 到 50MHz 之間的頻率
8 Virtualization Host Extensions
下圖顯示了我們?cè)谔摂M化異常部分中查看的軟件框圖和異常級(jí)別的簡(jiǎn)化版本:
可以看到獨(dú)立虛擬機(jī)管理程序如何映射到 Arm 異常級(jí)別。 管理程序在 EL2 上運(yùn)行,虛擬機(jī) (VM) 在 EL0/1 上運(yùn)行。
注意:DynamIQ 處理器(Cortex-A55、Cortex-A75 和 Cortex-A76)支持虛擬化主機(jī)擴(kuò)展 (VHE)。 事實(shí)上armv8.1 都支持VHE
8.1 Running the Host OS at EL2
VHE 由 HCR_EL2 中的兩位控制。 這些位可以總結(jié)為:
- E2H:控制是否啟用VHE。
- TGE:啟用VHE 時(shí),控制EL0 是Guest 還是Host
下表總結(jié)了典型設(shè)置:
| Guest kernel (EL1) | 1 | 0 |
| Guest application (EL0) | 1 | 0 |
| Host kernel (EL2) | 1 | 1* |
| Host application (EL0) | 1 | 1 |
(星號(hào)*)對(duì)于從 VM 退出到管理程序的異常,TGE 最初將為 0。軟件將在運(yùn)行主機(jī)內(nèi)核的主要部分之前必須設(shè)置該位。
可以在下圖中看到這些典型設(shè)置:
8.2 Virtual address space
下圖顯示了在引入 VHE 之前 EL0/EL1 的虛擬地址空間的樣子:
正如內(nèi)存管理中所討論的,EL0/1 有兩個(gè)區(qū)域。 按照慣例,上部區(qū)域稱為內(nèi)核空間,下部區(qū)域稱為用戶空間。 但是,EL2 在地址范圍的底部只有一個(gè)區(qū)域。 這種差異是因?yàn)?#xff0c;傳統(tǒng)上,管理程序不會(huì)托管應(yīng)用程序。 這意味著管理程序不需要在內(nèi)核空間和用戶空間之間進(jìn)行拆分。
注意:內(nèi)核空間分配給上層區(qū)域,用戶空間分配給下層區(qū)域,只是一個(gè)約定。 它不是 Arm 架構(gòu)強(qiáng)制要求的。
EL0/1 虛擬地址空間也支持地址空間標(biāo)識(shí)符 (ASID),但 EL2 不支持。 這是因?yàn)楣芾沓绦蛲ǔ2粫?huì)托管應(yīng)用程序。
為了讓我們的主機(jī)操作系統(tǒng)在 EL2 中高效執(zhí)行,我們需要添加第二個(gè)區(qū)域和 ASID 支持。 設(shè)置 HCR_EL2.E2H 解決了這些問題,如下圖所示:
而在 EL0 中,HCR_EL2.TGE 控制使用哪個(gè)虛擬地址空間:EL1 空間或 EL2 空間。 使用哪個(gè)空間取決于應(yīng)用程序是在 Host OS (TGE1) 還是 Guest OS (TGE0) 下運(yùn)行。
8.3 Re-directing register accesses (重新定位寄存器訪問)
我們?cè)谔摂M化通用定時(shí)器部分看到啟用 VHE 會(huì)改變 EL2 虛擬地址空間的布局。 但是,我們?nèi)匀挥?MMU 的配置問題。 這是因?yàn)槲覀兊膬?nèi)核會(huì)嘗試訪問xxx_EL1 寄存器,如 TTBR0_EL1,而不是 xxx_EL2 寄存器,如 TTBR0_EL2。
要在 EL2 上運(yùn)行相同的操作,我們需要將訪問從 EL1 寄存器重定向到 EL2 等效項(xiàng)。 設(shè)置 E2H 將執(zhí)行此操作,以便對(duì) xxx_EL1 系統(tǒng)寄存器的訪問被重定向到它們的 EL2 等效項(xiàng)。 此重定向如下圖所示:
然而,這種重定向給我們留下了一個(gè)新問題。 管理程序仍然需要訪問真正的_EL1 寄存器,以便它可以實(shí)現(xiàn)任務(wù)切換。 為了解決這個(gè)問題,引入了一組帶有 xxx_EL12 或 xxx_EL02 后綴的新寄存器別名。 當(dāng)在 EL2 上使用時(shí),E2H==1,它們可以訪問 EL1 寄存器以進(jìn)行上下文切換。 您可以在下圖中看到這一點(diǎn):
8.4 Exceptions
通常,HCR_EL2.IMO/FMO/AMO 位控制物理異常是路由到 EL1 還是 EL2。 在 TGE ==1 的 EL0 中執(zhí)行時(shí),所有物理異常都被路由到 EL2,除非它們被 SCR_EL3 路由到 EL3。 無論 HCR_EL2 路由位的實(shí)際值如何,情況都是如此。 這是因?yàn)閼?yīng)用程序作為主機(jī)操作系統(tǒng)的子操作系統(tǒng)執(zhí)行,而不是客戶操作系統(tǒng)。 因此,任何異常都應(yīng)路由到在 EL2 中運(yùn)行的主機(jī)操作系統(tǒng)
9 Nested virtualization (嵌套虛擬化)
理論上,管理程序可以在虛擬機(jī) (VM) 中運(yùn)行。 這個(gè)概念叫做嵌套虛擬化:
10 Secure virtualization
虛擬化是在 Armv7-A 中引入的。 當(dāng)時(shí)Hyp模式,相當(dāng)于AArch32中的EL2,只在Non-secure狀態(tài)下可用。 引入 Armv8.4-A 時(shí),添加了對(duì)處于安全狀態(tài)的 EL2 的支持作為可選功能。
當(dāng)處理器支持安全 EL2 時(shí),需要使用 SCR_EL3.EEL2 位從 EL3 啟用處理器。 設(shè)置該位允許進(jìn)入 EL2,并允許在安全狀態(tài)下使用虛擬化功能。
在安全虛擬化可用之前,EL3 通常用于托管安全狀態(tài)切換軟件和平臺(tái)固件的混合體。 這是因?yàn)槲覀兿矚g盡量減少 EL3 中的軟件量,讓 EL3 更容易安全。 安全虛擬化允許我們將平臺(tái)固件移動(dòng)到 EL1。 虛擬化為平臺(tái)固件和可信內(nèi)核提供單獨(dú)的安全分區(qū)。 下圖說明了這一點(diǎn):
10.1 Secure EL2 and the two Intermediate Physical Address spaces
Arm 架構(gòu)定義了兩個(gè)物理地址空間:安全和非安全。 在非安全狀態(tài)下,虛擬機(jī) (VM) 的stage 1轉(zhuǎn)換的輸出始終是非安全的。 因此,stage 1需要處理單個(gè)中間物理地址 (IPA) 空間。
在安全狀態(tài)下,VM 的stage 1轉(zhuǎn)換可以輸出安全和非安全地址。 轉(zhuǎn)換表描述符中的 NS 位控制是輸出安全地址空間還是非安全地址空間。 如下圖所示,這意味著stage 2有兩個(gè) IPA 空間,安全和非安全:
與stage 1不同,stage 2條目中沒有 NS 位。 對(duì)于特定的 IPA 空間,所有轉(zhuǎn)換都會(huì)產(chǎn)生安全物理地址或非安全物理地址。 該轉(zhuǎn)換由寄存器位控制。 通常,非安全 IPA 轉(zhuǎn)換為非安全 PA,而安全 IPA 轉(zhuǎn)換為安全 PA。
總結(jié)
以上是生活随笔為你收集整理的07-Armv8-A virtualization的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 06-GICv3_v4_overview
- 下一篇: 08-Isolation using v