【ARMv8 异常模型入门及渐进 8 - 安全中断介绍】

文章目录

    • 1.1 安全中断简介
      • 1.1.1 GIC 配置
      • 1.1.2 CPU的配置
    • 1.2 FIQ 中断触发
      • 1.2.1 Secure world and Normal world switch

1.1 安全中断简介

异常发生后系统将切换到具有更高执行权限的状态,在 AArch64 是通过 exception level 来实现的。AArch64 最多支持 EL0~EL3 四个 exception level,EL0 的 execution privilege 最低,EL3 的 execution privilege 最高。当发生异常的时候,系统的 exception 会迁移(route)到更高的 exception level 或者维持不变,但是绝不会降低。此外,不会有任何的异常会去到 EL0

AArch32,cpu 没有异常等级,而是采用 processor mode 模式,例如 User、FIQ、IRQ、Abort、Undefined、System,这些不同的 mode 对应 privilege(其他mode)和 no-privilege(User mode)。

GICv3 中,引入了支持 2 种安全状态(secure state),也就是对于中断,根据secure 状态,分为 安全中断非安全中断。当然也可以只支持一种安全状态。

这里的 2 种安全状态和 1 种安全状态,主要是影响:

  • 中断分组;
  • IRQFIQ 管脚的映射;
  • GIC中的寄存器访问。

1.1.1 GIC 配置

GICv3 对 security 进行了扩展,可以将 GIC 配置为工作在两种 secure 状态或 单一 secure 状态。它可以通过配置寄存器GICD_CTRL.DS 实现:

GICD_CTRL.DS的值 支持的seure状态 支持的group类型
secure和non secure两种状态 group0、secure group1、non secure group1
1 secure和non secure两种状态 group0、group1

从上表可以看到 GICv3 一共有三种中断 Group,对于 SPI类型的中断,可以通过寄存器 GICD_IGROUPRGICD_IGRPMOD 配置其中断 Group。每种 Group 中断都期望被下表特定的异常等级处理:

group 处理方式
group0 在EL3中处理
secure group1 在 secure EL1或secure EL2 中处理
non secure group 1 在 non secure EL1或non secure EL2 中处理

GICv3 可以触发两种中断信号 irq 和 fiq,对中断分组的目的就是使不同 Group 的中断在不同状态下可以被分别分发到 irq 或 fiq,在 aarch64 状态下,中断的分发方式如下:
【ARMv8 异常模型入门及渐进 8 - 安全中断介绍】_第1张图片
从上表可知:

  1. Group 0 中断总是以 FIQ 方式触发;
  2. Secure Group 1 中断根据 cpu 的当前执行状态确定触发方式:若当前执行状态为secure EL0 、EL1、EL2,以 irq 方式触发。否则,以fiq方式触发;
  3. Non Secure Group 1 中断,若当前执行状态为 non secure EL0、EL1、EL2,以 irq 方式触发。否则,以 fiq 方式触发 。

因此,GIC 对中断路由的支持可以总结为以下两点:

  • 在中断配置时,根据中断希望被处理的异常等级不同,将其配置为三种不同的 Group;
  • 在中断被触发时,GIC 根据中断 Group 配置和当前的系统执行状态,确定中断是以 fiq 还是 irq 的方式触发。

1.1.2 CPU的配置

使用 GICv3 后,中断的传递和 GICv2 有所改变,GICv3 中将 cpu interface 从 GIC 中抽离放入到 cpu 中,

  1. CPU Interface 通过 GIC Stream 接口与 GIC 进行通信;
  2. GIC要发送中断,GIC 通过GIC Stream接口给 CPU Interface 发送中断命令;

GIC 能做的只有中断是以哪种方式(fiq 或 irq)触发,若要达到不同 Group 中断能被不同异常等级处理的目的,还需要 cpu的配合才行。在 Armv8 中 SCR_EL3 寄存器是用于控制 Security 相关配置的,其各 bit 的定义如下图:
【ARMv8 异常模型入门及渐进 8 - 安全中断介绍】_第2张图片
其中 irq 和 fiq 用于配置中断触发时会被路由到 cpu 的哪个异常等级和 security 状态,它们的定义如下:
【ARMv8 异常模型入门及渐进 8 - 安全中断介绍】_第3张图片
(1)若将 FIQ 位配置为 0,且当前执行状态低于 EL3 时,则 FIQ 不会被路由到 EL3,而路由到第一个可以处理该中断的异常等级 FEL
(2)若将 FIQ 配置为 1,则运行于任何执行状态时,FIQ 都会被路由到 EL3

