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 0FIQ安全世界(EL3/EL1S)
非安全中断Group 1 Non-secureIRQ非安全世界(EL1NS)
安全中断(可配置)Group 1 SecureFIQ或IRQ安全世界

GIC Distributor(GICD)中的IGROUPR寄存器为每个中断线设置分组。Group 0中断始终为安全,Group 1中断可配置为安全或非安全。CPU Interface(GICC)则根据当前安全状态和优先级决定是否将中断递送给CPU。

此外,GIC提供GICD_ISENABLER、GICD_IPRIORITYR等寄存器,安全世界可完全控制安全中断的使能与优先级,而非安全世界只能操作非安全中断对应的寄存器视图。这种寄存器视图隔离,防止非安全软件篡改安全中断配置。

四、方法流程:中断从产生到处理的完整路径

  1. 外设拉高中断线,GIC Distributor采样并识别中断号。
  2. GIC根据IGROUPR判断该中断的安全分组。
  3. 若为Group 0或Group 1 Secure,且当前CPU处于非安全状态,GIC将中断标记为FIQ。
  4. CPU响应FIQ,根据SCR_EL3路由进入EL3或安全EL1。
  5. 安全中断处理程序读取GICC_IAR获取中断号,执行处理。
  6. 处理完成后写GICC_EOIR,通知GIC中断结束。
  7. 若需要返回非安全世界,通过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的状态。

TrustZone 中断路由与 GIC 安全分组 安全外设 安全定时器 / TZPC 非安全外设 网卡 / GPIO / 显示 GIC Distributor (GICD) IGROUPR / IGRPMODR / IPRIORITYR 安全视图隔离 · 中断分组判定 GIC CPU Interface (GICC) 优先级仲裁 · 安全状态判定 · 信号选择 FIQ IRQ 安全世界 (EL3 / EL1S) 处理 Group 0 / Group 1 Secure 非安全世界 (EL1NS) 处理 Group 1 Non-secure Group 0 安全中断 → FIQ Group 1 NS 非安全中断 → IRQ SCR_EL3 FIQ / IRQ 路由位 FIQ 信号 IRQ 信号