5-Interrupt Management Framework

本文详细介绍了ARM安全扩展中用于管理路由到EL3的中断的框架。该框架确保了安全和非安全中断按需路由,并提供了对不同安全状态中断处理的支持。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引流关键词: 中断、同步异常、异步异常、irq、fiq、BL1,BL2,BL3,BL31,BL32,BL33,AP_BL1,AP_BL2,AP_BL3,AP_BL31,AP_BL32,AP_BL33,SCP_BL1,SCP_BL2,BL0,BL30, optee、ATF、TF-A、Trustzone、optee3.14、MMU、VMSA、cache、TLB、arm、armv8、armv9、TEE、安全、内存管理、页表…

快速链接:
.
👉👉👉 个人博客笔记导读目录(全部) 👈👈👈


[专栏目录]-ATF/FF-A/specification学习

请添加图片描述

5.中断管理框架

该框架负责管理路由到 EL3 的中断。它还允许 EL3 软件配置中断路由行为。其主要目标是实现以下两个要求。

(1) 当执行处于非安全状态(正常世界)时,应该可以将打算由安全软件(安全中断)处理的中断路由到 EL3。然后,框架应负责将中断控制权交给 EL3 或 Secure-EL1 中的软件,具体取决于软件配置和 GIC 实现。此要求确保安全中断在安全软件的交付和处理方面处于安全软件的控制之下,而不会受到非安全软件的干预。

(2) 当执行在低于 EL3 的安全世界中执行时,应该可以将打算由非安全软件(非安全中断)处理的中断路由到正常世界中最后执行的异常级别。这可以在有或没有在 Secure-EL1/Secure-EL0 中执行的软件知识的情况下完成。方法的选择应由安全软件控制。此要求确保非安全软件能够与安全软件一起执行而不会覆盖它。

5.1。概念

5.1.1。中断类型

根据处理中断的异常级别,框架将中断分类为以下之一。

(1) 安全 EL1 中断。根据当前执行上下文的安全状态,这种类型的中断可以路由到 EL3 或 Secure-EL1。它总是在 Secure-EL1 中处理。

(2) 非安全中断。根据当前执行上下文的安全状态,这种类型的中断可以路由到 EL3、Secure-EL1、Non-secure EL1 或 EL2。它总是在非安全 EL1 或 EL2 中处理。

(3) EL3 中断。根据当前执行上下文的安全状态,这种类型的中断可以路由到 EL3 或 Secure-EL1。它总是在 EL3 中处理。

以下常量定义了框架实现中的各种中断类型。

#define INTR_TYPE_S_EL1      0
#define INTR_TYPE_EL3        1
#define INTR_TYPE_NS         2
5.1.2. 路由模型

一种类型的中断可以生成为 FIQ 或 IRQ。中断类型的目标异常级别通过 EL3 的安全配置寄存器中的 FIQ 和 IRQ 位(SCR_EL3.FIQ和SCR_EL3.IRQ 位)进行配置。当SCR_EL3.FIQ=1 时,FIQ 被路由到 EL3。否则,它们将被路由到能够处理中断的第一异常级别 (FEL)。当 SCR_EL3.IRQ=1 时,IRQ 被路由到 EL3。否则,它们将被路由到 FEL。在进入该安全状态下的较低异常级别之前,该寄存器由 EL3 软件为每个安全状态独立配置。

一种中断类型(生成为 FIQ 或 IRQ)的路由模型被定义为每个安全状态的目标异常级别。它由每个安全状态的单个位表示。值0表示应将中断路由到 FEL。值1表示中断应该被路由到 EL3。路由模型仅适用于不在 EL3 中执行的情况。

中断类型的默认路由模型是将其路由到处于任一安全状态的 FEL。

5.1.3. 有效的路由模型

该框架认为每种中断类型的某些路由模型是不正确的,因为它们与第 1 节中提到的要求相冲突。以下小节描述了所有可能的路由模型并指定哪些是有效的或无效的。EL3 中断当前仅支持 GIC 版本 3.0 (Arm GICv3),仅支持 Secure-EL1 和非安全中断类型用于 GIC 版本 2.0 (Arm GICv2)(请参阅中断管理框架中的假设)。以下小节中使用的术语解释如下。

(1) CSS : Current Security State。当前安全状态。0何时安全,1何时不安全

(2) TEL3 : Target Exception Level 3。目标异常级别 3。0针对 FEL 时。1当针对 EL3 时。

5.1.3.1。安全 EL1 中断
  • (1) CSS=0,电话 3=0。当执行处于安全状态时,中断被路由到 FEL。这是一个有效的路由模型,因为安全软件控制着处理安全中断。

  • (2) CSS=0,电话 3=1。当执行处于安全状态时,中断被路由到 EL3。这是一个有效的路由模型,因为 EL3 中的安全软件可以将中断移交给 Secure-EL1 进行处理。

  • (3) CSS=1,电话 3=0。当执行处于非安全状态时,中断被路由到 FEL。这是一个无效的路由模型,因为安全中断对安全软件不可见,这违反了 Arm 安全扩展背后的动机。

  • (4) CSS=1,电话 3=1。当执行处于非安全状态时,中断被路由到 EL3。这是一个有效的路由模型,因为 EL3 中的安全软件可以将中断移交给 Secure-EL1 进行处理。

