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