EL2異常捕獲設置-HCR_EL2

前言

之前寫了一點關於異常的東西,比較淺顯的勾勒了一下異常的全貌,就像一幅20萬像素的地球全景照,20萬像素也就是能畫出藍白相間的圓;畫成這個樣子當然不會是我這種對吹牛都要持證上崗的人的作風。再寫一篇或許更繁複但只求僅能部分指明要害的文章,以表述異常的一個重要分支,EL2層行爲控制相關的寄存器HCR_EL2當然也順手寫到了EL1層同類型的寄存器SCTLR_EL1。爲何選擇HCR_EL2也是有原因的,大概與之前選擇關鍵的思路是一致的;對於Aarch64指令架構下的用於控制的寄存器中,我認爲HCR_EL2是牽扯能力最強的寄存器,所謂牽扯能力就是說涉及的東西最多的。因爲EL3不是研究的目標,EL1是爲內核層次設計,百度的大神們已經講述的非常多,所以挑出HCR_EL2進行分析,並儘可能將其控制位的設計目標表述清楚。本文假設閱讀者已經看過<Aarch64異常>並基於ARM指令集的DDI0487版本,最高到arm-v8.3版本。

正文

HCR_EL2寄存器的控制位大概是44個,佔了45bit,有一個控制位佔了兩位。綜合來說,HCR_EL2的控制位是爲了確定所產生的異常是否要被捕獲到EL2,因此各個控制位的定義如下:

1.手工地址轉換產生的異常(AT)控制

主要控制EL1能否手工執行地址轉換指令。地址轉換是由MMU完成,AT S1ExR/W指令在執行完成後,可以從PAR_EL1中讀取出轉換結果。此控制位置0則不會捕獲EL1執行的ATS1ExR/W指令產生的異常;此控制位置1則會捕獲EL1執行的AT S1ExR/W指令產生的異常到EL2。

2.嵌套虛擬化產生的異常(NV/NV1)。

NV 爲了嵌套虛擬化存在,所謂嵌套虛擬化是指在EL1中運行Guest Hypervisor。對於嵌套虛擬化我並不感興趣,但是這裏面透露出如何在EL1中運行一個Hypervisor,使其正常運行在EL1。EL1訪問CurrentEL寄存器得到的值是0x2;EL1訪問特殊用途寄存器、系統寄存器;執行EL1/2轉換規則的地址轉換和TLB維護指令;都會被捕獲到EL2。具體的特殊用途寄存器和系統寄存器是:

所有用MRS/MSR訪問的命名末尾是_EL2/_EL12/_EL02的寄存器;

用MRS/MSR訪問的特殊目的寄存器SPSR_irq/SPSR_abt/SPSR_und/SPSR_fiq;

用MRS/MSR訪問的特殊寄存器SP_EL1。

具體的要捕獲的指令還有:

EL2轉換規則的地址轉換指令和TLB維護指令;

    只有從EL2/EL3能訪問的EL1轉換規則的地址轉換指令和TLB維護指令;

ERET、ERETAA和ERETAB指令。

TSC爲1且EL3未實現的SMC指令。

解釋一下:

CurrentEL寄存器是隻讀的,需要EL1以上才能訪問,指示當前的異常等級,也就是說NV位可以使CurrentEL騙人。MRS/MSR自不必說,SPSR_irq/abt/und/fiq就比較有趣了,在Aarch64異常中,EL1/2/3分別有自己的SPSR寄存器,作爲異步異常的IRQ、FIQ以及32位相關的Abort狀態、Undefined狀態都有SPSR的,作用與SPSR_ELx一致。ERET自然就是從異常返回的指令了,也是要被捕獲到EL2。 

NV1 應該算是NV的副手,第一個用途是決定EL1對VBAR_EL1、ELR_EL1、SPSR_EL1的訪問是否被捕獲到EL2。當NV==1且NV1==0,發生到EL1和EL1發生的異常,引起SPSR_EL1.M[3:2](標誌EL等級)值0b10,而不是0b01。當NV==1且NV1==1,EL1頁表塊頁中的標誌位[54]會是PXN而不是UXN;[53]位變爲保留,[6]位被當做0處理。在多層次權限使能情況下,EL1轉換表Table標誌位的[61]作爲0;[60]保留PXN表而不是UXN表,[59]變爲保留。除直接讀取,EL1的PSTATE.PAN被當做0處理。EL1執行LDTR*/STTR*指令與LDR*/STR*一樣。

上面一段話是原樣翻譯過來的,我解釋一下這裏面的東西:

VBAR_EL1寄存器是用於保存EL1的異常向量的基地址;EL1對VBAR_EL1的訪問被捕獲到EL2,很明顯是爲了防止Guest Hypervisor中運行的EL1的內核使用了EL1的異常向量。ELR_EL1異常返回地址,同樣不能使用。SPSR_EL1是異常發生時會使用的PSTATE,也是不能直接使用。

PXN和UXN的內容就比較多,但是非常有價值,因此單獨取出解析一下:

XN是Execute-Never,XN位表示此頁表項管理下的內存數據可以作爲代碼執行;

PXN只有1階段頁表且1階段頁表可以支持兩個VA範圍的情況下存在,置位後表示僅有>EL0狀態下才能執行從此內存段的代碼;

UXN標誌表示只有EL0狀態下才能將此頁表管理的內存中的數據作爲代碼執行。

當廠商提供CPU未支持ARMv8.2-TTS2UXN,XN在2階轉換中同樣是1位;

當ARMv8.2-TTS2UXN被支持,XN由2bit組成:

XN[1]==0,XN[0]==0,則2階段控制:允許EL1和EL0執行此內存段數據;

XN[1]==0,XN[0]==1,則2階段控制:不允許EL1執行內存段數據,但允許EL0執行;

XN[1]==1,XN[0]==0,則2階段控制:不允許EL1和EL0執行內存段數據;

XN[1]==1,XN[0]==1,則2階段控制:允許EL1執行內存段數據,不允許EL0執行。

3.指針認證(Pointer Authentication)相關的異常。

Pointer Authentication具體是個什麼東西並不瞭解,但其相關的指令非常之多。

4.緩存一致性相關(MIOCNCE)

具體不知道幹啥,只知道ARM strongly 推薦不用。

5.EL1/0同步外部異常路由設置(TEA)

 

6.錯誤回溯寄存器訪問異常的捕獲(TERR)

 

7.LOR寄存器的訪問異常的捕獲(TLOR)

LOR並不知爲何物。

8.內核運行異常等級設置(E2H)。

置位後,表示EL2運行有一個操作系統。而置零時表示EL2運行的是Hypervisor。當E2H爲0時,TCR_EL2控制EL2轉換規則的1階段,支持單VA範圍,使用TTBR0_EL2作爲頁表基地址寄存器;當E2H爲1時,TCR_EL2控制1階段EL2&0轉換規則,同時支持低VA範圍(TTBR0_EL2)和高VA範圍(TTBR1_EL2)。

E2H==0時TCR_EL2並不複雜,我簡單說一下其中控制位(忽略可廠商自定義的位)。

HPD位是多級權限控制位,影響多級控制位,影響TTBR0_EL2指向的轉換表APTable、PXNTable和UXNTable。

HD爲使能硬件髒頁自動回寫,需要HA位使能,

HA位使能即硬件可訪問標誌位更新;這些都是EL2執行1階段轉換的控制。

TBI是頭字節忽略。

PS是物理地址大小:

000是32位4GB;

001是36位64GB;

   010是40位1TB;

011是42位4TB;

100是44位16TB;

   101是48位256TB;

110是52位4PB。

TG0控制TTBR0_EL2的物理分頁單位:

   00是4K每頁,

01是64K每頁,

10是16K每頁。

SH0控制內存的共享屬性,與使用TTBR0_EL2的TTW相關聯:

   00是不可共享;

10是Outer共享;

11是Inner共享。

ORGN0和IRGN0是內存Outer/Inner緩存能力屬性,與TTBR0_EL2相關聯:

   00是普通內存的Outer/Inner不可緩存;

   01是普通內存的Outer/Inner回寫、讀分析、寫分配可緩存;

   10是普通內存的Outer/Inner寫通、讀分配、無寫分配可緩存;

   11是普通內存的Outer/Inner回寫、讀分配無寫分配可緩存;

   按我的理解解釋一下,Outer是二級緩存,Inner是一級緩存,

   回寫、寫通當然就是兩種cache形式,

   讀分配應該是讀取會使用緩存,寫分配應該是寫入會使用緩存。

E2H==1時TCR_EL2的控制位就比較多了,不過主要功能還是上面的東西,需要關注兩個地址範圍TTBR0_EL2和TTBR1_EL2,大致比上面的控制位翻了一倍。

9.2階段指令、數據緩存是否允許使用(ID/CD)。

 

10.低異常狀態執行控制(RW)

置零決定EL1是aarch32;置1決定EL1是aarch64,其EL0的執行狀態還是由PSTATE.nRW決定。

11.虛擬內存管理寄存器讀取控制(TRVM)