5.1.3.2。非安全中断
  • (1) CSS=0,电话 3=0。当执行处于安全状态时,中断被路由到 FEL。这允许安全软件捕获非安全中断,执行其簿记并通过 EL3 将中断交给非安全软件。这是一个有效的路由模型,因为安全软件控制其执行如何被非安全中断抢占。

  • (2) CSS=0,电话 3=1。当执行处于安全状态时,中断被路由到 EL3。这是一个有效的路由模型,因为 EL3 中的安全软件可以在将中断交给非安全软件之前保存 Secure-EL1/Secure-EL0 中的软件状态。该模型需要 Secure-EL1 和 EL3 软件之间的额外协调,以确保前者的状态被后者正确保存。

  • (3) CSS=1,电话 3=0。当执行处于非安全状态时,中断被路由到 FEL。这是一个有效的路由模型,因为非安全中断由非安全软件处理。

  • (4) CSS=1,电话 3=1。当执行处于非安全状态时,中断被路由到 EL3。这是一个无效的路由模型,因为没有正当理由将中断路由到 EL3 软件,然后将其返回给非安全软件进行处理。

5.1.3.3。EL3 中断
  • (1) CSS=0,电话 3=0。在 Secure-EL1/Secure-EL0 中执行时,中断被路由到 FEL。这是一个有效的路由模型,因为 Secure-EL1/Secure-EL0 中的安全软件控制其执行如何被 EL3 中断抢占,并且可以将中断移交给 EL3 进行处理。
    但是,当EL3_EXCEPTION_HANDLING是时1,此路由模型无效,因为 EL3 中断无条件路由到 EL3,并且 EL3 中断将始终抢占 Secure EL1/EL0 执行。请参阅异常处理文档。

  • (2) CSS=0,电话 3=1。在 Secure-EL1/Secure-EL0 中执行时,中断被路由到 EL3。这是一个有效的路由模型,因为 EL3 中的安全软件可以处理中断。

  • (3) - (1) CSS=1,电话 3=0。当执行处于非安全状态时,中断被路由到 FEL。这是一个无效的路由模型,因为安全中断对安全软件不可见,这违反了 Arm 安全扩展背后的动机。

  • (4) CSS=1,电话 3=1。当执行处于非安全状态时,中断被路由到 EL3。这是一个有效的路由模型,因为 EL3 中的安全软件可以处理中断。

5.1.4。中断类型到信号的映射

该框架旨在与平台实现的任何中断控制器一起使用。中断控制器可以根据当前的安全状态向 CPU 生成一种类型的中断作为 FIQ 或 IRQ 信号。类型和信号之间的映射只有平台知道。SCR_EL3框架使用此信息来确定在为某种中断应用路由模型时是否应该编程 IRQ 或 FIQ 位。平台通过 API 提供此信息 plat_interrupt_type_to_line()(在 移植指南中描述)。例如,在 FVP 端口上,当平台使用 Arm GICv2 中断控制器时,Secure-EL1 中断通过 FIQ 信号发出,而非安全中断通过 IRQ 信号发出。这适用于执行处于任一安全状态时。

5.1.4.1。几种中断类型映射到一个信号的效果

需要注意的是,如果多个中断类型映射到单个中断信号,并且如果任何一种中断类型为特定安全状态设置TEL3=1 ,则在该安全状态下,中断信号将被路由到 EL3。这意味着使用相同中断信号的所有其他中断类型将被强制使用相同的路由模型。在为中断类型选择路由模型时应牢记这一点。

例如,在 Arm GICv3 中,当执行上下文为 Secure-EL1/Secure-EL0 时,EL3 和非安全中断类型都映射到 FIQ 信号。因此,如果任一中断类型设置路由模型使得TEL3=1当CSS=0时,FIQ 位SCR_EL3将被编程为在 Secure-EL1/Secure-EL0 中执行时将 FIQ 信号路由到 EL3,从而有效地路由其他中断类型也到EL3。

5.2. 中断管理框架中的假设

该框架做出以下假设以简化其实现。

  • (1) 尽管该框架支持 2 种类型的安全中断(EL3 和 Secure-EL1 中断),但只有 Arm GICv3 之类的中断控制器架构才能以 Group 0 中断的形式支持 EL3 中断。在 Arm GICv2 中,假定所有安全中断都在 Secure-EL1 中处理。它们可以通过 EL3 传送到 Secure-EL1,但不能在 EL3 中处理。

  • (2) 在 EL3 执行期间,中断异常(PSTATE.I和位)被屏蔽。F

  • (3) 中断管理:以下部分描述了中断处理框架如何管理中断。这需要:
    提供一个接口以允许注册处理程序和为一种中断类型指定路由模型。
    在生成中断时实现对中断类型的手动控制到其注册处理程序的支持。

中断管理的两个方面都涉及从 EL3 到 Secure-EL1 的安全软件堆栈中的各种组件。这些组件在软件组件一节中进行了描述。该框架将与每种类型的中断相关的信息存储在以下数据结构中。

typedef struct intr_type_desc {
        interrupt_type_handler_t handler;
        uint32_t flags;
        uint32_t scr_el3[2];
} intr_type_desc_t;

该flags字段将中断类型的路由模型存储在位[1:0] 中。Bit[0] 存储执行处于安全状态时的路由模型。当执行处于非安全状态时,Bit[1] 存储路由模型。如第Routing model部分所述,值0表示中断应针对 FEL。值1意味着它应该针对 EL3。其余位为保留位和 SBZ。set_interrupt_rm_flag()应使用 辅助宏来设置flags参数中的位。

