IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> TEE系列之ARM Trustzone 技术浅析(三)——— Exceptions & Interrupts Handling 的安全扩展 -> 正文阅读

[嵌入式]TEE系列之ARM Trustzone 技术浅析(三)——— Exceptions & Interrupts Handling 的安全扩展

1、异常和中断的概念

(AArch64 Exception and Interrupt Handling)
异常是指需要特权软件(an exception handler))采取某些操作,以确保系统的平稳运行。中断有时用作异常的同义词。但是对于ARM的术语来说,中断是异步异常,只是异常的一种;异常是一个事件(而不是分支或跳转指令)导致指令的正常顺序执行被修改。

一般来说,会打断 CPU 当前程序执行的事件,都可以称之为一个异常,异常的来源可以是 cpu 内部,也可以是其他外部硬件。例如 cpu 在程序执行过程中,数据和指令发生了错误,导致程序无法正常执行,这就是一种异常;外部硬件向 cpu 发送中断请求,cpu 挂起当前执行程序,优先处理中断请求,这是外部中断,同时也是一种异常。
异常的发生就会导致 processor modes 的切换,一个 data abort 的发生,cpu 就会进入 Abort mode,一个 undefined instruction 的发生,cpu 就会进入 Undefined mode,同样 IRQ,FIQ 的触发就会导致 cpu 进入 IRQ 和 FIQ mode。但一般由于操作系统的存在,cpu 进入 IRQ 和 FIQ mode 之后,会迅速进入 SVC mode,交由操作系统中相应的 interrupt handler 处理。
还有一种异常并不是 abort,也并不是真实的硬件中断,而是通过特定指令触发的软件中断,引起 cpu 执行流程的改变。这样的软件中断指令在 arm指令集中有三个:SVC,SMC 和 HVC。其中 SVC指令(supervisor call instruction)通常在用户进程切换到内核进程时使用,也就是我们常说的 syscall,会让 cpu 进入 SVC mode;HVC(Hypervisor call instruction)为 ARM 虚拟化技术的扩展指令,触发 cpu 进入 HYP mode,最后就是 Trustzone 的扩展指令 SMC(secure monitor call instruction),会触发 cpu 进入 MON mode。

综上所述,ARM异常其实可以分为两组,同步和异步的。
同步异常类型可以有很多原因,但是它们是以类似的方式处理。
异步异常类型被细分为三个中断:IRQ, FIQ和SError(系统错误)。

2、异常产生的方法:

  • 1、Abort

指令获取失败时生成中止(指令中止),失败的数据访问(数据中止),它们可以来自外部记忆系统在内存访问上给出错误响应(指示可能指定的地址与系统中的实际内存不对应)。或者,核心的内存管理单元(MMU)生成中止。在AArch64中,同步中止会导致同步异常。异步中止会导致SError中断异常。

  • 2、Reset

重置是一种特殊情况,因为它总是有自己的向量以最高的实现异常级别为目标。地址可以从重置向量基地址寄存器中读取RVBAR_ELn,其中n是实现的最高异常级别的数目。所有的核心都有一个重置输入,并在它们被重置后接受重置异常重置。它是最高优先级的异常,不能被掩盖。这个异常是用来在内核上执行代码来初始化它,在系统通电后向上

  • 3、同步异常

? The Supervisor Call (SVC) instruction enables User mode programs
to request an OS service.
? The Hypervisor Call (HVC) instruction enables the guest OS to
request hypervisor services.
? The Secure monitor Call (SMC) instruction enables the Normal
在这里插入图片描述

  • 4、异步异常(中断)

中断有三种类型,IRQ, FIQ和SError。IRQ和FIQ是与SError相比,一般用途是与外部异步数据中止。所以通常,术语“中断”仅指到IRQ和FIQ。

3、同步异常和异步异常的处理

  • 1、处理一个同步异常

Exception Syndrome Register (ESR_ELn)
Fault Address Register (FAR_ELn)
The Exception Link Register (ELR_ELn)

异常综合征寄存器(ESR_ELn)和错误地址寄存器(FAR_ELn)是提供用于向异常处理程序提供有关同步异常原因的信息。ESR_ELn提供异常原因的信息,而FAR_ELn保存所有同步指令和数据中止和对齐错误的错误虚拟地址。