此處所謂內存管理寄存器是指(aarch64):SCTLR_EL1,TTBR0_EL1,TTBR1_EL1,TCR_EL1,ESR_EL1,FAR_EL1,AFSR0_EL1,AFSR1_EL1,MAIR_EL1,AMAIR_EL1,CONTEXIDR_EL1。

哇!好多寄存器,但是很開心的發現這裏面出現了許多熟悉的面孔,存儲頁表基地址的TTBR0_EL1(低地址段)、TTBR1_EL1(高地址段),其中的ASID佔8位(ASID是啥我就不說了),另外的48位是基地址。

TCR_EL1也可參照TCR_EL2知道其控制的內容。

ESR_EL1是能給出異常發生原因的狠人,在<Aarch64異常>中已經見識過。

FAR_EL1存同步指令數據中止或PC對齊或觀察點異常的失敗虛擬地址,也提過了。

AFSR0_EL1/AFSR1_EL1是歸廠商自定義的。

MAIR_EL1/AMAIR_EL1是內存屬性相關(如Inner、Outer內存的寫通、回寫等屬性)。

CONTEXTIDER_EL1放的是進程ID,需要內核設入,使CPU知道當前運行的進程ID,手冊說僅可用於Debug和Trace邏輯。

上述寄存器就只剩下SCTLR_EL1是未知的了,但不得不說,SCTLR_EL1也是個內容豐富的寄存器呀,內容量大概有本文的一半。SCTLR_EL1的地位主要在於控制EL0的一些操作是否產生異常並路由到EL1, 是不是有點熟悉。。。本文對HCR_EL2開頭也有類似的這麼一句。。。所以說SCTLR_EL1在EL1/0與HCR_EL2在EL2/1/0是差不多的,不過HCR_EL2很明顯更大,更強,因此簡要說明SCTLR_EL1內容

EnIA/EnIB/EnDA/EnDB是指針認證相關控制位,還是忽略。

UCI是捕獲EL0的cache維護指令到EL1,置零後EL0執行:

DC CVAU(按地址清理數據緩存PoU)、

DC CIVAC(按地址清除並失效數據緩存PoC)、

DC CVAC(按地址清除緩存PoC)、

DC CVAP(按地址清除緩存PoP,如內存不識別Persistence操作則與DC CVAC)、

IC IVAU(按地址失效指令緩存PoU)

將會被捕獲到EL1。

在此我似乎應該說一下PoU和PoC,簡單講PoC是所有能訪存的設備的同步點(特定地址下,數據內容一致),PoU是一個Core去與主存同步一下。

EE、E0E是大小端相關的控制位。

SPAN是對PSTATE.PAN的控制:

置零則發生異常到EL1時,PSTATE.PAN置1;

   置1則發生異常到EL1時PSTATE.PAN保持原樣。

IESB位控制在異常入口、出口添加的隱式的錯誤同步事件。

WXN位可控制EL1&0轉換規則,強制所有可寫內存區域都作爲XN處理。

nTWE/nTWI位控制捕獲EL0執行WFE/WFI指令到EL1。

UCT位可捕獲EL0訪問CTR_EL0寄存器到EL1。

CTR_EL0位提供cache的架構信息。

DZE位捕獲EL0執行DC ZVA指令到EL1:

   DC ZVA是按地址將數據緩存歸零:將自然對齊的N字節的塊歸零,N由DCZID_EL0確定。

I位控制指令訪問可緩存行控制。

UMA位EL0執行MSR/MRS訪問PSTATE的D/A/I/F掩碼捕獲到EL1。

SA0位控制使能EL0的SP對齊檢查。

SA位控制使能EL1的SP對齊檢查。

C位控制數據訪問的緩存能力控制。

A位控制指令對齊檢查。

M位控制EL1/0的1階地址轉換使能。

另外還有其他32位相關的控制位沒有列出。

SCTLR_EL1的功能明顯較HCR_EL2更少一些,不過EL2也還有自己的SCTLR_EL2寄存器,當HCR_EL2關閉E2H和TGE的時候,SCTLR_EL2功能較少,但當E2H和TGE打開後SCTLR_EL2的功能就與SCTLR_EL1差不多了。

12.HVC指令的關閉(HCD)

  

13.對EL0/1執行DC ZVA指令的捕獲(TDZ)

DC ZVA指令在11.9的SCTLR_EL1介紹中有提到,

EL0執行DC ZVA可以被SCTLR_EL1.DZE設置爲被捕獲到EL1,

EL1和EL0執行DC ZVA可以都被HCR_EL2.TDZ設置爲捕獲到EL2