该scr_el3[2]字段还存储路由模型,但作为该字段中的模型到每个安全状态flags中相应位的映射。SCR_EL3

该框架还依赖于平台端口来配置中断控制器以区分安全中断和非安全中断。该平台应了解系统中存在的安全设备及其相关的中断号。它应该配置中断控制器以启用安全中断,确保它们的优先级始终高于非安全中断,并将它们定位到主 CPU。它还应该导出移植指南中描述的接口以启用中断处理。

在本文档的其余部分,为简单起见,考虑了 Arm GICv2 系统,并假设 FIQ 信号用于生成 Secure-EL1 中断,而 IRQ 信号用于在任一安全状态下生成非安全中断. 不考虑 EL3 中断。

5.3. 软件组件

中断管理的角色和职责细分为在 EL3 和 Secure-EL1 中运行的软件的以下组件。下面简要介绍每个组件。

  • (1) EL3 运行时固件。该组件对 TF-A 的所有端口都是通用的。

  • (2) 安全有效载荷调度 (SPD) 服务。该服务与在 Secure-EL1/Secure-EL0 中运行并负责在安全和非安全状态之间切换执行的安全有效负载 (SP) 软件接口。开关由安全监视器调用触发,它使用上下文管理库导出的 API 来实现此功能。在两种安全状态之间切换执行也是中断管理的要求。这导致对 SPD 服务的严重依赖。TF-A 实现了一个示例测试安全有效负载调度程序 (TSPD) 服务。
    SPD 服务插入到 EL3 运行时固件中,并且可能对 TF-A 的某些端口通用。

  • (3) 安全有效载荷 (SP)。在生产系统上,安全有效负载对应于运行在 Secure-EL1/Secure-EL0 中的安全操作系统。它与 SPD 服务接口以管理与非安全软件的通信。TF-A 实现了一个名为 Test Secure Payload (TSP) 的示例安全有效负载,它仅在 Secure-EL1 中运行。
    安全有效负载实现对于 TF-A 的某些端口可能是通用的,就像 SPD 服务一样。

5.4. 中断注册

本节详细描述了在 为中断类型注册处理程序期间每个软件组件(请参阅软件组件)的作用。

5.4.1。EL3 运行时固件

该组件为中断类型的处理程序声明了以下原型。

typedef uint64_t (*interrupt_type_handler_t)(uint32_t id,
                                             uint32_t flags,
                                             void *handle,
                                             void *cookie);

is 参数是保留的id,只有在存在确定 id 的万无一失的方法时,才能在将来用于传递最高挂起中断的中断 id。目前它包含INTR_ID_UNAVAILABLE.

该flags参数包含如下杂项信息。

  • (1) 安全状态,位 [0]。该位指示产生中断时较低异常级别的安全状态。值1表示它处于非安全状态。值0表示它处于安全状态。处理程序可以使用该位来确保根据注册期间指定的路由模型生成和路由中断。

  • (2) 保留,位 [31:1]。其余位保留供将来使用。

该handle参数指向参数中cpu_context指定的安全状态的当前 CPU 的结构flags。

一旦处理程序例程完成,执行将返回到安全或非安全状态。处理程序例程必须为目标安全状态返回一个指向 cpu_context当前 CPU 结构的指针。在 AArch64 上,调用者当前忽略此返回值,因为cpu_context预期将由处理程序通过上下文管理库 API 设置要使用的适当值。可移植的中断处理程序实现必须在返回指针指向的结构中以及通过上下文管理库 API 设置目标上下文。处理程序应将所有错误条件视为严重错误,并在其实现中采取适当的措施,例如使用断言失败。

运行时固件提供以下 API,用于为特定类型的中断注册处理程序。Secure Payload Dispatcher 服务应使用此 API 为 Secure-EL1 注册一个处理程序,并可选择为非安全中断注册一个处理程序。此 API 还要求调用者指定中断类型的路由模型。

int32_t register_interrupt_type_handler(uint32_t type,
                                        interrupt_type_handler handler,
                                        uint64_t flags);

该type参数可以是上面列出的三种中断类型之一, INTR_TYPE_S_EL1即INTR_TYPE_NS& INTR_TYPE_EL3。该flags参数如第 2 节所述。

该函数将0在成功注册后返回。-EALREADY如果已注册中断类型的处理程序,它将返回 。如果type无法识别或flags或handler无效,它将返回-EINVAL。

中断路由由在SCR_EL3.FIQ/IRQ任一安全状态下进入较低异常级别之前的位配置控制。上下文管理库为每个 CPU 结构中的每个安全状态维护SCR_EL3系统寄存器的副本。cpu_context它导出以下 API 以让 EL3 运行时固件编程并检索当前 CPU 的每个安全状态的路由模型。函数使用SCR_EL3存储在 中的值在从 EL3 异常级别返回之前对寄存器进行编程 。cpu_contextel3_exit()SCR_EL3

uint32_t cm_get_scr_el3(uint32_t security_state);
void cm_write_scr_el3_bit(uint32_t security_state,
                          uint32_t bit_pos,
                          uint32_t value);

cm_get_scr_el3()返回SCR_EL3当前 CPU 的指定安全状态的寄存器值。cm_write_scr_el3_bit()将0或写入1 指定的位bit_pos。register_interrupt_type_handler()调用 API,该 API根据使用和API 的路由模型进行set_routing_model()编程。SCR_EL3cm_get_scr_el3()cm_write_scr_el3_bit()

