0、ARMv8架構
1)ARMv8基本概念
(1)執(zhí)行狀態(tài)(execution state):處理器運行時的環(huán)境,包括寄存器的位寬、支持的指令集、異常模型、內存管理及編程模型等。ARMv8體系結構定義了兩個執(zhí)行狀態(tài):
AArch64:64位的執(zhí)行狀態(tài)
提供31個64位的通用寄存器。
提供64位程序計數(shù)指針寄存器(Program Counter,PC)、棧指針寄存器(Stack Pointer,SP)及異常鏈接寄存器(Exception Link Register,ELR)。
提供A64精簡指令集。
定義ARMv8異常模型,支持4個異常等級:EL0~EL3。
提供64位的內存模型。
定義一組處理器狀態(tài)(PSTATE),用來保存PE(Processing Element,處理機)的狀態(tài)。
AArch32:32位的執(zhí)行狀態(tài)
提供13個32位的通用寄存器、PC指針寄存器、SP寄存器、鏈接寄存器。
支持A32和T32兩套指令集。
支持ARMv7-A異常模型。
提供32位的虛擬內存訪問機制。
定義一組處理器狀態(tài)(PSTATE),用來保存PE的狀態(tài)。
AArch64狀態(tài)的異常等級
ARMv8處理器支持兩種執(zhí)行狀態(tài):AArch64狀態(tài)和AArch32狀態(tài)。其中AArch64狀態(tài)是ARMv8新增的64位執(zhí)行狀態(tài),該狀態(tài)下運行A64指令集。AARch32狀態(tài)是為了兼容ARMv7的32位執(zhí)行狀態(tài),該狀態(tài)下運行A32指令集或者T32指令集。
AArch64狀態(tài)的異常等級,決定了處理器當前運行的特權級別,類似于ARMv7中的特權等級。
EL0:用戶特權,用于運行普通用戶程序。
EL1:系統(tǒng)特權,通常用于操作系統(tǒng)內核,比如linux、rtos。如果系統(tǒng)使能了虛擬化擴展,運行虛擬機操作系統(tǒng)內核。
EL2:運行虛擬化擴展的虛擬機監(jiān)控器(hypervisor)。
EL3:運行安全世界中的安全監(jiān)控器(secure monitor)。
ARMv8允許切換應用程序的運行模式,在一個64位操作系統(tǒng)的ARMv8處理器中,我們可以同時運行A64指令集和A32指令集的應用程序,但是32位操作系統(tǒng)的ARMv8處理器中,就不能運行A64指令集的應用程序了。
ARMv8體系結構提供2種安全狀態(tài):Secure和Non-secure。Secure state和Non-secure state將運行環(huán)境劃分為Normal world和Secure world,EL3只存在于Secure state。每種安全狀態(tài)有獨立的物理地址空間范圍,在Secure state,處理器可以訪問Secure和Non-secure的物理地址空間范圍。在Non-secure state,處理器只能訪問Non-secure的物理地址空間范圍。
異常等級之間的切換:
Supervisor Call(SVC)指令:EL0的軟件向EL1(OS service)申請軟件服務。
Hypervisor Call(HVC)指令:主要被EL1(guest OS)請求hypervisor(EL2)服務。
Secure monitor Caller(SMC)指令:EL3用來切換安全非安全世界。
ERET指令用于異常返回,返回地址和處理器狀態(tài)是從當前EL(exception level)下的ELR和SPSR寄存器中恢復的。ERET 指令可用于返回到 CPU 支持的相同或任何較低的異常級別。如果存儲在 SPSR_EL3.M[4:0] 中的已保存模式字段,設置為 0b00101 或 0b00100,其中位M[ 3:2] 將異常級別編碼為1,然后在 EL3 執(zhí)行的 ERET 指令將返回到 EL1。
(2)ARMv8指令集:根據(jù)不同的執(zhí)行狀態(tài),提供不同的指令集支持,支持如下指令集。
A64指令集:運行在AArch64狀態(tài)下,提供64位指令集支持。A64指令集是ARMv8新增的,和A32采用了不同的指令編碼,所以跟A32不兼容。A64可以處理64位寬的寄存器和數(shù)據(jù),使用64位的指針來訪存,但是A64指令集的指令寬度是32位。
A32指令集:運行在AArch32狀態(tài)下,提供32位A32指令集支持。
T32指令集:運行在AArch32狀態(tài)下,提供16位和32位Thumb指令集支持。
2)ARMv8特性
使用64位體系結構,因此處理器可以訪問遠超4GB的物理地址空間。雖然是64位體系結構,但是一般并不使用64位地址總線,例如使用48位,即可以訪問256TB的物理地址空間。在32位ARM體系結構中,如果不使能LPAE(Large Physical Address Extension)功能,最多只能訪問4GB物理地址空間。即使使能了LPAE功能,也只是將物理地址空間的尋址能力擴展到40位,也就是1TB。
提供64位的虛擬地址尋址,從而擴大了進程的虛擬地址空間。在32位ARM體系結構中,即使使能了LAPE功能,也只是擴展了物理地址空間,但是進程的虛擬地址空間還是只有4GB。擴大虛擬地址空間之后,可以使用memory map的方式映射更大的文件到進程虛擬地址空間中,從而提高IO的效率。
通過automatic event signaling機制,實現(xiàn)高性能低功耗的spinlock。
提供31個64位通用寄存器,可減少對棧的使用,減少訪存的頻率,從而提升性能。在ARMv7體系結構的AAPCS(ARM Architecture Procedure Call Standard)中,前4個參數(shù)使用寄存器傳遞,大于4個的參數(shù)部分需要使用棧傳遞,也就是需要訪問內存。而在ARMv8體系結構中,可以使用寄存器傳遞前8個參數(shù),從而減少了對棧的使用。
提供基于PC寄存器±4GB的相對尋址范圍,提高了相對尋址效率,可以提升動態(tài)庫和位置無關代碼的執(zhí)行效率。
支持16KB & 64KB的分頁粒度,可以減少頁表級數(shù),同時提高TLB命中率。
全新的異常處理模型,更加利于操作系統(tǒng)和虛擬化的實現(xiàn)。
設計了全新的Load-Acquire和Store-Release指令,在線程安全的代碼中,不再需要顯式的內存屏障指令,從而提升了性能。
3)ARMv8寄存器
(1)通用寄存器
AArch64執(zhí)行狀態(tài)支持31個64位通用寄存器(X0~X30),AArch32狀態(tài)支持16個32位通用寄存器。
通用寄存器
(2)狀態(tài)寄存器
狀態(tài)寄存器
(3)特殊寄存器
特殊寄存器
當運行異常處理程序時,處理器會把PSTATE寄存器的值暫時保存在SPSR(Saved Program Status Register,SPSR)里。當異常處理完返回時,再把SPSR的值恢復到PSTATE寄存器。
(4)系統(tǒng)寄存器
通過訪問和設置這些系統(tǒng)寄存器,來完成對處理器不同的功能配置。ARMv8支持7類系統(tǒng)寄存器:
通用系統(tǒng)控制寄存器
調試寄存器
性能監(jiān)控寄存器
活動監(jiān)控寄存器
統(tǒng)計擴展寄存器
RAS寄存器
通用定時器寄存器
系統(tǒng)寄存器支持不同的異常等級訪問,具體的訪問規(guī)則如下:
Reg_EL1:處理器處于EL1、EL2、EL3時,都可以訪問該寄存器。
Reg_EL2:處理器處于EL2、EL3時,可以訪問寄存器。
大部分系統(tǒng)寄存器不支持處理器處于EL0時訪問,但也有例外,比如CTR_EL0。
通過MSR、MRS指令訪問系統(tǒng)寄存器。
1 綜述
本文描述了Armv8-A AArch64的虛擬化支持。包括stage 2頁表轉換,虛擬異常,以及陷阱。本文介紹了一些基礎的硬件輔助虛擬化理論以及一些Hypervisor如何利用這些虛擬化特性的例子。文本不會講述某一具體的Hypervisor軟件是如何工作的以及如何開發(fā)一款Hypervisor軟件。通過閱讀本文,你可以學到兩種類型的Hypervisor以及它們是如何映射到Arm的異常級別。你將能解釋陷阱是如何工作的以及其是如何被用來進行各種模擬操作。你將能描述Hypervisor可以產生什么虛擬異常以及產生這些虛擬異常的機制。理解本文內容需要一定基礎,本文假定你熟悉ARMv8體系結構的異常模型和內存管理。 1.1 虛擬化簡介 這里我們將介紹一些基礎的Hypervisor和虛擬化的理論知識。如果你已經(jīng)有一定的基礎或是已經(jīng)熟悉了這些概念,可以跳過這部分內容。我們用Hypervisor這個詞來定義一種負責創(chuàng)建,管理以及調度虛擬機(Virtual Machines, VMs)的軟件。
虛擬化為什么重要
虛擬化是一種在現(xiàn)代云計算和企業(yè)基礎架構中廣泛使用的技術。開發(fā)人員用虛擬機在一個硬件平臺上運行多個不同的操作系統(tǒng)來開發(fā)和測試軟件,以避免對主計算環(huán)境造成可能的破壞。虛擬化技術在服務器上非常流行,大多數(shù)面向服務器的處理器都需要支持虛擬化功能,這是因為虛擬化能給數(shù)據(jù)中心服務器帶來如下一些需要的特性:
隔離:利用虛擬化可以對同一個物理核上運行的虛擬機進行隔離。這使得相互間不可信的的計算環(huán)境可以共享同一套硬件環(huán)境。例如,兩個競爭對手可以共享同一個物理機器而又不能訪問對方的數(shù)據(jù)。
高可用性:虛擬化可以在不同的物理機器之間無縫透明地遷移負載。這個技術廣泛用于將負載從出錯的硬件平臺遷移至其他可用平臺,以便維護和替換出錯的硬件而不影響服務。
負載均衡:為了降低數(shù)據(jù)中心硬件和功耗成本,需要盡可能充分地利用硬件平臺資源。將負載均衡地遷移到不同地物理機上,有利用充分利用物理機資源,降低功耗,同時為租戶提供最佳性能。
沙箱:虛擬機可以作為一個沙箱來為運行在其中的應用屏蔽其他軟件的干擾,或者避免其干擾其他軟件。例如在虛擬機中運行特定軟件,可以避免該軟件的bug或病毒導致物理機器上的其他軟件損壞。
1.2 Hypervisor的兩種類型
Hypervisor通常被分成兩種類型,獨立類型Type 1和寄生類型 Type 2。我們先看看Type 2類型的Hypervisor。對于Type 2類型的Hypervisor,其寄生的宿主操作系統(tǒng)擁有對硬件平臺和資源(包括CPU和物理內存…)的全部控制權。下圖展示了Type 2類型的Hypervisor。
圖1:Type 2 Hypervisor 宿主操作系統(tǒng),指的是直接運行在硬件平臺上并為Type 2類型的Hypervisor提供運行環(huán)境的操作系統(tǒng)。這類Hypervisor可以充分利用宿主操作系統(tǒng)對物理硬件的管理功能,而Hypervisor只需提供虛擬化相關功能即可。不知你是否使用過Virtual Box或是VMware Workstation, 這類軟件就是Type 2類型的Hypervisor。 接下來,看看獨立類型的Type 1 Hypervisor, 如圖2。這類Hypervisor沒有宿主操作系統(tǒng)。其直接運行在物理硬件之上,直接管理各種物理資源,同時管理并運行客戶機操作系統(tǒng)。
圖2:Type 1 Hypervisor 在開源社區(qū)常見的Hypervisor, Xen (Type 1) 和 KVM (Type 2)就分屬這兩種不同的類型。其他開源的或知識產權的Hypervisor,可參見WiKi。
1.3 全虛擬化和半虛擬化
關于虛擬機,經(jīng)典定義是:虛擬機是一個獨立的隔離的計算環(huán)境,這種計算環(huán)境讓使用者看起來就像在使用真實的物理機器一樣。盡管我們可以在基于ARM的硬件平臺上模擬真實硬件,但這通常不是最有效的做法,因此我們常常不這么做。例如,模擬一個真實的以太網(wǎng)設備是非常慢的,這是因為對任何一個模擬寄存器的訪問都會陷入到Hypervisor當中進行模擬。比起直接訪問物理寄存器來說,這種操作的代價要昂貴得多。一個替代方案是修改客戶操作系統(tǒng),使之意識到自身運行在虛擬機當中,通過在Hypervisor中模擬一個虛擬設備來給客戶機使用。以此來換取更好得I/O性能。嚴格來說,全虛擬化需要完全模擬真實硬件,性能上會比較差。開源項目Xen推進了半虛擬化,通過修改客戶機操作系統(tǒng)的核心部分使其更適合在虛擬環(huán)境中運行,以此來提高性能。 另一個使用半虛擬化的原因是早期的體系結構并不是為虛擬化而設計的,存在虛擬化漏洞。因為虛擬化要求所有敏感指令或訪問敏感資源的指令都能被截獲模擬。對于存在虛擬化漏洞的體系結構,則需要通過半虛擬化的方案來填補漏洞。而今,大多數(shù)體系機構都支持硬件輔助虛擬化,包括Arm。這使得操作系統(tǒng)的核心部分無需修改也能獲得較好得性能。只有少數(shù)存儲和網(wǎng)絡相關的I/O設備仍然采用半虛擬化的方案來改善性能,這類半虛擬化的方案如,virtio 和 Xen PV Bus。
1.4 虛擬機(VM)和虛擬CPU (vCPU)
有必要區(qū)分虛擬機(VM)和虛擬CPU(vCPU)。這有利于理解本文的后續(xù)部分。例如,一個內存頁面可以分配給一個虛擬機,因此所有屬于該VM的vCPUs都可以訪問它。而一個虛擬中斷只是針對某個vCPU,因此只有該vCPU可以收到。虛擬機(VM)和虛擬CPU(vCPU)的關系如圖3所示。
圖3:VM vs vCPU 注意:ARM體系結構定義了處理單元(Processing Element, PE)一詞,現(xiàn)代CPU可能包含多個內核或線程,PE用來指代單一的執(zhí)行單元。同樣的這里的vCPU嚴格來說應該是vPE。
2 AArch64的虛擬化
對于ARMv8, Hypervisor運行在EL2異常級別。只有運行在EL2或更高異常級別的軟件才可以訪問并配置各項虛擬化功能。
Stage 2轉換
EL1/0指令和寄存器訪問
注入虛擬異常
安全狀態(tài)和非安全狀態(tài)下的異常級別及可運行的軟件如圖4所示
圖4:AArch64的虛擬化 注意:安全狀態(tài)的EL2用灰色顯示是因為,安全狀態(tài)的EL2并不總是可用,這是Armv8.4-A引入的特性。
2.1 Stage 2 轉換
什么是Stage 2 轉換
Stage 2 轉換允許Hypervisor控制虛擬機的內存視圖。具體來說,其可以控制虛擬機是否可以訪問特定的某一塊物理內存,以及該內存塊出現(xiàn)在虛擬機內存空間的位置。這種能力對于虛擬機的隔離和沙箱功能來說至關重要。這使得虛擬機只能看到分配給它自己的物理內存。為了支持Stage 2 轉換, 需要增加一個頁表,我們稱之為Stage 2頁表。操作系統(tǒng)控制的頁表轉換稱之為stage 1轉換,負責將虛擬機視角的虛擬地址轉換為虛擬機視角的物理地址。而stage 2頁表由Hypervisor控制,負責將虛擬機視角的物理地址轉換為真實的物理地址。虛擬機視角的物理地址在Armv8中有特定的詞描述,叫中間物理地址(intermediate Physical Address, IPA)。 stage 2轉換表的格式和stage 1的類似,但也有些屬性的處理不太一樣,例如,判斷內存類型 是normal 還是 device的信息被直接編碼進了表里,而不是通過查詢MAIR_ELx寄存器。
圖5:地址轉換, VA to IPA to PA
VMID
每一個虛擬機都被分配一個ID號,稱之為VMID。這個ID號用于標記某個特定的TLB項屬于哪一個VM。VMID使得不同的VM可以共享同一塊TLB緩存。VMID存儲在寄存器VTTBR_EL2中,可以是8或16比特,由VTCR_EL2.vs比特位控制,其中16比特的VMID支持是在armv8.1-A中擴展的,是可選的。需注意,EL2和EL3的地址轉換不需要VMID標記,因為它們不需要stage 2轉換。
VMID vs ASID
TLB項也可以用ASID(Address Space Identifier)標記,每個應用都被操作系統(tǒng)分配有一個ASID,所有屬于同一個應用的TLB項都有相同的ASID。這使得不同應用可以共享同一塊TLB緩存。每一個VM有它自己的ASID空間。例如兩個不同的VMs同時使用ASID 5,但指的是不同的東西。對于虛擬機而言,通常VMID會結合ASID同時使用。
屬性整合和覆蓋
stage 1 和 stage 2映射都包含屬性,例如存儲類型,訪問權限等。內存管理單元(MMU)會將兩個階段的屬性整合成一個最終屬性,整合的原則是選擇更有限制的屬性。且看如下例子:
圖6:映射屬性整合 在上面的例子中,Device屬性比起Normal屬性更具限制性,因此最終結果是Device屬性。同樣的原理,如果你將順序調換一下也不會改變最終的屬性。 屬性整合在大多數(shù)情況下都可以工作。但有些時候,例如在VM的早期啟動階段,Hypervisor希望改變默認的行為,則可以通過如下寄存器比特來實現(xiàn)。
HCR_EL2.CD: 控制所有stage 1屬性為Non-cacheable。
HCR_EL2.DC:強制所有stage 1屬性為Normal,Write-Back Cacheable。
HCR_EL2.FWB (Armv8.4-A引入):使用stage 2屬性覆蓋stage 1屬性,而不是使用默認的限制性整合原則。
模擬MMIO
與物理機器的物理地址空間類似,VM的IPA地址空間包含了內存與外圍設備兩種區(qū)域。如下圖所示
圖7:模擬MMIO VM使用外圍設備區(qū)域來訪問其看到的物理外圍設備,這其中包含了直通設備和虛擬外圍設備。虛擬設備完全由Hypervisor模擬,如下圖所示
圖8:stage 2映射 一個直通設備被直接分配給VM并映射到IPA地址空間,這使得VM中的軟件可用直接訪問真實的物理硬件。一個虛擬的外圍設備由Hypervisor模擬,其stage 2的轉換項被標記為fault。雖然VM中的軟件看來其是直接與物理設備交互,但實際上這一訪問會導致stage 2轉換fault,從而進入相應的異常處理程序由Hypervisor模擬。 為了模擬一個外圍設備,Hypervisor需要知道哪一個外圍設備被訪問,外圍設備的哪一個寄存器被訪問,是讀訪問還是寫訪問,訪問長度是多少,以及使用哪些寄存器來傳送數(shù)據(jù)。 當處理stage 1 faults時,F(xiàn)AR_ELx寄存器包含了觸發(fā)異常的虛擬地址。但虛擬地址不是給Hypervisor用的,Hypervisor通常不會知道客戶操作系統(tǒng)如何配置虛擬地址空間的映射。對于stage 2 faults,有一個專門的寄存器HPFAR_EL2,該寄存器會報告發(fā)生錯誤的IPA地址。IPA地址空間由Hypervisor控制,因此可用利用此寄存器里的信息來進行必要的模擬。 ESR_ELx寄存器用于報告發(fā)生異常的相關信息。當loads或stores一個通用寄存器觸發(fā)stage 2 fault時,相關異常信息由這些寄存器提供。這些信息包含了,訪問的長度,訪問的原地址或目的地址。Hypervisor可以以此來判斷對虛擬外圍設備訪問的權限。下圖展示了一個陷入(trapping) – 模擬(emulating)的訪問過程。
圖9:外圍設備模擬
VM里的軟件嘗試訪問虛擬外圍設備,這個例子當中是虛擬UART的接收FIFO。
該訪問被stage 2轉換block住,導致一個abort異常被路由到EL2。
異常處理程序查詢ESR_EL2關于異常的信息,如訪問長度,目的寄存器,是load還是store操作。
異常處理程序查詢HPFAR_EL2,取得發(fā)生abort的IPA地址。
Hypervisor通過ESR_EL2和HPFAR_EL2里的相關信息對相關虛擬外圍設備作模擬,模擬完成后通過ERET指令返回vCPU,并從發(fā)生異常的下一條指令繼續(xù)執(zhí)行。
系統(tǒng)內存管理單元(System Memory Management Units, SMMUs)
到目前為止,我們只考慮了從處理器發(fā)起的各種訪問。我們還需要考慮其他主設備如DMA控制器發(fā)起的訪問。我們需要一種方法來擴展stage 2映射以保護這些主設備的地址空間。如果一個DMA控制器沒有使用虛擬化,那它看起來應該如下圖所示
圖10:沒有虛擬化的DMA訪問 DMA控制器通常由內核驅動編程控制。內核驅動會確保不違背操作系統(tǒng)層面的內存保護原則,即一個應用不能使用DMA訪問其沒有權限訪問的其他應用的內存。 下面讓我們考慮操作系統(tǒng)運行在虛擬機中的場景。
圖11:虛擬化下沒有SMMU的DMA訪問 在這個系統(tǒng)中,Hyperviosr通過stage 2映射來隔離不同VMs的地址空間。這是基于Hypervisor控制的stage 2映射表實現(xiàn)的。而驅動則直接與DMA控制器交互,這會產生兩個問題:
隔離:DMA控制器訪問在虛擬機之間沒有了隔離,這破壞了虛擬機的沙箱功能。
地址空間:利用兩級映射轉換,使內核看到的PAs實際上是IPAs。但DMA控制器看到的仍然是PAs。因此DMA控制器和內核看到的是不同的地址空間,為了解決這個問題,每當VM與DMA控制器交互時就需要陷入到Hypervisor中做必要的轉換。這種處理方式是極其沒有效率的,且容易出錯。
解決的辦法是將stage 2的機制推廣到DMA控制器。這么做的話,這些主設備控制器也需要一個MMU,Armv8稱之為SMMU(通常也稱為IOMMU)。
圖12:虛擬化下通過SMMU的DMA訪問 Hypervisor負責配置SMMU,以使DMA控制器看到的物理地址空間與kenrel看到的物理地址空間相同。這樣就能解決上述兩個問題。 轉自:https://calinyara.github.io/technology/2019/11/03/armv8-virtualization.html 相關文章:
-
寄存器
+關注
關注
31文章
5343瀏覽量
120377 -
架構
+關注
關注
1文章
514瀏覽量
25472 -
ARMv8
+關注
關注
1文章
35瀏覽量
14158
原文標題:收藏:Arm v8架構及虛擬化介紹
文章出處:【微信號:架構師技術聯(lián)盟,微信公眾號:架構師技術聯(lián)盟】歡迎添加關注!文章轉載請注明出處。
發(fā)布評論請先 登錄
相關推薦
評論