TEE OS中断篇(一):系统的中断处理

news/2024/5/1 3:51:38/文章来源:https://blog.csdn.net/weixin_45264425/article/details/127164040

前面我学习了线程方面的东西,这个假期,空闲了来看看《手机安全和可信应用开发指南》这本书的中断篇。

中断处理

一个完整的系统都会存在中断,ARMv7架构扩展出了Monitor模式而ARMv8使用EL的方式对ARM异常运行模式进行了重新定义,分为EL0~EL3。

在ARMv8架构系统中,OP-TEE运行于安全侧的EL1, bl31运行于EL3。系统运行过程中任何阶段都有可能会产生外部中断。本章将主要介绍FIQ事件和IRQ事件在OP-TEE、ARMv7架构中的Monitor模式、ARMv8架构中的EL3的处理过程。

(前面其实如果你读过这本书的前面,会知道我们对于通过SMC的方式去陷入到EL3的方式与处理流程以及有所认识,但是大多数时候都避开了中断的方式。这里好好关注一下中断的方式。其次在ARMv8的架构体系中,EL3是拉通的,而EL2到EL0是分为安全与非安的。当然EL3肯定是安全的。)

1 系统的中断处理

ARM核处于安全世界状态(SWS)和正常世界状态(NWS)都具有独立的VBAR寄存器和中断向量表。

VBAR(Vector Base Address Register)的寄存器有:如果是aarch64:
VBAR_EL1
VBAR_EL2
VBAR_EL3如果是aarch32
VBAR
HVBAR
MVBAR

(VBAR(Vector Base Address Register)就是寄存器基地址)

而当ARM核处于Monitor模式或者EL3时,ARM核将具有独立的中断向量表和MVBAR寄存器。

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

因此这里是三种中断,想实现各种中断在三种状态下被处理的统一性和正确性,就需要确保各种状态下 中断向量表以及GIC的正确配置。

RM的指导手册中建议在TEE中使用FIQ,在ROS中使用IRQ,即TEE侧会处理由中断引起的FIQ事件,而Linux内核端将会处理中断引起的IRQ事件。

而由于ATF的使用,Monitor状态或者EL3下中断的处理代码将会在ATF中实现。

针对ARM核,中断与ARM核每种状态的关系图如图12-1所示。
在这里插入图片描述
系统中的中断主要被分为Native Interrupt(内部中断)和Foreign Interrupt(外部中断)事件,FIQ会被TEE侧处理,IRQ会被REE侧处理。

如果在Monitor模式或EL3阶段产生了中断,则处于Monitor模式或者EL3的软件会使用MVBAR寄存器中保存的异常向量表中的处理函数对FIQ或者IRQ事件进行处理。

2 中断控制器

中断控制器(General Interruption Controller, GIC)模块是CPU的外设之一,它的作用是接收来自其他外设的中断引脚输入,然后根据中断触发模式中断类型优先级等 设置来控制发送不同的中断信号到CPU。

(这就是通过GIC对外设的中断进行了统一的管理)

ARM对GIC的架构也在不断改进,已经从GICv1发展到现在的GICv4版本。目前主要使用的是GICv2和GICv3架构。(书里面介绍在支持TEE安全扩展的ARM处理器平台上这两个版本的中断控制器是如何工作的。)

2.1 GIC寄存器

GIC模块中的寄存器主要分为**中断控制分发寄存器(缩写为GICD)以及CPU接口寄存器(缩写为GICC)**两部分。

GICD接收所有的中断源,然后根据中断的优先级来判定是否响应中断,以及是否将该中断信号转发到对应的CPU。

GICC和各个ARM核相连。当收到来自GICD的中断信号时,由GICC来决定是否将中断请求发送给ARM核。

支持安全扩展的GIC模块将中断分为了两组:Group0中断和Group1中断

对于ARMv7架构,Group0为安全中断,Group1为非安全中断。

对于ARMv8架构,Group0为安全中断且有最高的优先级,而Group1又分安全中断(Group1Secure, G1S)非安全中断(Group1 NonSecure,G1NS)

GIC会根据中断所在的Group安全类型及当前ARM核运行模式来决定是发送FIQ还是IRQ信号到ARM核。

根据GIC版本的不同其决定方式也不同。关于这点将在接下来的章节分开介绍。

另外,当ARM核收到FIQ/IRQ信号后会进入哪种模式是由SCR寄存器来决定的。