对于实现了EL2 (Hypervisor)或EL3(安全内核)的系统,同步异常通常在当前或更高的异常级别中获取。异步异常可以(如果)),将被路由到更高的异常级别,由Hypervisor或安全程序处理
内核。SCR_EL3寄存器指定哪些异常被路由到EL3,类似地,HCR_EL2指定将哪些异常路由到EL2。有一些单独的位允许独立控制IRQ, FIQ和SError的路由。

  • 2、ESR_ELn - 异常综合征寄存器

包含允许异常的信息。处理程序来确定异常的原因。它只针对同步异常进行更新和SError。它不为IRQ或FIQ更新,因为这些中断处理程序通常获得状态来自通用中断控制器(GIC)寄存器的信息

  • (3)、Unallocated instructions

Unallocated instructions cause a Synchronous Abort in AArch64. 该异常产生的原因:
? An instruction opcode that is not allocated.
? An instruction that requires a higher level of privilege than the current Exception level. //比如你在EL1中操作了SCR_EL3寄存器
? An instruction that has been disabled.
? Any instruction when the PSTATE.IL field is set.

  • (4)、System calls
    在这里插入图片描述

4、异常处理

ARMv8-A体系结构有四个异常级别:EL0、EL1、EL2和EL3。处理器执行
只能通过获取异常或从异常返回来在异常级别之间移动。

需要注意的是:

When the processor moves from a higher to a lower Exception level, the Execution state can
stay the same, or it can switch from AArch64 to AArch32.
When moving from a lower to a higher Exception level, the Execution state can stay the same
or switch from AArch32 to AArch64
也就是说,如果高级别的level为aarch32,那么低级别的level一定得为aarch32
如果高级别的level为aarch64,那么低级别的level一可以为aarch32或aarch64

当一个异常发生时, the processor自动执行了如下动作:

The SPSR_ELn is updated (where n is the Exception level where the exception is taken), to
store the PSTATE information that is required to correctly return at the end of the exception.
PSTATE is updated to reflect the new processor status (and this can mean that the
Exception level is raised, or it can stay the same).
The address to return to at the end of the exception is stored in ELR_ELn.
The _ELn suffix on register names denotes that there are multiple copies of these registers
existing at different Exception levels. This means, for example, that SPSR_EL1 is a different
physical register to SPSR_EL2.

在这里插入图片描述
而我们在异常处理中,又会调用下一级的函数来干活,图形也就如下所示:
在这里插入图片描述
当异常处理完成后,processor由高级别返回低级别时,使用ERET指令返回。

5、异常向量表

每个异常级别都有自己的一套向量表,这些表的基地址分别写在VBAR_EL3, VBAR_EL2 and VBAR_EL1系统寄存器中。
向量表中的每个条目有16 instructions long(0x80字节)(在ARMv7-A和AArch32中,每个条目只有4个字节)。这意味着在AArch64中顶层处理程序可以直接在向量中,而不是跳转到其它地址处执行。

VBAR_ELn执行的每个table中,定义了16个entries,具体走哪一个entry是由下面几个因素决定的:
? The type of exception (SError, FIQ, IRQ, or Synchronous)
? If the exception is being taken at the same Exception level, the stack pointer to be used (SP0 or SPn).
? If the exception is being taken at a lower Exception level, the Execution state of the next lower level (AArch64 or AArch32).

一张经典的向量表,如下所示:
在这里插入图片描述
举一个超级简单的例子:
kernel code执行在EL1,这时来了一个IRQ,该中断没有配置到hypervisor和secure environment中,所以它的处理仅仅是在kernel中完成,程序跳转到VBAR_EL1+0x280,栈使用sp_el1(将SPSel设置程sp_el1)。

6、异常返回

软件必须告诉处理器何时从异常中返回。这是通过代码完成的使用ERET指令。这将从SPSR_ELn中恢复异常前的PSTATE并返回通过从ELR_ELn恢复PC,将程序执行返回到原始位置。
在A64指令集中,使用寄存器X30(与RET指令一起)返回子例程

ELR_ELn寄存器用于存储来自异常的返回地址。它的价值寄存器是自动写入的入口异常,并被写入到PC作为其中之一执行用于从异常中返回的ERET指令的效果。

