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 里一个比较特殊的概念。它允许非安全世界触发一个中断,然后安全世界来处理。听起来像是“非安全世界叫安全世界干活”,对吧?
具体流程是这样的:
- 非安全世界触发一个 SGI(Software Generated Interrupt),该 SGI 被配置为安全中断。
- GIC 将该中断路由到安全世界。
- 安全世界的中断处理程序执行,处理完毕后返回非安全世界。
这个机制有什么用?最常见的场景是:非安全世界需要安全世界执行某个敏感操作(比如解密一段数据),但又不希望直接调用 SMC(Secure Monitor Call),因为 SMC 的上下文切换开销比较大。用 NSC 中断,可以更轻量地实现“请求-响应”模式。
我曾经踩过的坑:NSC 中断处理时,安全世界必须非常小心地保存和恢复非安全世界的上下文。有一次我忘了保存非安全世界的寄存器状态,结果安全世界处理完中断返回后,非安全世界直接崩溃了。嗯,从那以后我每次写 NSC 中断处理函数,第一件事就是保存所有可能被污染的寄存器。
4.4 中断路由的完整流程
为了让你更直观地理解,我画了一张流程图:
从这张图你可以看到,中断路由的核心是 GIC 和 SCR 的协同工作。GIC 负责判断中断的 Group,SCR 决定最终路由到哪个世界。
4.5 中断处理的实战要点
讲完了理论,咱们聊聊实际开发中要注意的几个点:
- 中断优先级:安全中断的优先级必须高于非安全中断。否则非安全中断可能抢占安全中断,导致安全世界响应延迟。
- 中断嵌套:安全世界处理中断时,可以再次被更高优先级的安全中断打断,但绝对不能被打断进入非安全世界。这是 TrustZone 的硬性要求。
- 中断屏蔽:在安全世界的临界区里,记得屏蔽所有中断(包括 FIQ)。我见过有人只屏蔽了 IRQ,结果 FIQ 进来把关键数据改乱了。
避坑指南:我曾经在一个项目里,安全世界的加密任务被非安全世界的 DMA 中断打断,导致加密结果出错。后来我把 DMA 中断配成安全中断,并在安全世界的中断处理函数里加了优先级控制,问题才解决。
4.6 小结
中断与异常处理,是 TrustZone 隔离体系里最考验细节的部分。安全中断和非安全中断的划分、FIQ 与 IRQ 的路由策略、NSC 中断的轻量级通信,每一个点都直接影响系统的稳定性和安全性。记住一句话:中断路由的主动权永远在安全世界手里,非安全世界只能被动接受。