ARMv8架构中,OP-TEE根据中断要求触发的模式将中断类型分为三类,其定义如下:

        #define INTR_TYPE_S_EL1   0        // 该中断应该由Secure EL1处理#define INTR_TYPE_EL3     1        // 该中断应该由EL3处理#define INTR_TYPE_NS      2        // 该中断应该由Normal World处理

不同版本的GIC对于以上三种类型的中断将会产生不同的IRQ或FIQ事件,故需要先根据GIC版本来确定上述三种类型的中断所产生的是IRQ还是FIQ事件,然后再设定SCR寄存器中SCR.FIQ和SCR.IRQ位来决定该中断是否会触发ARM核进入EL3阶段。

2.2 ARMv7 SCR寄存器的设定

ARMv7架构中,SCR寄存器中的值是在optee_os/core/arch/arm/sm/sm_a32.S文件被设定,其内容大家阅读书籍,这里我的关注点主要在ARMv8上。

2.3 ARMv8 SCR寄存器的设定

首先ATF在bl31/interrupt_mgmt.h下分别定义了Secure EL1、NonSecure以及EL3模式下Group0和Group1中断的路由模式。

        /* 以下分别定义了在EL3/SEL1/NS模式下中断的路由模式,定义名称格式如下* RM:    Routing Model* SEL1: Secure EL1 Mode(optee os)* NS:    Non Secure Mode* 0:     Routing Model 0* 1:     Routing Model 1* 值对应SCR寄存器中的bit[2:0],定义如下* bit[0]: SCR.NS (0: Secure, 1: Non Secure)* bit[1]: SCR.IRQ (0: enter IRQ mode 1: enter EL3 monitor)* bit[2]: SCR.FIQ (0: enter FIQ mode 1: enter EL3 monitor)*//* 从NS进入EL3.并在安全态的EL1进行处理 */#define INTR_SEL1_VALID_RM0       0x2/* 从NS或者安全态进入EL3 */#define INTR_SEL1_VALID_RM1       0x3/* 从NS进入EL1/EL2并转切到安全态的EL1 */#define INTR_NS_VALID_RM0 0x0/* 从NS到EL1/EL2或从安全态进入EL3#define INTR_NS_VALID_RM1 0x1/* 从NS进入EL3,并进入安全态的EL1,最终进入EL3 */#define INTR_EL3_VALID_RM0        0x2/* 从NS或安全态进入EL3 */#define INTR_EL3_VALID_RM1        0x3/* 默认模式转移路径 */#define INTR_DEFAULT_RM   0x0