值得注意的是,在当前框架的实现中,EL3 运行时固件负责对路由模型进行编程。SPD 负责确保在收到中断时遵循路由模型。

5.4.2. 安全有效负载调度程序

SPD 服务负责确定和维护自身支持的中断路由模型和 Secure Payload。它还负责根据路由模型在安全和非安全软件之间传送中断。它可以在构建时或运行时确定路由模型。它必须使用此信息使用register_interrupt_type_handler()EL3 运行时固件中的 API 为每种中断类型注册处理程序。

如果 SPD 服务在构建时不知道路由模型,则它必须由 SP 作为其初始化的结果提供。只有在 SP 初始化完成后,SPD 才应该对路由模型进行编程,例如在变量指向的 SPD 初始化函数中bl32_init。

SPD 应确定在接收到来自 EL3 运行时固件的中断后将控制权传递给安全有效负载的机制。此信息可以在构建时提供给 SPD 服务,也可以由 SP 在运行时提供。

5.4.3. 测试安全有效负载调度程序行为

注意: 在本文档讨论TSP_NS_INTR_ASYNC_PREEMPT的情况下 1,相同的结果也适用于当EL3_EXCEPTION_HANDLING是1。

TSPD 仅处理 Secure-EL1 中断,并在构建时提供以下路由模型。

  • Secure-EL1 中断在执行处于非安全状态时路由到 EL3,并且在执行处于安全状态时路由到 FEL,即CSS=0、TEL3=0和CSS=1、TEL3=1用于 Secure-EL1 中断

  • 当构建标志TSP_NS_INTR_ASYNC_PREEMPT为零时,默认路由模型用于非安全中断。它们以任一安全状态(即CSS=0、TEL3=0和CSS=1、TEL3=0用于非安全中断)被路由到 FEL。

  • 当构建标志TSP_NS_INTR_ASYNC_PREEMPT定义为 1 时,当执行处于安全状态时,非安全中断被路由到 EL3,即CSS=0,对于非安全中断,TEL3=1。这有效地抢占了 Secure-EL1。默认路由模型用于非安全状态下的非安全中断。即CSS=1, TEL3=0。

它在函数中执行以下操作tspd_init()来满足前面提到的要求:

(1) 它将控制权传递给测试安全有效负载以执行其初始化。TSP 在 SP 中提供向量表的地址, tsp_vectors其中还包括sel1_intr_entry字段中 Secure-EL1 中断的处理程序。当 TSPD 接收到 Secure-EL1 中断时,它会将控制权传递给位于该地址的 TSP。

TSP 和 TSPD 之间的切换协议要求 TSPDPSTATE.DAIF在调用时屏蔽所有中断(位) tsp_sel1_intr_entry()。TSP 必须保留被调用方保存的通用、SP_EL1/Secure-EL0、LR、VFP 和系统寄存器。它可以 x0-x18用来启用其 C 运行时。

(2) TSPD 实现了 Secure-EL1 中断的处理函数。该函数使用 API 注册到 EL3 运行时固件 register_interrupt_type_handler(),如下所示

/* Forward declaration */
interrupt_type_handler tspd_secure_el1_interrupt_handler;
int32_t rc, flags = 0;
set_interrupt_rm_flag(flags, NON_SECURE);
rc = register_interrupt_type_handler(INTR_TYPE_S_EL1,
                                 tspd_secure_el1_interrupt_handler,
                                 flags);
if (rc)
    panic();

(3) 当构建标志TSP_NS_INTR_ASYNC_PREEMPT定义为 1 时,TSPD 为非安全中断实现处理函数。该函数使用 API 注册到 EL3 运行时固件 register_interrupt_type_handler(),如下所示

/* Forward declaration */
interrupt_type_handler tspd_ns_interrupt_handler;
int32_t rc, flags = 0;
set_interrupt_rm_flag(flags, SECURE);
rc = register_interrupt_type_handler(INTR_TYPE_NS,
                                tspd_ns_interrupt_handler,
                                flags);
if (rc)
    panic();
5.4.4。安全有效载荷

安全有效负载必须在 Secure-EL1 (Secure-EL1 IHF) 上实现中断处理框架,以支持其选择的中断路由模型。安全有效负载执行将在以下情况之间交替。

  • (1) 在启用了 IRQ、FIQ 或两者的中断的代码中,如果一个中断类型针对 FEL,那么它将被路由到 Secure-EL1 异常向量表。这被定义为处理中断的异步模式。此模式适用于 Secure-EL1 和非安全中断。

  • (2) 在两个中断都被禁用的代码中,如果一个中断类型以 FEL 为目标,那么执行最终将迁移到非安全状态。任何非安全中断都将按照CSS=1 和 TEL3=0的路由模型中的描述进行处理。Secure-EL1 中断将被路由到 EL3(根据CSS=1 和 TEL3=1的路由模型),SPD 服务会将它们交给 SP。这被定义为处理中断的同步模式。

SP 实现的中断处理框架应支持这些中断处理模型中的一种或两种,具体取决于所选的路由模型。

以下列表简要描述了有效路由模型的选择(请参阅有效路由模型)如何影响 Secure-EL1 IHF 的实现。如果在编译时 SPD 服务不知道中断路由模型的选择,那么 SP 应该在运行时在其初始化阶段将此信息传递给 SPD 服务。

