4. 中断与异常处理:安全中断与非安全中断、FIQ 与 IRQ 路由、NSC 中断处理

中断和异常,是 TrustZone 隔离体系里最容易被低估的环节。很多人觉得把内存隔开、外设分好组就万事大吉了,结果一跑起来,非安全世界的中断把安全世界给冲了,或者安全中断响应慢了半拍导致系统崩溃。嗯,我在项目里就吃过这个亏,所以今天咱们把这部分彻底讲透。

4.1 安全中断 vs 非安全中断:谁说了算?

在 ARMv8-A 的 TrustZone 架构里,中断不再只是简单的“来了就处理”。每个中断源都有一个属性:它是安全的,还是非安全的?这个属性由中断控制器(GIC,Generic Interrupt Controller)来管理。

GIC 会为每个中断分配一个 Group:

  • Group 0:安全中断,只能由安全世界处理。
  • Group 1:非安全中断,由非安全世界处理。

但这里有个关键点:GIC 本身是安全世界的资源。非安全世界不能修改中断的安全属性。说白了,安全世界在启动阶段就把中断的“归属权”定死了,非安全世界只能被动接受。

核心原则:中断的安全属性由 GIC 的配置决定,且只能由安全世界软件修改。非安全世界无权干涉。

我在项目中遇到过一个问题:某个外设的中断在非安全世界被频繁触发,但安全世界需要偶尔访问这个外设。结果每次安全世界访问时,中断状态都被非安全世界搞乱了。后来我直接把该中断配成安全中断,由安全世界统一管理,问题就解决了。

4.2 FIQ 与 IRQ 路由:两条独立的“车道”

ARM 架构里有两个物理中断线:IRQ 和 FIQ。在 TrustZone 里,它们被赋予了新的含义:

  • IRQ:通常路由给非安全世界。
  • FIQ:通常路由给安全世界。

但这只是“通常”。实际上,你可以通过 SCR(Secure Configuration Register)寄存器来配置路由策略。SCR 里有几个关键位:

SCR 位 功能 说明
IRQ IRQ 路由控制 0:路由到当前异常级别;1:强制路由到安全世界
FIQ FIQ 路由控制 0:路由到当前异常级别;1:强制路由到安全世界
EA 外部中止路由 控制外部中止(External Abort)的路由

为什么要有两条车道?你想想看,如果安全世界和非安全世界共用一条中断线,那安全世界在处理关键操作时,非安全世界的中断突然插进来,安全上下文就被污染了。FIQ 作为安全世界的“专用通道”,可以保证安全关键任务不被干扰。

个人习惯:我一般把 FIQ 留给安全世界的实时任务(比如 TEE 的加密操作),IRQ 给非安全世界的普通中断。这样即使非安全世界的中断风暴来了,安全世界也能稳如泰山。

4.3 NSC 中断处理:安全世界的“特快专递”

NSC(Non-Secure Callable)中断,是 TrustZone 里一个比较特殊的概念。它允许非安全世界触发一个中断,然后安全世界来处理。听起来像是“非安全世界叫安全世界干活”,对吧?

具体流程是这样的:

  1. 非安全世界触发一个 SGI(Software Generated Interrupt),该 SGI 被配置为安全中断。
  2. GIC 将该中断路由到安全世界。
  3. 安全世界的中断处理程序执行,处理完毕后返回非安全世界。

这个机制有什么用?最常见的场景是:非安全世界需要安全世界执行某个敏感操作(比如解密一段数据),但又不希望直接调用 SMC(Secure Monitor Call),因为 SMC 的上下文切换开销比较大。用 NSC 中断,可以更轻量地实现“请求-响应”模式。

我曾经踩过的坑:NSC 中断处理时,安全世界必须非常小心地保存和恢复非安全世界的上下文。有一次我忘了保存非安全世界的寄存器状态,结果安全世界处理完中断返回后,非安全世界直接崩溃了。嗯,从那以后我每次写 NSC 中断处理函数,第一件事就是保存所有可能被污染的寄存器。

4.4 中断路由的完整流程

为了让你更直观地理解,我画了一张流程图:

TrustZone 中断路由流程图 TrustZone 中断路由流程 非安全中断源 安全中断源 GIC 中断控制器 Group 0 / Group 1 判定 SCR 路由决策 IRQ/FIQ 位判定 安全世界 (FIQ) TEE 中断处理 非安全世界 (IRQ) REE 中断处理 NSC 中断:非安全→安全 IRQ → 非安全世界 FIQ → 安全世界

从这张图你可以看到,中断路由的核心是 GIC 和 SCR 的协同工作。GIC 负责判断中断的 Group,SCR 决定最终路由到哪个世界。

4.5 中断处理的实战要点

讲完了理论,咱们聊聊实际开发中要注意的几个点:

  • 中断优先级:安全中断的优先级必须高于非安全中断。否则非安全中断可能抢占安全中断,导致安全世界响应延迟。
  • 中断嵌套:安全世界处理中断时,可以再次被更高优先级的安全中断打断,但绝对不能被打断进入非安全世界。这是 TrustZone 的硬性要求。
  • 中断屏蔽:在安全世界的临界区里,记得屏蔽所有中断(包括 FIQ)。我见过有人只屏蔽了 IRQ,结果 FIQ 进来把关键数据改乱了。

避坑指南:我曾经在一个项目里,安全世界的加密任务被非安全世界的 DMA 中断打断,导致加密结果出错。后来我把 DMA 中断配成安全中断,并在安全世界的中断处理函数里加了优先级控制,问题才解决。

4.6 小结

中断与异常处理,是 TrustZone 隔离体系里最考验细节的部分。安全中断和非安全中断的划分、FIQ 与 IRQ 的路由策略、NSC 中断的轻量级通信,每一个点都直接影响系统的稳定性和安全性。记住一句话:中断路由的主动权永远在安全世界手里,非安全世界只能被动接受。