为兼容GICv2和G ICv3平台,在初始化CPU时将IRQ和FIQ位同时设置为1,设置相关代码如下:

        void css_cpu_standby(plat_local_state_t cpu_state){unsigned int scr;assert(cpu_state == ARM_LOCAL_STATE_RET);scr = read_scr_el3();/*对于非安全中断,如果当前CPU运行在EL3,对于GICv3平台非安全Group1中断会触发FIQ中断,而对于  GICv2平台Group1中断会触发IRQ中断,这里同时将FIQ和IRQ位设置成1所以GICv2/v3平台的非安全中断都会进入EL3 */write_scr_el3(scr | SCR_IRQ_BIT | SCR_FIQ_BIT);isb();dsb();//等待非安全中断触发wfi();//恢复SCR寄存器的原始值write_scr_el3(scr);}

CPU初始化过程中会调用register_interrupt_type_handler来设定Secure EL1下的SCR寄存器,其内容如下:

        case TEESMC_OPTEED_RETURN_ENTRY_DONE:assert(optee_vectors == NULL);optee_vectors = (optee_vectors_t *) x1;if (optee_vectors) {set_optee_pstate(optee_ctx->state, OPTEE_PSTATE_ON);//OP-TEE初始化成功,安装psci处理函数psci_register_spd_pm_hook(&opteed_pm);//设置flag为ON_SECURE定义为1flags = 0;set_interrupt_rm_flag(flags, NON_SECURE);//设定进入Secure EL1状态时SCR应使用的值rc = register_interrupt_type_handler(INTR_TYPE_S_EL1,opteed_sel1_interrupt_handler, flags);if (rc)panic();

register_interrypt_type_handler函数会调用set_routing_model来定义三种不同目标的中断在EL3和EL1的SCR寄存器的值,该函数内容如下:

        int32_t set_routing_model(uint32_t type, uint32_t flags){int32_t rc;rc = validate_interrupt_type(type);if (rc)return rc;/* 检查将要设定的SCR的值是否是之前interrupt_mgmt.h中预定义的有效值 */rc = validate_routing_model(type, flags);if (rc)return rc;/* 结构体变量intr_type_descs用来描述安全/正常模式下SCR的设定 */intr_type_descs[type].flags = flags;/* 设置在CPU安全模式下(SCR.NS=0)的SCR.IRQ、SCR.FIQ位 */set_scr_el3_from_rm(type, flags, SECURE);/* 设置在CPU正常模式下(SCR.NS=1)的SCR.IRQ、SCR.FIQ位 */set_scr_el3_from_rm(type, flags, NON_SECURE);return 0;}set_scr_el3_from_rm函数实现如下:static void set_scr_el3_from_rm(uint32_t type, uint32_t interrupt_type_flags,uint32_t security_state){uint32_t flag, bit_pos;/** 这里根据security_state状态来获取对应SCR要设定的值* 如果之前调用的是set_interrupt_rm_flag(flags, NON_SECURE)* 1. security_state == SECUREflag = (0xb10 >> SECURE) & 0xb1  = 0* 2. security_state == NONSECURE: flag = (0xb10 >> NONSECURE) & 0xb1 = 1* 如果之前调用的是set_interrupt_rm_flag(flags, SECURE) 同理* 1. security_state == SECURE: flag = 1* 2. security_state == NONSECURE: flag = 0*/flag = get_interrupt_rm_flag(interrupt_type_flags, security_state);/* 这个函数根据GIC的版本决定设定SCR寄存器中FIQ/IRQ位 */bit_pos = plat_interrupt_type_to_line(type, security_state);intr_type_descs[type].scr_el3[security_state] = flag << bit_pos;/* 如果当前上下文有效则可以在这里直接更新scr_el3否则将要设定的SCR的值保存在* intr_type_descs中,之后通过get_scr_els3_from_routing_model()函数来获取并* 写入SCR寄存器中*/if (cm_get_context(security_state))cm_write_scr_el3_bit(security_state, bit_pos, flag);}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_18662.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring 测试运行的时候提示 Unable to find a @SpringBootConfiguration 错误

Spring 进行测试的时候提示的错误信息如下: SEVERE: Caught exception while closing extension context: org.junit.jupiter.engine.descriptor.JupiterEngineExtensionContext@c63c11ed java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you n…

Flink学习笔记(4)——Flink运行架构

目录 一、Flink运行时架构 1.1 系统架构 1.1.1 整体构成 1.1.2 作业管理器(JobManager) 1.1.3 任务管理器(TaskManager) 1.2 作业提交流程 1.2.1 高层级抽象视角 1.2.2 独立模式(Standalone) 1.2.…

SpringCloud 使用 Turbine 聚合监控 Hystrix 健康状态

Hystrix 的降级熔断,只是被迫的折中方案,并不是我们所期望的结果,我们还是期望系统能够永远健康运行。绝大多数情况下,一个系统有很多微服务组成,在高峰期很可能个别微服务会发生降级熔断,我们必须能够通过监控才行,这样才能快速发现并解决问题。 Hystrix 是 Netflix 的…

soc的核间通信机制-->mailbox

对于mailbox,这个东西其实看到了很多次,但是一直不知道是啥。这里大概看了一下,知道了为甚有这个玩意儿,以及这个玩意相关的有啥,至于具体怎么使用,以及详细的工作原因等着以后再说吧。 正文 目前很多芯片…

微信小程序开发实战(SM周期及WXS脚本)

作者 : SYFStrive 博客首页 : HomePage 📜: 微信小程序 📌:个人社区(欢迎大佬们加入) 👉:社区链接🔗 📌:觉得文章不错可以点点关注 &#x1f4…

webshell 提权

在我们使用cve或者其他方式获取shell 后 python -c import pty;pty.spawn("/bin/bash") 获取一个交互式的bash shell 使用id 命令可以查看当前的用户权限 查看当前的linux 系统版本 利用kali自带的漏洞检索库检索漏洞 searchsploit privilege | grep -i linux |…

【MySQL】数据库介绍以及MySQL数据库

目录 数据库介绍 数据库概述 数据表 MySql数据库 MySql安装 登录MySQL数据库 ​​​​​​​SQLyog(MySQL图形化开发工具) 数据库介绍 数据库概述 什么是数据库(DB:DataBase) 数据库就是存储数据的仓库,其本质是一个文件系统&#…

实训任务1:Linux基本操作

文章目录一、实训目的二、实训要求三、实训任务1、创建并配置三个虚拟机2、创建SSH连接3、实现IP地址与主机名的映射4、关闭和禁用防火墙5、创建目录结构6、压缩打包7、安装软件包8、创建脚本文件9、直接运行脚本10、虚拟机相互免密登录11、远程拷贝文件一、实训目的 通过实训…

代谢组学和宏基因组学研究不同添加剂对青贮品质的影响

​ 发表期刊:Bioresource Technology 影响因子:9.642 百趣生物提供服务:代谢组学宏基因组 研究背景 人口增长促进了全球肉类和牛奶消费量增加,养殖所需饲料用量也逐年上升,发酵后的饲料是进行农副产品处理更好的选…

大数据技术Spark3.0详解

一、Spark3.0 简介 Spark3.0版本包含了3400多个补丁程序,是开源社区做出巨大贡献的最高峰,带来了Python和SQL功能的重大进步,并着眼于探索和生产的易用性。 1、Spark3.0新功能 (1)通过自适应查询执行,动…

基于物联网的智能厨房安全监测系统-上位机程序

CSDN话题挑战赛第2期 参赛话题:学习笔记 博客写作背景----项目中解决的问题 最近遇到一个基于TCP/IP网络的远程智能物联网系统,采用Arduino Uno控制器作为下位机,采用LabVIEW作为远程监控软件,两者通过网络实现通信。初步定为使…

2022/10/4——基于stm32mp157a的M4核的中断实验

本次实验采用STM32CubeMX软件进行元器件的初始化 本次实验采用的中断源为三个按键和光电开关、火焰传感器、人体红外。其实验接口分别为: key1------>PF9 key2------>PF7 key3------>PF8(检测方式:下降沿) 光电开…

详解欧拉计划第107题:最小网络

下面这个无向网络包含有7个顶点和12条边,其总重量为243。 这个网络也可以用矩阵的形式表示如下。 ABCDEFGA-161221---B16--1720--C12--28-31-D211728-181923E-20-18--11F--3119--27G---231127-然而,我们其实可以优化这个网络,移除其中的一些边&#

windows幻灯片壁纸

幻灯片设置10秒设置为10秒 win+r输入regedit 查找路径 HKEY_CURRENT_USER\Control Panel\Personalization\Desktop Slideshow 修改interval文件没有就创建一个 修改10进制文件 60000(毫秒为60秒)改为10000(毫秒为10秒)即可 修改后点击幻灯片放映他自己设置为10分钟不用管他已经…

深入分析vhost-user网卡实现原理 —— VirtIO Features协商

文章目录前言数据结构设备模型deviceVirtIONetPCIVirtIONetNICStateNetClientStatenetdevNetVhostUserStatevhost_netvhost_devchardevchardevChardevClassSocketChardevFeaturesVirtIONetVirtIODevicevhost_devNetVhostUserStatefeature_bitsBackend流程详解启动过程网络连接网…

【Docker Desktop】Neo4j

1、下载neo4j并启动 docker run --rm --name testneo4j -p 7474:7474 -p 7687:7687 -d -v C:/Users/ASUS/Desktop/neo4j/data:/data -v C:/Users/ASUS/Desktop/neo4j/logs:/logs -v C:/Users/ASUS/Desktop/neo4j/import:/var/lib/neo4j/import -v C:/Users/ASUS/Desktop/neo4j…

Mysql出现问题:慢查询日志失效解决方案

❤️作者主页:小虚竹 ❤️作者简介:大家好,我是小虚竹。Java领域优质创作者🏆,CSDN博客专家🏆,华为云享专家🏆,掘金年度人气作者🏆,阿里云专家博主&#x1f3…

【C++入门】学习使用二维数组基本知识及用法详解

🧛‍♂️iecne个人主页::iecne的学习日志 💡每天关注iecne的作品,一起进步 💪一起学习,必看iecne 🐳希望大家多多支持🥰一起进步呀! 文章目录一.定义方式1.1…

深度学习进阶-自然语言处理-04-基于计数的方法(上)

语料库:大量的文本数据 语料库通常采用树的结构,我们这里的与料理假定没有添加任何标签,在实际项目中,一般都会给文本数据添加标签(如,词性) 1 语料库的预处理 步骤一:创建单词列表 #样本文章…

JavaScript学习笔记:Navigator

<!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><script>// BOM// 浏览器对象模型// BOM可以使我们通过js来操作浏览器// 在BOM中为我们提供了一组对象&#xff0c;用来完成对浏览器的操作// BOM对象/…