AArch64 异常等级(exception level)

为什么有异常等级

可以将异常等级想象成几组软件运行的模式。每一种模式拥有一定的操作权限,和访问当前等级下允许访问的寄存器。比如当我们处于最低等级时,我们仅仅有权限访问一些通用寄存器x0-x30, 及栈指针寄存器SP,和str、ldr等操作命令去加载和存储到内存,还有一些用户程序用到的一些其它命令。
一个用户程序仅仅有权限访问自己的数据,而不能访问或修改其它用户程序的数据,通过这种方法来实现系统的权限管理。让每一等级的权力运行在约束之下。(众所周知,没有约束的权力是非常危险的)

什么是异常等级

ARMv8 架构将异常等级和软件的执行权限关联起来,总共定义了4个异常等级:EL0,EL1,El2,EL3。4个异常等级的权限:EL3>EL2>EL1>EL0 每个等级运行的软件通常如下图所示:
异常等级示意图

  1. EL0被称之为无特权的异常等级,通常用于用户程序的执行。执行在用户空间,可称之为用户模式。
  2. EL1常用于操作系统,可称之为管理员模式。
  3. EL2常用于实施虚拟化,来管理虚拟机(客户操作系统)作为虚拟机的监控程序。
  4. EL3被称为安全监视器(EL0-EL2被认为运行在非安全状态)。拥有最高的权限,是唯一拥有切换安全执行状态和非安全执行状态等级的异常等级。

在实际的应用中,不强制要求连续的异常等级。可以放弃对虚拟化(EL2)的支持,仅实现EL3,EL1和EL0 。EL3 和EL2是可选的,EL1和EL0是必须的。

异常等级的切换

异常等级的切换只有在处理器发生异常或者异常之后返回的时候发生。

  • 异常发生时,异常等级只能切换到更高或者保持在相同的异常等级。
  • 异常返回时,异常等级只能切换到更低或者保持在相同的异常等级。

通常异常产生后将会发生一系列事件如下(下面介绍中,ELn代表当前所处的异常等级n,可已是, 0, 1, 2, 3):

  1. 当前指令的地址保存在ELR_ELn(ELR_EL(n+1)? 还不确定,需要后面确认) 寄存器。(ELR_ELn, 即Exception link register。称为异常链接寄存器)
  2. 当前处理器的状态保存在SPSR_ELn寄存器(SPSR_ELn,即Saved Program Status register,称为程序状态寄存器)。
  3. 执行异常所指向的异常处理程序,(个人以为可理解为中断处理函数)。
  4. 异常处理完成后执行eret指令返回。从SPSR_ELn恢复处理器状态,从ELR_ELn寄存器中恢复处理器执行的地址。

这里仅仅介绍了几个典型的步骤,实际上会保存一些其它的寄存器如必要的寄存器数据入栈保护。异常发生之后会有对应的现场恢复。

异常产生

当进程状态(processing element 简称PE)出现异常时即为异常产生,此时异常状态即使PE的状态。
进程只有运行一些非法的指令(访问内存越界,除以0)等。另外也可以通过svc指令产生特定目的的异常。同时,硬件产生的中断也是作为一种特使的异常来处理。

异常返回

通常执行ERET(Exception return)指令返回。需要注意的是:异常返回并不一定恢复之前程序运行的地址并且恢复到之前的处理器状态。SPSR_ELn 和ELR_ELn寄存器都是可以被异常处理函数写入的。

异常的位数

每个异常等级可以运行在64位模式(称为AArch64)和32位模式(称为AArch32)。支持所有异常等级使用AArch64,或者部分异常等级使用AArch32.
注意:

  • EL3异常等级只可以用AArch64模式
  • 如果一个异常等级用了AArch64,那么他的高一级必须是AArch64,比如EL1用AArch64模式,EL2一定是AArch64模式,EL0想用AArch64位模式,EL1和EL2都将是AArch64位模式。

位数的切换

在32位模式(AArch32)和64位模式(AArch64)之间切换称为“互处理” (interprocessing).
位数的切换仅在异常等级切换的时候才会发生,也就是发生异常或者异常返回时。即:
当发生异常时,如果异常等级改变,则位数有两种情况:AArch32-> AArch64, 或者保持不变。
当异常返回时,如果异常等级改变,则位数同样有两种情况:AArch64->AArch32, 或者保持不变。异常等级不变时,位数不变。

异常等级和对应的软件

不同层级的软件(应用,系统内核,虚拟层,安全软件trust)可以运行在不同的异常等级,同样也可以运行不通的位数模式。
不同软件的执行状态仅在重启或者异常等级切换的时候。
下图展示了不同安全级别和异常等级和不同层级的软件之间的关系示意图:
ARMv8架构异常等级和典型的应用示意图
(图片来源于网络,侵删)

异常等级的选择

如上所述,实际应用中,EL0和EL1是必须存在的,EL2和EL3是可选的。

  • 存在EL3,没有EL2时:将不支持硬件虚拟化,但是可以支持安全模式的切换(通常认为EL3时安全状态,EL0-2是非安全状态)
  • 存在EL2,没有EL3时:支持硬件虚拟话,但是不支持安全模式的切换(通常EL2用来实现虚拟化)
  • 当EL2和EL3都没有应用时:不支持虚拟化。运行可以是安全模式或者非安全模式,但是不支持运行期间切换。启动时根据某种设定(例如可以通过修改板子的pin引脚状态)进入不同的安全模式。

参考 https://medium.com/@om.nara/aarch64-exception-levels-60d3a74280e6

猜你喜欢

转载自blog.csdn.net/weixin_43328157/article/details/130201318