【DeepSeek】BL31 的服务,都必须通过 SMC 指令进入
是的,你的理解非常准确!BL31 作为 ARM Trusted Firmware-A (TF-A) 的运行时服务,常驻于 EL3,任何非 EL3 的代码想要请求 BL31 的服务,都必须通过 SMC 指令进入。
以下是详细的机制解析:
一、BL31 的定位与运行级别
BL31 的核心特征:
- 运行级别:EL3(最高特权级)
- 生命周期:系统启动后常驻内存,永不退出
- 职责:充当安全监控器,管理世界切换和安全服务
二、为什么必须用 SMC 调用?
1. 特权级隔离原则
| 调用者 | 当前 EL | 目标 EL | 必须使用的指令 |
|---|---|---|---|
| Linux Kernel | EL1 | EL3 | SMC |
| OP-TEE | EL1 (Secure) | EL3 | SMC |
| Hypervisor | EL2 | EL3 | SMC |
| U-Boot (BL33) | EL2/EL1 | EL3 | SMC |
原因:
SVC只能从 EL0 切换到 EL1HVC只能从 EL0/EL1 切换到 EL2- 只有
SMC能切换到 EL3
2. SMC 调用标准(SMCCC)
ARM 定义了 SMC Calling Convention (SMCCC),规定了如何通过寄存器传递参数:
// SMC 调用约定
x0 = Function ID (功能号,标识请求的服务)
x1 ~ x7 = 参数
SMC #0
// 返回时
x0 ~ x4 = 返回值
三、BL31 服务调用完整流程
以 Linux 内核请求 CPU 休眠(PSCI 服务)为例:
四、BL31 提供的典型服务
| 服务类型 | Function ID 范围 | 典型功能 |
|---|---|---|
| PSCI | 0x8400xxxx / 0xC400xxxx | CPU 开关机、休眠、系统复位 |
| SiP | 0x8200xxxx | 厂商自定义服务 |
| OEM | 0x8300xxxx | OEM 厂商服务 |
| Standard | 0x8600xxxx | 标准 Secure Service |
示例:系统复位
// Linux 内核中的调用
void psci_system_reset(void)
{
// x0 = PSCI_FN_SYSTEM_RESET (0x84000009)
// x1 = reset_type (复位类型)
asm volatile(
"mov x0, #0x84000009\n"
"mov x1, #0\n" // 冷复位
"smc #0\n"
);
// 永远不会执行到这里
}
五、BL31 内部的处理机制
// BL31 的 SMC 处理流程(简化)
void smc_handler64(void) {
uint64_t smc_fid = get_smc_fid(x0); // 获取功能号
// 根据功能号分发
if (is_psci_fid(smc_fid)) {
ret = psci_smc_handler(smc_fid, x1, x2, x3);
}
else if (is_sip_fid(smc_fid)) {
ret = sip_smc_handler(smc_fid, x1, x2, x3);
}
else {
ret = SMC_UNK; // 未知服务
}
// 设置返回值
x0 = ret;
eret(); // 返回调用者
}
六、特殊情况说明
1. 中断也可以进入 EL3
除了 SMC,以下异步异常也会进入 BL31:
| 异常类型 | 触发源 | 用途 |
|---|---|---|
| IRQ | 外部中断 | EL3 处理安全中断 |
| FIQ | 快速中断 | TrustZone 安全中断 |
| SError | 系统错误 | 致命错误处理 |
2. BL31 内部调用不需要 SMC
如果代码已经在 EL3(BL31 内部),直接函数调用即可:
// 在 BL31 内部
void bl31_internal_call(void) {
// 已经在 EL3,直接调用
psci_cpu_on(target_cpu, entrypoint);
// 不需要 SMC
}
七、总结
核心结论:
- ✅ BL31 常驻 EL3,是安全世界的守门人
- ✅ SMC 是唯一标准入口,从非 EL3 进入 BL31 必须用 SMC
- ✅ 遵循 SMCCC 规范,通过 x0 传递功能号,x1-x7 传参
- ✅ BL31 处理后通过 ERET 返回,恢复调用者状态
这就是为什么在 Linux 内核中,所有 PSCI(电源管理)相关操作最终都会执行 smc 指令的原因。
这是一个非常敏锐的安全问题!你的担忧很有道理:如果随便发个中断就能进 EL3,那安全隔离岂不是形同虚设?
答案是:无法绕过。
虽然中断能进入 EL3,但它和 SMC 调用有本质区别。简单来说:SMC 是“办事窗口”,中断是“应急通道”。
一、为什么中断无法绕过安全检查?
1. 执行流不可控
| 特性 | SMC 调用 | 中断进入 |
|---|---|---|
| 触发方式 | 软件主动执行 SMC 指令 |
硬件外部信号触发 |
| 目标代码 | 根据 x0(功能号) 查表跳转 | 跳转到 固定的中断向量 |
| 能否指定服务 | ✅ 可以(我想执行 PSCI 关机) | ❌ 不可以(只能执行中断处理逻辑) |
| 能否传参 | ✅ 可以(x1-x7 自由设置) | ❌ 不可以(寄存器保存的是被打断的上下文) |
2. 中断处理逻辑是固定的
当 IRQ 触发进入 EL3 时,CPU 跳转到 VBAR_EL3 + Offset,执行的是 BL31 预先写死的代码:
// BL31 中断处理流程(伪代码)
void el3_irq_handler(void) {
// 1. 保存上下文(此时 x0-x7 是被打断进程的数据,不是服务参数)
save_context();
// 2. 查询中断控制器(GIC),看是谁发的中断
uint32_t intid = gic_get_pending_irq();
// 3. 根据中断号分发(这是硬件中断号,不是 SMC 功能号)
switch (intid) {
case SECURE_TIMER_IRQ:
handle_secure_timer();
break;
case SGI_FOR_WORLD_SWITCH:
// 可能用于 OP-TEE 与 Linux 的通信调度
handle_world_switch_request();
break;
default:
panic(); // 未知中断,直接报错
}
// 4. 恢复上下文返回
eret();
}
关键点:你在 EL1/EL0 触发中断后,只能执行 BL31 允许你执行的那几段固定逻辑(比如处理定时器、维护调度),无法像 SMC 那样请求“CPU 下电”或“修改安全内存”。
二、中断路由控制:大部分中断进不了 EL3
ARM 架构通过 GIC(中断控制器) 严格控制谁能接收中断:
配置示例
BL31 在启动时会配置 GIC:
// BL31 初始化代码
void gic_setup(void) {
// 将 UART 中断路由给 Linux (EL1)
gic_set_group(UART_IRQ, GICV3_GROUP1_NS);
// 将安全定时器中断路由给 EL3
gic_set_group(SEC_TIMER_IRQ, GICV3_GROUP0);
// 将 SGI (软件中断) 配置为只能由 EL3 接收
// 即使 EL1 尝试触发 SGI,也只会路由到 EL1 自己
}
结论:EL1/EL0 的大部分外设中断(网卡、磁盘、UART)根本进不了 EL3,只能去 EL1。
三、对比:SMC vs 中断进入 EL3
场景:恶意代码想关机
❌ 尝试 1:通过中断绕过
// 恶意代码在 EL1
mov x0, #PSCI_SYSTEM_OFF // 想关机
// 尝试触发一个 IRQ?
// 问题:无法把 x0 传给中断处理函数
// 问题:中断处理函数根本不解析 x0,也不提供关机服务
trigger_irq();
// 结果:EL3 只是处理了中断,然后返回继续执行,根本没关机
✅ 正确方式:通过 SMC
// 正常代码在 EL1
mov x0, #PSCI_SYSTEM_OFF
smc #0
// 结果:EL3 解析 x0,执行关机逻辑
四、那中断进入 EL3 有什么用?
既然不能“办事”,为什么还要让中断进 EL3?
| 用途 | 说明 |
|---|---|
| 世界调度 | OP-TEE (Secure) 和 Linux (Non-Secure) 切换时,通过 SGI 中断通知 EL3 |
| 安全定时器 | EL3 自己的定时器中断,用于实现可信时间源 |
| 电源管理事件 | 比如系统休眠唤醒的硬件信号,需要 EL3 第一时间处理 |
| 错误处理 | SError(总线错误)可能需要 EL3 收集故障信息 |
五、安全模型总结
核心结论
- 中断只能“进”,不能“用”:中断可以触发 EL3 代码执行,但执行什么完全由 BL31 预先定义,攻击者无法注入意图。
- SMC 是唯一的“服务接口”:只有 SMC 允许非安全世界传递参数(Function ID)并请求特定操作。
- 路由隔离:绝大多数中断被 GIC 拦截在 EL1,根本无法触及 EL3。
所以,中断机制不会破坏 EL3 的安全隔离,反而通过硬件路由和固定处理流程,确保了 EL3 的安全边界。
更多推荐



所有评论(0)