而 irq 的配置方式与 fiq 类似。综合上面分析,结合 gic 和 cpu 的配置,ARMv8 的中断将有以下几种路由方式:

Secure EL1 中断

  • 当前执行在 secure EL1,则触发方式为 irq,
    由于 secure EL1 中断需要在 secure EL1中处理,故只要将 scr.irq 设置为0即可将它路由到 FEL;
  • 当前执行在 non secure EL1,则触发方式为fiq,
    同样,由于它需要被 secure EL1处理,而 EL3 具有中断转发功能,因此可以将中断先路由到 EL3,然后由 EL3 转发给secure EL1。故可以将 scr.fiq 设置为1;
  • 当前执行在 EL3,则触发方式为 fiq,
    此时,FIQ 需要被设置为1,中断被路由到 EL3,然后转发给 secure EL1。

Non Secure EL1 中断

  • 当前执行在 secure EL1,则触发方式为 fiq,
    由于中断希望被 non secure EL1处理,因此中断可以先路由到 EL3,然后转发到 non secure EL1。因此 scr.fiq 设置为 1;
  • 当前执行在 non secure EL1,则触发方式为irq,   
    此时,中断被当前 EL 处理即可,故 scr.irq 需设置为 0;
  • 当前执行在 EL3,则触发方式为 fiq,  
    此时,FIQ 需要被设置为 1,中断被路由到 EL3,然后转发给 non secure EL1。

EL3 中断

  • 当前执行在 secure EL1,则触发方式为fiq     
    scr.fiq 设置为 1,以使中断路由到 EL3
  • 当前执行在 non secure EL1,则触发方式为 fiq,
    将 scr.fiq设置为 1,以使中断路由到 EL3
  • 当前执行在EL3,则触发方式为 fiq, 
    将 scr.fiq设置为 1,以使中断路由到EL3

根据上面的几种情况,即可知道异常等级切换时只要将 SCR.fiqSCR.irq 值按下表设置,及可正确地配置中断路由关系:

异常等级 scr.irq scr.fiq
secure EL1 0 1
non secure EL1 0 1
EL3 1 1

1.2 FIQ 中断触发

ARMv8 中除 EL0 以外,不同异常等拥有独立的异常向量表,它们的基地址被分别保存在 VBAR_EL1、VBAR_EL2 和VBAR_EL3 寄存器中。由于 EL1 和 EL2 的 Secure 状态和 Non Secure 状态使用相同的寄存器,因此在进行 secure 状态切换时,需要重新设置 VBAR_EL1 或 VBAR_EL2 寄存器的内容。这也是中断能在各异常等级之间路由的基础。

通常来说 FIQ 中断产生后会跳转到 VBAR_EL3+ 偏移地址 而手机厂商一般是将VBAR_EL3 的地址写到 ATF 中,所以 FIQ 产生的中断一般在 Linux kernel 中的中断向量处找不到对应的处理函数

一般来说 FIQ 产生后,不管是 ARMv-7 还是 ARMv-8 都会跳转到 ATF 中进行处理。

在 ARMv-8 中当在 Normal World 中产生一个安全中断后,首先会产生一个 FIQ 中断,在 FIQ 中断处理中段向量表中 只有一条 SMC 指令,所以先通过 SMC 指令切换到 Secure World,但是此时中断还是 Pending 状态,切换到 Secure World 之后,CPU Interface 在把中断报给 core

1.2.1 Secure world and Normal world switch

进入EL3 状态之后,拉低 NS 线,系统执行 ERET 指令 进入 Secure OS。系统从 Secure OS 出来的时候也是先执行 SMC 进入 EL3 然后将 NS 线拉高,然后再 执行 ERET 进入到 Kernel OS

推荐阅读:
https://zhuanlan.zhihu.com/p/520207211
https://zhuanlan.zhihu.com/p/520161285

你可能感兴趣的:(#,ARM,System,Exception,安全,arm,linux)