14.對EL0產生的異常的捕獲(TGE)

 

15.對EL1寫虛擬內存控制寄存器的捕獲(TVM)

TRVM控制EL1對虛擬內存控制寄存器的讀,TVM控制寫,相關的虛擬內存控制寄存器都是一樣的。

16.對EL1執行TLB維護指令的捕獲(TTLB)

其涉及的相關指令主要是失效TLB中緩存的轉換表條目。

17.對EL0/1指令緩存維護(PoU)的捕獲(TPU)

捕獲cache的PoU維護指令:EL0主要用IC IVAU和DC CVAU(受到SCTLR_EL1控制),在前面已經提到過IC IVAU和DCCVAU的功能;EL1主要用IC IVAU,IC IALLU,IC IALLUIS,DCCVAU,指令功能也已經提到;

18.對EL0/1數據或統一緩存維護(PoC/Persistence)指令的捕獲(TPCP)

EL0主要用DC CIVAC,DC CVAC,DCCVAP,受到SCTLR_EL1控制,第一個C表示清理,I表示失效,最後一個C是Coherency,指令功能前面已經提過。

EL1主要用DC IVAC,DC CIVAC,DCCVAC,DC CVAP。

19.對EL1數據或統一緩存(按Set/Way)維護指令的捕獲(TSW)

EL1主要涉及指令爲:DC ISW,DC CSW,DCCISW,C表示清理,I表示失效,SW表示set/way。

20.對EL1訪問Auxiliary控制寄存器的捕獲(TACR)

訪問廠商定義管理寄存器ACTLR_EL1捕獲到EL2。

21.對EL1訪問廠商自定義功能的捕獲(TIDCP)

 

22.對EL1執行SMC指令的捕獲(TSC)

 

23.對EL1讀ID group3/2/1/0寄存器的捕獲(TID3/2/1/0)

 

24.對EL0/1執行WFE/WFI指令的捕獲(TWE/TWI)

 

25.試圖關閉EL0/1的一階段頁錶轉換並保持2階段頁錶轉換(DC)

SCTLR_EL1的對一階段轉換的控制力小於HCR_EL2.DC;HCR_EL2.VM的控制力也小於HCR_EL2.DC,無論VM位怎樣,2階段頁錶轉換會被打開。提供給EL1&0的轉換規則是,普通內存不可共享(non-shareable),Inner回寫(write-back)、讀申請(read-allocate)、寫申請(write-allocate),Outer回寫、讀申請、寫申請。

26.控制EL0/1內存屏障的最小共享域(BSU,2bit)

所謂內存屏障的最小共享域,內存屏障(barrier)我就不說了,內存屏障的minimum shareabilitydomain我認爲是指所執行的內存屏障指令能夠影響的範圍。

00表示無影響,這個無影響應該是說只清空了Core的流水線?

01是InnerShareable,這應該表示會引起1級緩存的一致?

10是OuterShareable,這應該是表示會引起1、2級緩存的一致點(類似PoU)?

11是Fullsystem,這應該就是屏障會觸發PoC點了?

上述是猜測,如有精確解釋請不吝指出[email protected]

27.強制一些EL1執行的指令在內Inner共享域廣播(FB)

這些指令是:

TLBI VMALLE1(按VMID失效TLB),

TLBI VAE1(按ASID下的VA失效TLB),

TLBI ASIDE1(按ASID失效TLB),

TLBI VAAE1(按VA失效TLB,所有ASID),

TLBI VALE1(按ASID下的VA失效最低級TLB),

TLBI VAALE1(按VA失效最低級TLB,所有ASID)

IC IALLU(失效所有cache到PoU點)

28.虛擬SError中斷觸發標誌(VSE)

 

29.虛擬IRQ中斷觸發標誌(VI)

 

30.虛擬FIQ中斷觸發標誌(VF)

 

31.物理SError/IRQ/FIQ中斷路由控制(AMO/IMO/FMO)

除被路由到EL3外,上述中斷均路由到EL2,如果HCR_EL2.TGE==0則vSError/vIRQ/vFIQ都會打開。

34.對TTW的保護(PTW)

階段的TTW服從2階段轉換;兩階段轉換後,內存類型屬性可能是設備內存;當這種情況發生,PTW置1則產生2階段權限失敗。

35.EL1執行的按Set/Way數據緩存失效是否引起數據緩存的清除(SWIO)

 

36.EL0/1的2階段地址轉換的使能(VM)

爲EL1&0的轉換規則使能2階段轉換。使能後,執行EL1的數據緩存失效指令將會變成數據緩存清除並失效。

  •  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章