如前所述,考虑了一个 Arm GICv2 系统,并假设 FIQ 信号用于生成 Secure-EL1 中断,而 IRQ 信号用于在任一安全状态下生成非安全中断。

5.4.4.1。安全有效载荷 IHF 设计 wrt 安全 EL1 中断
  • (1) CSS=0,电话 3=0。如果PSTATE.F=0,Secure-EL1 中断将在 Secure-EL1 FIQ 异常向量之一处触发。Secure-EL1 IHF 应该支持异步处理 FIQ 中断。
    如果PSTATE.F=1那么 Secure-EL1 中断将按照同步中断处理模型进行处理。SP 可以通过在注册阶段将 Secure-EL1 中断的单独入口点导出到 SPD 服务来实现此场景。SPD 服务还需要知道系统的状态、通用目的以及PSTATE它应该安排将执行返回给 SP 的寄存器。如果 SPD 服务在构建时不知道该信息,则 SP 应在注册阶段以实现定义的方式提供此信息。

  • (2) CSS=1,电话 3=1。当执行处于非安全状态时,中断被路由到 EL3。它们应该通过上面 1. 中描述的同步中断处理模型来处理。

  • (3) CSS=0,电话 3=1。当执行处于安全状态时,Secure-EL1 中断被路由到 EL3。SP 将看不到它们。Secure-EL1/Secure-EL0 中的PSTATE.F位不会屏蔽 FIQ。EL3 运行时固件将调用 SPD 服务为 Secure-EL1 中断注册的处理程序。然后,Secure-EL1 IHF 应该通过上面 1. 中描述的同步中断处理模型来处理所有 Secure-EL1 中断。

5.4.4.2。安全有效载荷 IHF 设计 wrt 非安全中断
  • (1) CSS=0,电话 3=0。如果PSTATE.I=0,将在 Secure-EL1 IRQ 异常向量之一处触发非安全中断。Secure-EL1 IHF 应与 SPD 服务协调以将执行转移到应处理中断的非安全状态,例如,SP 可以分配一个功能标识符以向 SPD 服务发出 SMC64 或 SMC32,这表明SP 执行已被非安全中断抢占。如果 SPD 服务在编译时不知道这个函数标识符,那么 SP 可以在注册阶段提供它。
    如果PSTATE.I=1然后非安全中断将挂起,直到在非安全状态下恢复执行。

  • (2) CSS=0,电话 3=1。非安全中断被路由到 EL3。SP 将看不到它们。Secure-EL1/Secure-EL0 中的PSTATE.I位无效。SPD 服务应注册一个非安全中断处理程序,该处理程序应正确保存 SP 状态并在将处理中断的非安全状态下恢复执行。Secure-EL1 IHF 不需要采取任何行动。

  • (3) CSS=1,电话 3=0。非安全中断在非安全状态 (EL1/EL2) 的 FEL 中处理,并且对 SP 不可见。此路由模型不影响 SP 行为。

Secure Payload 还必须确保所有 Secure-EL1 中断都通过 EL3 运行时固件的平台端口在中断控制器上正确配置。它应该配置 EL3 运行时固件通过其平台端口不知道的任何其他 Secure-EL1 中断。

5.4.5。测试安全有效负载行为

TSP 选择的 Secure-EL1 和非安全中断的路由模型在部分Secure Payload Dispatcher中进行了描述。它在构建时为 TSPD 服务所知。

