ARMv8 SP_ELx

在 ARMv8/AArch64 架构中,SP_ELx 是不同异常级别(Exception Level, EL)的 栈指针寄存器,用于管理当前执行环境的栈。以下是各异常级别下栈指针寄存器的详细解释:


1. 异常级别(EL)与 SP_ELx 寄存器

异常级别 描述 对应的栈指针寄存器
EL0 用户态(User Mode) SP_EL0
EL1 操作系统内核(Kernel) SP_EL1
EL2 虚拟机监控程序(Hypervisor) SP_EL2
EL3 安全监控程序(Secure Monitor) SP_EL3

2. SP_ELx 的核心行为
(1) 栈指针的选择规则
• 当处理器处于 ELx 时,默认使用 SP_ELx 作为栈指针。

• 通过 SPSel 寄存器(Stack Pointer Select)可以选择是否使用 SP_EL0

SPSel = 1(默认):使用 SP_ELx

SPSel = 0:使用 SP_EL0(仅当当前 EL ≥ EL1 时有效)。

(2) 关键特性
• EL0 的栈指针:

• 只能使用 SP_EL0(不可访问 SP_EL1 或其他栈指针)。

• 由操作系统为用户程序分配和管理。

• EL1-EL3 的栈指针:

• 特权级代码可以自由切换 SP_ELxSP_EL0

• 例如,在 EL3 中可以通过 msr spsel, #0 切换到 SP_EL0


3. 不同异常级别的详细行为
(1) EL0(用户态)
• 栈指针:强制使用 SP_EL0

• 权限:用户态程序无法直接修改 SP_EL0(需通过系统调用)。

• 用途:用户程序的栈(如函数调用、局部变量)。

(2) EL1(操作系统内核)
• 默认栈指针:SP_EL1

• 切换栈指针:

msr spsel, #0   // 切换到 SP_EL0(临时使用)
msr spsel, #1   // 切换回 SP_EL1

• 用途:

SP_EL1:内核代码的栈(如中断处理、系统调用)。

SP_EL0:临时保存用户态栈(例如在内核中模拟用户栈)。

(3) EL2(虚拟机监控程序)
• 默认栈指针:SP_EL2

• 切换栈指针:与 EL1 类似,可通过 SPSel 选择 SP_EL0

• 用途:

SP_EL2:Hypervisor 的栈(如虚拟机管理、虚拟中断处理)。

SP_EL0:临时使用(例如在 Hypervisor 中模拟客户机栈)。

(4) EL3(安全监控程序)
• 默认栈指针:SP_EL3

• 切换栈指针:

msr spsel, #0   // 切换到 SP_EL0(例如在安全监控代码中)

• 用途:

SP_EL3:安全世界(Secure World)的栈(如 SMC 调用处理)。

SP_EL0:临时使用(例如在安全监控代码中隔离不同任务)。


4. 代码示例与操作
(1) 切换栈指针(从 EL3 切换到 SP_EL0)

// 保存当前 SP_EL3 到通用寄存器
mov x10, sp

// 切换到 SP_EL0
msr spsel, #0

// 使用 SP_EL0 的栈
mov sp, x0  // x0 是新的栈地址

// 执行操作(例如保存寄存器到新栈)
stp x1, x2, [sp, #-16]!

// 恢复 SP_EL3
msr spsel, #1
mov sp, x10

(2) 在 EL1 中访问 SP_EL0

// 检查当前 EL(假设当前为 EL1)
mrs x0, CurrentEL
cmp x0, #(1 << 2)
b.ne not_el1

// 切换到 SP_EL0
msr spsel, #0

// 使用 SP_EL0 的栈
mov sp, #0x8000  // 设置新的栈地址

// 切换回 SP_EL1
msr spsel, #1

5. 栈指针隔离与安全
• EL3 的栈隔离:

• 安全世界(Secure World)的栈(SP_EL3)与非安全世界(Non-secure World)的栈(SP_EL1/SP_EL0)完全隔离。

• 通过 SCR_EL3.NS 位控制安全状态。

• 虚拟机隔离:

• Hypervisor(EL2)的栈(SP_EL2)与客户机(EL1/EL0)的栈隔离。

• 通过 VTTBR_EL2 和 VTCR_EL2 实现虚拟机内存隔离。


6. 总结

场景 栈指针行为
用户程序(EL0) 只能使用 SP_EL0,由操作系统分配。
内核(EL1) 默认用 SP_EL1,可临时切换到 SP_EL0(例如处理用户态请求)。
Hypervisor(EL2) 默认用 SP_EL2,栈隔离不同虚拟机。
安全监控(EL3) 默认用 SP_EL3,管理安全世界与非安全世界的切换。

理解 SP_ELx 的行为对以下场景至关重要:

  1. 异常处理:在中断或系统调用时切换栈。
  2. 权限隔离:确保不同特权级的代码使用独立的栈。
  3. 安全设计:防止低特权级代码破坏高特权级的栈。
posted @ 2025-05-13 10:15  颜小雀  阅读(40)  评论(0)    收藏  举报