赞
踩
前言之前写了一点关于异常的东西,比较浅显的勾勒了一下异常的全貌,就像一幅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点了? 上述是猜测,如有精确解释请不吝指出ab12696@qq.com。 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的数据缓存失效指令将会变成数据缓存清除并失效。 |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。