除了SPSR和ELR寄存器之外,每个异常级别都有自己专用的堆栈指针登记。它们是SP_EL0、SP_EL1、SP_EL2和SP_EL3。这些寄存器用来指向专用的栈。堆栈可以,例如,用来存储寄存器被损坏异常处理程序,使它们可以在返回之前恢复到原来的值原始代码

处理程序代码可以从使用SP_ELn切换到使用SP_EL0。例如,SP_EL1可能指向存储小堆栈的内存块,内核可以始终保证该小堆栈是有效的。SP_EL0可能指向较大的内核任务堆栈. 但不能保证不发生溢出。这切换通过写入SPSel寄存器来控制。

7、PSTATE

在这里插入图片描述
当前processor的状态保存在PSTATE,当异常到来时,PSTATE的值会自动保存在SPSR中。 aarch64中由三个SPSR : SPSR_EL3, SPSR_EL2, and SPSR_EL1
例如,如果发生了一个异常target到EL1,那么当前处理器的状态会自动保存到SPSR_EL1中。

在这里插入图片描述

8、中断的处理流程

在这里插入图片描述在这里插入图片描述

10、安全扩展

了解 processor modes 和异常的关系之后,就明白为什么操作系统在初始化时首先需要做的事情是配置 cpu 的异常向量表:Vector Table。配置异常向量表就是告诉 cpu 不同异常发生之后,入口函数在哪里。以 Linux kernel 的 vector table 为例:

.L__vectors_start:
    W(b)    vector_rst    /* reset mode */
    W(b)    vector_und    /* undefined mode */
    W(ldr)  pc, .L__vectors_start + 0x1000    /* svc mode */
    W(b)    vector_pabt    /* abort mode (prefetch abort) */
    W(b)    vector_dabt    /* abort mode (data abort) */
    W(b)    vector_addrexcptn  /* unused */
    W(b)    vector_irq    /* irq mode */
    W(b)    vector_fiq    /* fiq mode */

配置 Vector table 除了需要指定各个 exceptions handler 的入口函数之外,最重要的就是指定 vector table 的地址,这样 cpu 才计算出各个入口函数的地址。

那么异常处理和 Trustzone 又有什么关系呢。前文说过,引入 Trustzone 之后,cpu 在不同的 processor modes 时都要 secure 和 non-secure 两种状态,如下图所示:

在这里插入图片描述secure 和 non-secure state 的切换必须经过 monitor mode,而 cpu mode 的切换必须又异常触发,那么触发进入 monitor mode 的异常处理函数应该在哪里配置呢?处于安全考虑,显然不能和 kernel OS 共用一套 vector table,因此一个新的寄存器: MVBAR (Monitor Vector Base Address Register)由此引入。先看一段monitor vector table 配置的 sample code(ARM V7):

monitor_vector_table:
    nop             /* RESET    */
    b   .           /* UNDEF    */
    b   .Lsmcall_func       /* SMC      */
    b   .           /* IABORT   */
    b   .           /* DABORT   */
    nop             /* reserved */
    b   .           /* IRQ      */
    b   .           /* FIQ      */

arm-trusted-firmware-master\bl31\aarch64\runtime_exceptions.S (ARM V8)

vector_base runtime_exceptions

	/* ---------------------------------------------------------------------
	 * Current EL with SP_EL0 : 0x0 - 0x200
	 * ---------------------------------------------------------------------
	 */
vector_entry sync_exception_sp_el0
	/* We don't expect any synchronous exceptions from EL3 */
	no_ret	report_unhandled_exception
	check_vector_size sync_exception_sp_el0

vector_entry irq_sp_el0
	/*
	 * EL3 code is non-reentrant. Any asynchronous exception is a serious
	 * error. Loop infinitely.
	 */
	no_ret	report_unhandled_interrupt
	check_vector_size irq_sp_el0


vector_entry fiq_sp_el0
	no_ret	report_unhandled_interrupt
	check_vector_size fiq_sp_el0


vector_entry serror_sp_el0
	no_ret	report_unhandled_exception
	check_vector_size serror_sp_el0

	/* ---------------------------------------------------------------------
	 * Current EL with SP_ELx: 0x200 - 0x400
	 * ---------------------------------------------------------------------
	 */
