4. TrustZone中断架构
在TrustZone系统中,中断不仅是外设通知CPU的手段,更是安全世界与非安全世界之间控制权切换的关键触发源。理解中断架构,核心要回答三个问题:中断属于哪个世界、由谁处理、如何路由。ARM通过GIC(Generic Interrupt Controller)的安全扩展,将中断按安全属性分组,并利用FIQ与IRQ两条物理信号线实现硬件级隔离。
一、核心原理:安全中断与非安全中断
TrustZone将系统划分为安全世界(Secure World)与非安全世界(Normal World)。每个中断源在GIC中被赋予一个安全属性:
- 安全中断(Secure Interrupt):只能由安全世界处理,例如安全定时器、TZPC控制器、安全外设。其配置寄存器通常只允许安全访问。
- 非安全中断(Non-secure Interrupt):由非安全世界处理,例如普通GPIO、网络、显示控制器。
- 可配置中断:部分中断源可通过GIC配置为安全或非安全,由启动阶段的TZ配置决定。
关键点在于:非安全世界无法屏蔽、修改或窃取安全中断。即使非安全OS将IRQ关闭,安全中断仍可通过FIQ送达安全世界。这是TrustZone中断隔离的硬件基础。
二、FIQ与IRQ路由机制
ARM处理器提供两条中断输入线:IRQ和FIQ。在TrustZone架构中,它们被赋予新的路由语义:
- IRQ:通常路由到当前世界的非安全中断处理程序。非安全OS使用IRQ处理普通外设中断。
- FIQ:优先路由到安全世界,用于安全中断。FIQ具有更高优先级,且可配置为仅在安全状态响应。
GIC通过SCR_EL3.IRQ和SCR_EL3.FIQ位控制路由。当CPU处于非安全状态时,若发生安全中断,GIC会将其标记为FIQ,触发异常进入EL3或安全EL1,完成世界切换。反之,非安全中断在安全世界运行时,可被路由回非安全世界处理,避免安全世界被普通中断频繁打断。
SCR_EL3.FIQ = 1:安全中断以FIQ路由到安全世界。
SCR_EL3.IRQ = 0:非安全中断以IRQ路由到非安全世界。
GICD_IGROUPR:设置每个中断的安全分组。
GICD_IGRPMODR:进一步区分Group 0与Group 1。
三、GIC安全扩展与中断分组
GICv2及以后版本引入安全扩展,将中断划分为三类:
| 中断类型 | 分组 | 典型路由 | 处理世界 |
|---|---|---|---|
| 安全中断 | Group 0 | FIQ | 安全世界(EL3/EL1S) |
| 非安全中断 | Group 1 Non-secure | IRQ | 非安全世界(EL1NS) |
| 安全中断(可配置) | Group 1 Secure | FIQ或IRQ | 安全世界 |
GIC Distributor(GICD)中的IGROUPR寄存器为每个中断线设置分组。Group 0中断始终为安全,Group 1中断可配置为安全或非安全。CPU Interface(GICC)则根据当前安全状态和优先级决定是否将中断递送给CPU。
此外,GIC提供GICD_ISENABLER、GICD_IPRIORITYR等寄存器,安全世界可完全控制安全中断的使能与优先级,而非安全世界只能操作非安全中断对应的寄存器视图。这种寄存器视图隔离,防止非安全软件篡改安全中断配置。
四、方法流程:中断从产生到处理的完整路径
- 外设拉高中断线,GIC Distributor采样并识别中断号。
- GIC根据
IGROUPR判断该中断的安全分组。 - 若为Group 0或Group 1 Secure,且当前CPU处于非安全状态,GIC将中断标记为FIQ。
- CPU响应FIQ,根据SCR_EL3路由进入EL3或安全EL1。
- 安全中断处理程序读取GICC_IAR获取中断号,执行处理。
- 处理完成后写GICC_EOIR,通知GIC中断结束。
- 若需要返回非安全世界,通过ERET恢复非安全上下文。
// 安全世界中断处理伪代码
void secure_fiq_handler(void) {
uint32_t iar = read_gicc_iar();
uint32_t irq_id = iar & 0x3FF;
if (irq_id == SECURE_TIMER_IRQ) {
handle_secure_timer();
}
write_gicc_eoir(iar);
// 返回非安全世界
secure_monitor_exit();
}
五、案例场景:安全定时器与非安全网络中断共存
假设系统运行非安全Linux,同时安全世界运行TEE。安全定时器每10ms产生一次Group 0中断,非安全网卡产生Group 1 Non-secure中断。当Linux正在处理网络数据时,安全定时器触发:
- GIC将安全定时器标记为FIQ,优先级高于IRQ。
- CPU暂停Linux执行,进入EL3,保存非安全上下文。
- EL3将控制权交给安全EL1,执行TEE定时任务。
- 任务完成后,通过SMC返回EL3,再ERET回Linux。
- Linux继续处理网络中断,感知不到安全世界的短暂介入。
这一过程实现了时间隔离与中断隔离,非安全世界无法延迟或阻止安全中断。
六、误区与复盘
1. 认为非安全世界可以屏蔽安全中断——错误,FIQ路由不受非安全CPSR屏蔽位控制。
2. 忽略GIC寄存器视图隔离——非安全访问安全寄存器会触发异常或返回零。
3. 将Group 1 Secure误认为非安全——Group 1 Secure仍由安全世界处理。
4. 忘记配置SCR_EL3路由位——导致安全中断无法正确送达安全世界。
复盘要点:中断分组必须在启动早期由安全固件完成配置,且GICD和GICC的安全视图需正确初始化。调试时可通过读取GICD_IGROUPR和GICC_IAR确认中断归属。若安全中断未触发,优先检查SCR_EL3.FIQ是否使能、GICD_IGROUPR是否正确、以及CPU是否处于可响应FIQ的状态。