0%

如何在Armv8 AArch64中获取当前Exception Level

​ Armv8架构在AArch64运行状态下定义了4种特权级别,也称为Exception Level,分别为:

  • EL0:Application运行在EL0
  • EL1:Rich OS(Linux kernel)运行在EL1
  • EL2:Hypervisor运行在EL2
  • EL3:Firmware/Secure Monitor运行在EL3

不同的任务运行在不同的EL,如果我们想知道当前CPU处于哪个EL(比如在BootLoader中)该如何实现呢?

答案是:CurrentEL寄存器。

​ Armv8 AArch64状态下使用CurrentEL寄存器指示当前CPU所处的EL;该寄存器是64bit只读寄存器,使用[3:2]两个有效位表示EL值,具体定义如下:

CurrentEL bits[3:2] Meaning
0b00 EL0
0b01 EL1
0b10 EL2
0b11 EL3

使用MRS指令访问CurrentEL:

1
MRS <Xt>, CurrentEL

C嵌入汇编示例代码如下,参考自chromium:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#define EL0 0
#define EL1 1
#define EL2 2
#define EL3 3

#define CURRENT_EL_MASK 0x3
#define CURRENT_EL_SHIFT 2

uint64_t get_current_el() {
uint64_t current_el;
asm volatile("mrs %0, CurrentEL\n\t" : "=r" (current_el) : : "memory");
return (current_el >> CURRENT_EL_SHIFT) & CURRENT_EL_MASK;
}

//注意:
//根据Armv8参考手册,CurrentEL不能从EL0级别访问;
//因此如果你尝试在Linux用户空间运行上述代码,会引发SIGILL,程序退出。

注意:

根据Armv8参考手册,CurrentEL不能从EL0级别访问;因此,如果你尝试在Linux用户空间运行上述代码,会引发SIGILL,程序退出。