vector_entry sync_exception_sp_elx
	/*
	 * This exception will trigger if anything went wrong during a previous
	 * exception entry or exit or while handling an earlier unexpected
	 * synchronous exception. There is a high probability that SP_EL3 is
	 * corrupted.
	 */
	no_ret	report_unhandled_exception
	check_vector_size sync_exception_sp_elx

vector_entry irq_sp_elx
	no_ret	report_unhandled_interrupt
	check_vector_size irq_sp_elx

vector_entry fiq_sp_elx
	no_ret	report_unhandled_interrupt
	check_vector_size fiq_sp_elx

vector_entry serror_sp_elx
	no_ret	report_unhandled_exception
	check_vector_size serror_sp_elx

	/* ---------------------------------------------------------------------
	 * Lower EL using AArch64 : 0x400 - 0x600
	 * ---------------------------------------------------------------------
	 */
vector_entry sync_exception_aarch64
	/*
	 * This exception vector will be the entry point for SMCs and traps
	 * that are unhandled at lower ELs most commonly. SP_EL3 should point
	 * to a valid cpu context where the general purpose and system register
	 * state can be saved.
	 */
	handle_sync_exception
	check_vector_size sync_exception_aarch64

vector_entry irq_aarch64
	handle_interrupt_exception irq_aarch64
	check_vector_size irq_aarch64

vector_entry fiq_aarch64
	handle_interrupt_exception fiq_aarch64
	check_vector_size fiq_aarch64

vector_entry serror_aarch64
	/*
	 * SError exceptions from lower ELs are not currently supported.
	 * Report their occurrence.
	 */
	no_ret	report_unhandled_exception
	check_vector_size serror_aarch64

	/* ---------------------------------------------------------------------
	 * Lower EL using AArch32 : 0x600 - 0x800
	 * ---------------------------------------------------------------------
	 */
vector_entry sync_exception_aarch32
	/*
	 * This exception vector will be the entry point for SMCs and traps
	 * that are unhandled at lower ELs most commonly. SP_EL3 should point
	 * to a valid cpu context where the general purpose and system register
	 * state can be saved.
	 */
	handle_sync_exception
	check_vector_size sync_exception_aarch32

vector_entry irq_aarch32
	handle_interrupt_exception irq_aarch32
	check_vector_size irq_aarch32

vector_entry fiq_aarch32
	handle_interrupt_exception fiq_aarch32
	check_vector_size fiq_aarch32

vector_entry serror_aarch32
	/*
	 * SError exceptions from lower ELs are not currently supported.
	 * Report their occurrence.
	 */
	no_ret	report_unhandled_exception
	check_vector_size serror_aarch32

也就是一旦系统中发生 smc 指令,cpu 会立即挂起当前程序,直接跳到 smcall_func 处理 smc 引发的异常。而 smcall_func 的入口地址究竟在哪里则由 MVBAR 计算得出,跳转到上述的地址执行。
在前一个 topic: Processor modes & registers 中提过,除了 smc 软件中断指令可以触发 cpu 进入 monitor mode,外部中断 IRQ,FIQ 也可以配置成触发 cpu 进入 monitor mode,由寄存器 SCR(secure configuration register)的 IRQ bit 和 FIQ bit 决定,再回顾一下SCR 的寄存器表格:
在这里插入图片描述
这样 fiq 为 secure interrupt,而 irq 仍然是 normal interrupt。那么问题来了,当 cpu 在 secure state 时,收到 irq 中断会如何处理呢?irq interrupt routing 示意图如下:

在这里插入图片描述
也就是说一旦在 secure state 发生 irq 中断,cpu 应该先 route 到 monitor mode,切换到 non-secure state 之后,再进到 normal OS 的 irq 处理函数中处理 irq。每一次的切换都需要小心的保存和恢复现场,才能保证 cpu 的正常运行。而为了防止中断嵌套,一般 cpu 在进入 monitor mode 之后都会屏蔽所有中断。

最后说一句,整个系统会有 normal OS,secure OS,monitor 三个 exception vector table,通过寄存器和代码控制,系统中异常和中断的处理组合可以多种多样,官方推荐只是其中一种做法而已。只是不论采用官方推荐做法,还是自己发明创造的异常中断处理方式,如何保护和恢复上下文,以及保证secure world 上下文的安全性都是需要考虑的重中之重!

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-08-09 10:23:46  更:2021-08-09 10:25:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 1:53:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计