tsp_sel1_intr_entry()TSP实现了一个入口点(它将对该入口点的引用传递 tsp_vectors给 TSPD 服务。

TSP 还将通过变量引用的默认异常向量表替换为 early_exceptions能够处理在相同 (Secure-EL1) 异常级别采取的 FIQ 和 IRQ 异常的向量表。该表通过tsp_exceptions变量引用并编程到 VBAR_EL1。它迎合异步处理模型。

TSP 还对 Arm Generic Timer 块中的安全物理定时器进行编程,以引发周期性中断(每半秒一次),以测试软件组件中列出的所有软件组件的中断管理。

5.5. 中断处理

本节详细描述了每个软件组件(请参阅软件组件一节)在处理特定类型的中断中的作用。

5.5.1。EL3 运行时固件

EL3 运行时固件填充变量引用的 IRQ 和 FIQ 异常向量runtime_exceptions,如下所示。

  • (1) 从当前异常级别获取的 IRQ 和 FIQ 异常具有 SP_EL0或被SP_EL3报告为不可恢复的错误条件。如前所述,EL3 运行时固件总是在 设置PSTATE.I和PSTATE.F位的情况下执行。

  • (2) 以下文本描述了如何处理使用 AArch64 或 AArch32 从较低异常级别获取的 IRQ 和 FIQ 异常。

产生中断时,每种中断类型的向量负责:

  • (1) 进入异常后立即保存整个通用寄存器上下文 (x0-x30)。寄存器保存在寄存器cpu_context 引用的 per-cpu 数据结构中SP_EL3。

  • (2) ELR_EL3将,SP_EL0和system 寄存器保存在寄存器引用SPSR_EL3的 per-cpu数据结构中。cpu_contextSP_EL3

  • (3) CTX_RUNTIME_SP通过从 per-cpucpu_context数据结构中恢复值SP_EL0并执行指令来切换到 C 运行时堆栈。msr spsel, #0

  • (4) 确定中断的类型。Secure-EL1 中断将在 FIQ 向量处发出信号。非安全中断将在 IRQ 向量处发出信号。平台应实现以下 API 来确定挂起中断的类型。

uint32_t plat_ic_get_interrupt_type(void);

它应该返回INTR_TYPE_S_EL1或INTR_TYPE_NS。

  • (5) 确定已生成中断类型的处理程序。为此目的添加了以下 API。
interrupt_type_handler get_interrupt_type_handler(uint32_t interrupt_type);

它返回对该中断类型的已注册处理程序的引用。从第2 节中描述handler的结构中检索。如果没有为这种类型的中断注册处理程序,则返回。这种情况被报告为不可恢复的错误情况。intr_type_desc_tNULL

  • (6) 为生成的中断类型调用注册的处理函数。该id参数设置为INTR_ID_UNAVAILABLE当前。id 连同当前安全状态和对当前安全状态cpu_context_t 结构的引用作为参数传递给处理函数。

处理函数返回cpu_context_t 对目标安全状态的 per-cpu 结构的引用。

  • (7) 调用el3_exit()以从 EL3 返回到由处理程序例程确定的安全状态中的较低异常级别。该el3_exit() 函数负责从 cpu_context_t目标安全状态的数据结构中恢复寄存器上下文。
5.5.2. 安全有效负载调度程序
5.5.2.1。中断入口

当 EL3 运行时固件为该类型的中断调用处理函数时,SPD 服务开始处理该中断。SPD 服务负责以下工作:

  • (1) 验证中断。这涉及确保根据注册期间 SPD 服务指定的中断路由模型生成中断。flags它应该使用中断被从中获取的异常级别的安全状态(在处理程序的参数中传递)来确定这一点。如果中断未被识别,则处理程序应将其视为不可恢复的错误条件。

SPD 服务可以为 Secure-EL1 和/或非安全中断注册处理程序。非安全中断不应该从非安全状态路由到 EL3。此外,如果选择了在执行处于安全状态时将 Secure-EL1 中断路由到 S-EL1 的路由模型,则永远不应将 S-EL1 中断从安全状态路由到 EL3。处理程序可以使用安全状态标志来检查这一点。

  • (2) 确定是否需要上下文切换。这取决于路由模型和中断类型。对于非安全和 S-EL1 中断,如果产生中断的执行上下文的安全状态与处理中断所需的安全状态不同,则需要进行上下文切换。以下 2 种情况需要从安全到非安全的上下文切换,反之亦然:
    – 从非安全状态获取的 Secure-EL1 中断应路由到安全有效负载。
    – 从安全状态获取的非安全中断应路由到最后一个已知的非安全异常级别。

SPD 服务必须保存当前安全状态的系统寄存器上下文。然后它必须恢复目标安全状态的系统寄存器上下文。它应该使用cm_set_next_eret_context()API 来确保下一个cpu_context要恢复的是目标安全状态。

如果目标状态是安全的,则应根据其实现的同步中断处理模型将执行交给 SP。在 SP 中执行时,可以将 Secure-EL1 中断路由到 EL3。这意味着在处理另一个更高优先级的 Secure-EL1 中断或 EL3 中断的中断时,可以抢占 SP 执行。在将控制权交给 SP 之前,SPD 服务应该能够处理这种抢占或管理安全中断优先级。

  • (3) cpu_context如果中断已成功验证并准备好在较低的异常级别处理,则将处理程序的返回值设置为 per-cpu 。

路由模型允许非安全中断在安全状态下中断 Secure-EL1(如果已配置为这样做)。SPD 服务和 SP 应该实现一种机制,将这些中断路由到非安全状态下的最后一个已知异常级别。前者要保存SP上下文,恢复非安全上下文,安排进入非安全状态,以便处理中断。

5.5.2.2。中断出口

当 Secure Payload 处理完 Secure-EL1 中断后,它可以通过 SMC32 或 SMC64 将控制权返回给 SPD 服务。SPD 服务应处理此安全监视器调用,以便在异常级别和最初获取 Secure-EL1 中断的安全状态中恢复执行。

5.5.2.3。测试安全有效负载调度程序 Secure-EL1 中断处理

示例 TSPD 服务为从非安全状态获取的 Secure-EL1 中断注册处理程序。在 S-EL1 中执行期间,TSPD 期望 Secure-EL1 中断由 TSP 在 S-EL1 中处理。它的处理程序 tspd_secure_el1_interrupt_handler()只希望为源自非安全状态的 Secure-EL1 调用。它在被调用时执行以下操作。

  • (1) 它使用flags参数中提供的安全状态来确保安全中断源自非安全状态。它断言如果不是这种情况。

  • (2) 它通过调用保存非安全状态的系统寄存器上下文 cm_el1_sysregs_context_save(NON_SECURE);。

  • (3) 它将ELR_EL3系统寄存器设置为tsp_sel1_intr_entry并设置 SPSR_EL3.DAIF安全 CPU 上下文中的位。它设置x0为 TSP_HANDLE_SEL1_INTR_AND_RETURN。如果 TSP 在 SMC 处理期间被非安全中断提前抢占yielding,请保存将被丢弃的寄存器,即ELR_EL3和SPSR_EL3,以便能够重新进入 TSP 以进行 Secure-EL1 中断处理。它不需要保存任何其他安全上下文,因为预计 TSP 会保留它(请参阅测试安全有效负载调度程序行为部分)。

  • (4) 它通过调用来恢复安全状态的系统寄存器上下文 cm_el1_sysregs_context_restore(SECURE);。

  • (5) 它确保安全的 CPU 上下文用于通过调用cm_set_next_eret_context(SECURE);.

  • (6) 它返回 per-cpucpu_context以指示中断现在可以由 SP 处理。x1写入elr_el3 非安全状态的寄存器值。SP 使用此信息进行调试。

下图描述了在执行处于非安全状态时产生 Secure-EL1 中断时 TSPD 如何实现中断处理。

在这里插入图片描述

TSP 发出一个带有TSP_HANDLED_S_EL1_INTR函数标识符的 SMC,以表示中断处理的完成。

tspd_smc_handler()TSPD 服务在接收到具有TSP_HANDLED_S_EL1_INTR作为功能标识符的 SMC 时在功能中采取以下操作:

  • (1) 它确保调用源自安全状态,否则执行返回到SMC_UNKin的非安全状态x0。

  • (2) 如果 TSP 早先被非安全中断抢占,它将保存的ELR_EL3和系统寄存器恢复到安全 CPU 上下文(参见上面的步骤 3)。SPSR_EL3

  • (3) 它通过调用恢复非安全状态的系统寄存器上下文cm_el1_sysregs_context_restore(NON_SECURE)。

  • (4) 它确保使用非安全 CPU 上下文通过调用cm_set_next_eret_context(NON_SECURE).

  • (5) tspd_smc_handler()返回对非安全的引用cpu_context 作为返回值。

5.5.2.4。测试安全有效负载调度程序非安全中断处理

Secure-EL1 中的 TSP 可以在 SMC 处理期间被非安全中断抢占, yielding或者在 Secure-EL1 中断处理期间被更高优先级的 EL3 中断抢占。当EL3_EXCEPTION_HANDLING是时0,只有非安全中断会导致 TSP 抢占,因为系统中没有 EL3 中断。EL3_EXCEPTION_HANDLING=1然而,任何 EL3 中断都可能抢占安全执行。

应该注意的是,当 TSP 被抢占时,TSPD 仅允许进入 TSP 以进行 Secure-EL1 中断处理或恢复被抢占的 yieldingSMC 以响应TSP_FID_RESUME来自正常世界的 SMC。(请参阅抢占 SMC 对非安全软件的影响一节)。

在 SMC 处理期间在 Secure-EL1 中触发的非安全中断yielding可以路由到 EL3 或 Secure-EL1,并由构建选项控制TSP_NS_INTR_ASYNC_PREEMPT(请参阅测试安全负载调度程序行为一节)。如果设置了构建选项,TSPD 将为非安全中断设置路由模型,使其从安全状态(即TEL3=1,CSS=0)路由到 EL3,并注册tspd_ns_interrupt_handler()为非安全中断处理程序。被调用的tspd_ns_interrupt_handler()on 确保中断源自安全状态,并禁用非安全中断从安全状态到 EL3 的路由。这是为了防止在重新进入 TSP 以处理在正常环境中执行时触发的 Secure-EL1 中断时进一步抢占(通过非安全中断)。这tspd_ns_interrupt_handler()然后调用 tspd_handle_sp_preemption()以进行进一步处理。

如果TSP_NS_INTR_ASYNC_PREEMPT构建选项为零(默认),则安全状态下非安全中断的默认路由模型生效,即TEL3=0, CSS=0。在yieldingSMC 处理期间,IRQ 异常未被屏蔽PSTATE.I=0,即在 Secure-EL1 IRQ 异常向量处将触发非安全中断。TSP 保存通用寄存器上下文并发出一个 SMCTSP_PREEMPTED作为功能标识符,以表示 TSP 的抢占。TSPD SMC 处理程序 tspd_smc_handler()确保 SMC 调用源自安全状态,否则执行返回到非安全状态 SMC_UNKin x0。然后它调用tspd_handle_sp_preemption()以进行进一步处理。

tspd_handle_sp_preemption()被调用时会执行以下操作:

  • (1) 它通过调用来保存安全状态的系统寄存器上下文 cm_el1_sysregs_context_save(SECURE)。

  • (2) 它通过调用恢复非安全状态的系统寄存器上下文cm_el1_sysregs_context_restore(NON_SECURE)。

  • (3) 它确保使用非安全 CPU 上下文通过调用cm_set_next_eret_context(NON_SECURE).

  • (4) SMC_PREEMPTED设置为 x0 并在恢复非安全上下文后返回非安全状态。

yieldingNormal World 有望在SMC 抢占后通过发布一个 SMCTSP_FID_RESUME作为功能标识符来恢复 TSP (请参阅抢占 SMC 对非安全软件的影响一节)。tspd_smc_handler()TSPD 服务在收到此 SMC 后在功能上采取以下行动:

  • (1) 它确保呼叫源自非安全状态。否则会引发断言。

  • (2) 检查 TSP 是否需要恢复,即检查它是否被抢占。然后它通过调用保存非安全状态的系统寄存器上下文 cm_el1_sysregs_context_save(NON_SECURE)。

  • (3) 通过调用恢复安全上下文 cm_el1_sysregs_context_restore(SECURE)

  • (4) 它确保安全的 CPU 上下文用于通过调用cm_set_next_eret_context(SECURE).

  • (5) tspd_smc_handler()返回对安全的引用cpu_context作为返回值。

下图描述了当构建标志为 0时在 TSP with PSTATE.I= 0 中执行期间生成的非安全中断时,TSP/TSPD 如何处理该中断。TSP_NS_INTR_ASYNC_PREEMPT

在这里插入图片描述

5.5.3. 安全有效负载中断处理

SP 应该实现同步和异步中断处理模型中的一种或两种,具体取决于它选择的中断路由模型(如安全有效负载部分所述)。

在同步模型中,它应该在从构建时间或注册阶段商定的入口点接收来自 SPD 服务的控制后开始处理 Secure-EL1 中断。在处理中断之前,SP 应该保存任何 Secure-EL1 系统寄存器上下文,以便稍后在 SP 中恢复正常执行,SPSR_EL1例如ELR_EL1. 处理完中断后,SP 可以将控制权返回到最初获取中断的异常级别和安全状态。SP 应使用 SMC32 或 SMC64 请求 SPD 服务执行此操作。

PSTATE.I在异步模型中,当和位为 0时,Secure Payload 负责在其异常向量表中的 IRQ 和 FIQ 向量处处理非安全和 Secure-EL1 中断。PSTATE.F如前所述,当生成非安全中断时, SP 应与 SPD 服务协调,以将控制权传递回最后一个已知异常级别的非安全状态。这将允许在非安全状态下处理非安全中断。

5.5.3.1。测试安全有效负载行为

TSPD 将 Secure-EL1 中断的控制权交给 TSP 在 tsp_sel1_intr_entry(). TSP 处理中断,同时确保保持部分测试安全负载调度程序行为中描述的切换协议。它通过调用来更新一些统计信息 tsp_update_sync_sel1_intr_stats()。然后它调用 tsp_common_int_handler()which。

  • (1) 检查中断是否为安全物理定时器中断。它使用平台 APIplat_ic_get_pending_interrupt_id()来获取中断号。如果它不是安全物理定时器中断,则意味着更高优先级的中断已经抢占了它。通过发出具有作为功能标识符的 SMC 来调用 tsp_handle_preemption()将控制权移交回 EL3 。TSP_PREEMPTED

  • (2) 通过使用平台 API 确认安全定时器中断中断 plat_ic_acknowledge_interrupt()、调用 tsp_generic_timer_handler()以重新编程安全物理通用定时器并调用plat_ic_end_of_interrupt()平台 API 以发出中断处理结束的信号来处理安全定时器中断中断。

TSP 通过发出 SMC64 TSP_HANDLED_S_EL1_INTR作为功能标识符将控制权交还给 TSPD。

TSP 处理异步模型下的中断如下。

  • (1) Secure-EL1 中断通过调用该tsp_common_int_handler() 函数来处理。该功能已在上面进行了描述。

  • (2) 通过调用函数来处理非安全中断,该tsp_common_int_handler() 函数最终调用tsp_handle_preemption()并发出 SMC64TSP_PREEMPTED作为函数标识符。当 TSPD 将控制权交给 TSP 以响应具有TSP_FID_RESUME非安全状态的功能标识符的 SMC 时,执行在此 SMC 指令之后的指令处恢复执行(请参阅测试安全有效载荷调度程序非安全中断处理部分)。

5.6. 其他注意事项

5.6.1。抢占 SMC 对非安全软件的影响

对安全有效负载的yieldingSMC 调用可以被非安全中断抢占,并且执行可以返回到非安全世界以处理中断(有关yieldingSMC 的详细信息,请参阅SMC 调用约定)。在这种情况下,SMC 调用尚未完成其执行,执行必须返回到安全有效负载以恢复被抢占的 SMC 调用。这可以通过发出指示恢复被抢占的 SMC 的 SMC 调用来实现。

fastSMC 不能被抢占,因此这种情况不会发生在快速 SMC 调用中。

在 Test Secure Payload 实现中,TSP_FID_RESUME被指定为恢复 SMC FID。重要的是要注意这TSP_FID_RESUME是一个 yieldingSMC,这意味着它也可以被抢占。发布yieldingSMC 的典型非安全软件序列如下所示,假设P.STATE.I=0处于非安全状态:

int rc;
rc = smc(TSP_YIELD_SMC_FID, ...);     /* Issue a Yielding SMC call */
/* The pending non-secure interrupt is handled by the interrupt handler
   and returns back here. */
while (rc == SMC_PREEMPTED) {       /* Check if the SMC call is preempted */
    rc = smc(TSP_FID_RESUME);       /* Issue resume SMC call */
}

是TSP_YIELD_SMC_FID任何yieldingSMC 函数标识符,并且 smc() 函数调用带有所需参数的 SMC 调用。挂起的非安全中断导致 IRQ 异常,注册在异常向量中的 IRQ 处理程序处理非安全中断并返回。测试来自 SMC 调用的返回值SMC_PREEMPTED以检查它是否被抢占。如果是,则TSP_FID_RESUME发出恢复 SMC 调用。再次测试 SMC 调用的返回值,检查是否被抢占。这是在循环中完成的,直到 SMC 调用成功或失败。如果yielding SMC 被抢占,在使用 SMC 恢复并完成之前,当前 TSPD 通过返回错误TSP_FID_RESUME来防止任何其他 SMC 调用重新进入 TSP

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Arm精选

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值