linux ARM64 异常

linux 的系统调用是通过指令陷入不同异常级别实现的。arm64 架构的 cpu 的异常级别结构如下:

在上图中,用户层运行在 EL0 也就是异常级别 0,Linux 内核运行在 EL1 也就是异常级别 1,安全可信操
作系统运行在异常级别 2:EL2,安全监控模块运行在异常级别 3:EL3。
上述提到的用户层和内核大家都熟悉,为了介绍异常级别的完整性,我们简单说一下这里的 EL2 和 EL3,
这两个异常级别实际为了实现 TEE(Trusted Execution Environment)即可信执行环境的一种硬件架构,在 ARM 上
称之为 TrustZone,TrustZone 是 ARM 针对消费电子设备设计的一种硬件架构,其目的是为消费电子产品构建
一个安全框架来抵御各种可能的攻击。TrustZone 在概念上将 SoC 的硬件和软件资源划分为安全(Secure World)
和非安全(Normal World)两个世界,所有需要保密的操作在安全世界执行(如指纹识别、密码处理、数据加解密、
安全认证等),其余操作在非安全世界执行(如用户操作系统、各种应用程序等),安全世界和非安全世界通过
一个名为 Monitor Mode 的模式进行转换。这里了解一下就行,针对于系统调用我们涉及不到这个。
介绍完异常级别,下面介绍一下在 ARM64 下,是如何陷入不同运行级别的:
1)  异常级别 0 使用 svc( Supervisor Call)指令陷入异常级别 1
2)  异常级别 1 使用 hvc(Hypervisor Call)指令陷入异常级别 2
3)  异常级别 2 使用 smc(Secure Monitor Call)指令陷入异常级别 3
系统调用就是运行在异常级别 0 的用户程序,通过使用 svc 指令陷入异常级别 1,来完成的陷入动作,之后
会根据异常向量表,执行异常向量服务程序。本文以 ARM64 为例来看异常向量表的配置,内核在
arch/arm64/kernel/entry.S 汇编代码中设置了异常向量表。
在介绍异常向量表之前,先介绍一下异常。在 ARM64 体系结构中,异常分为同步异常和异步异常。同步异
常是试图执行指令时生成的异常,或是作为指令的执行结果生成的异常。同步异常包括如下。
1)  系统调用。异常级别 0 使用 svc( Supervisor Call)指令陷入异常级别 1,异常级别 1 使用 hvc
(Hypervisor Call)指令陷入异常级别 2,异常级别 2 使用 smc(Secure Monitor Call)指令陷入异常级
别 3。
2)  数据中止,即访问数据时的页错误异常,虚拟地址没有映射到物理地址,或者没有写权限。
3)  指令中止,即取指令时的页错误异常,虚拟地址没有映射到物理地址,或者没有执行权限。
4)  栈指针或指令地址没有对齐。
5)  没有定义的指令。
6)  调试异常。
异步异常不是由正在执行的指令生成的,和正在执行的指令没有关联。异步异常包括以下。
1)  中断( normal priority interrupt, IRQ),即普通优先级的中断。
2)  快速中断( fast interrupt, FIQ),即高优先级的中断。

3)  系统错误( System Error, SError),是由硬件错误触发的异常,例如最常见的是把脏数据从缓存行写
回内存时触发异步的数据中止异常。

/*
* Exception vectors.
*/
.pushsection ".entry.text", "ax"
.align 11
ENTRY(vectors)
kernel_ventry 1, sync_invalid //异常级别 1 生成的同步异常,使用栈指针寄存器 SP_EL0
kernel_ventry 1, irq_invalid //异常级别 1 生成的中断,使用栈指针寄存器 SP_EL0
kernel_ventry 1, fiq_invalid //异常级别 1 生成的快速中断,使用栈指针寄存器 SP_EL0
kernel_ventry 1, error_invalid //异常级别 1 生成的系统错误,使用栈指针寄存器 SP_EL0
kernel_ventry 1, sync //异常级别 1 生成的同步异常,使用栈指针寄存器 SP_EL1
kernel_ventry 1, irq //异常级别 1 生成的中断,使用栈指针寄存器 SP_EL1
kernel_ventry 1, fiq_invalid //异常级别 1 生成的快速中断,使用栈指针寄存器 SP_EL1
kernel_ventry 1, error_invalid //异常级别 1 生成的系统错误,使用栈指针寄存器 SP_EL1
kernel_ventry 0, sync //64 位应用程序在异常级别 0 生成的同步异常
kernel_ventry 0, irq // 64 位应用程序在异常级别 0 生成的中断
kernel_ventry 0, fiq_invalid // 64 位应用程序在异常级别 0 生成的快速中断
kernel_ventry 0, error_invalid //64 位应用程序在异常级别 0 生成的系统错误
#ifdef CONFIG_COMPAT
kernel_ventry 0, sync_compat, 32 //32 位应用程序在异常级别 0 生成的同步异常
kernel_ventry 0, irq_compat, 32 // 32 位应用程序在异常级别 0 生成的中断
kernel_ventry 0, fiq_invalid_compat, 32 // 32 位应用程序在异常级别 0 生成的快速中断
kernel_ventry 0, error_invalid_compat, 32 // 32 位应用程序在异常级别 0 生成的系统错误
#else
kernel_ventry 0, sync_invalid, 32 //32 位应用程序在异常级别 0 生成的同步异常
kernel_ventry 0, irq_invalid, 32 // 32 位应用程序在异常级别 0 生成的中断
kernel_ventry 0, fiq_invalid, 32 // 32 位应用程序在异常级别 0 生成的快速中断
kernel_ventry 0, error_invalid, 32 // 32 位应用程序在异常级别 0 生成的系统错误
#endif
END(vectors)

上面的代码进一步展开,就是设置不同 mode 下的异常向量表,异常可以分为 4 组,每组异常有 4 个,所以
这里一共会设置 16 个 entry。4 组异常分别对应 4 种情况下发生异常时的处理。以下是 4 个异常向量 entry 的含
义:
1)  同步异常
2)  中断
3)  快速中断
4)  系统错误

kernel_ventry 是一个宏,参数是跳转标号,即异常处理程序的标号,宏的定义如下(/arch/arm64/kernel/entry.S):
.macro kernel_ventry, el, label, regsize = 64
.align 7
sub sp, sp, #S_FRAME_SIZE //将 sp 预留一个 fram_size, 这个 size 就是 struct pt_regs 的
大小
#ifdef CONFIG_VMAP_STACK
//....这里省略掉检查栈溢出的代码
#endif
b el\()\el\()_\label // 跳转到对应级别的异常处理函数
.endm
“ .align 7”表示把下一条指令的地址对齐到 2^7,即对齐到 128; 对于向量表 vectors 中的 kernel_entry 0, sync,
则 b el\()\el\()_\label 跳转到 el0_sync 函数。 其中 0 表示的是从哪个异常模式产生的,比如是 user->kernel 就是
0., kernel->kernel 就是 1。
实现的函数有 el1_sync,el1_irq,el0_sync,el0_irq,el1_sync_compat,el1_irq_compat 其余都是 invalid。从
异常级别 1 的异常向量表可以看出如下内容。
1)  有些异常向量的跳转标号带有“invalid”,说明内核不支持这些异常,例如内核不支持 ARM64 处
理器的快速中断。
2)  对于内核模式(异常级别 1)生成的异常, Linux 内核选择使用异常级别 1 的栈指针寄存器。
3)  对于内核模式(异常级别 1)生成的同步异常,入口是 el1_sync。
4)  如果处理器处在内核模式(异常级别 1),中断的入口是 el1_irq。
5)  对于 64 位应用程序在用户模式(异常级别 0)下生成的同步异常,入口是 el0_sync。
6)  如果处理器正在用户模式(异常级别 0)下执行 64 位应用程序,中断的入口是 el0_irq。
7)  对于 32 位应用程序在用户模式(异常级别 0)下生成的同步异常,入口是 el0_sync_compat。
8)  如果处理器正在用户模式(异常级别 0)下执行 32 位应用程序,中断的入口是 el0_irq_compat。
前面设置了异常向量表,我们来进一步查看 SVC mode 的处理。当系统调用时 CPU 会切换到 SVC mode,并
跳转到对应的地址去运行。kernel 中会配置两个 SVC Handler,分别对应这 SVC_32/SVC_64 两种 mode,32bit
程序和 64bit 程序执行系统调用会跳转到两个不同的 handler 去执行。

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

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

相关文章

微信小程序---分包

概念:分包就是把一个完整的小程序项目,按照需求划分为不同的子包,在构建时打包成不同的分包,用户在使用时按需进行加载。 分包的优点:可以优化小程序首次启动的下载时间,在多团队共同开发时可以更好的解耦…

[2023-年度总结]凡是过往,皆为序章

原创/朱季谦 2023年12月初,傍晚,在深圳的小南山看了一场落日。 那晚我们坐在山顶的草地上,拍下了这张照片——仿佛在秋天的枝头上,结出一颗红透的夕阳。 这一天很快就会随着夜幕的降临,化作记忆的碎片,然…

ComfyUI如何中文汉化

comfyui中文地址如下: https://github.com/AIGODLIKE/AIGODLIKE-ComfyUI-Translationhttps://github.com/AIGODLIKE/AIGODLIKE-ComfyUI-Translation如何安装? 1. git安装 进入项目目录下的custom_nodes目录下,然后进入控制台,运…

Geotrust与QuickSSL证书

随着互联网的发展,SSL证书已经成为了保护网站数据传输安全的重要手段。然而,一些SSL证书申请流程繁琐,需要提供各种证明文件和等待审核,这对于许多小型企业或个人站长来说是一个很大的困扰。QuickSSL是Geotrust旗下的子品牌之一&a…

飞天使-k8s知识点7-kubernetes升级

文章目录 验证新版本有没有问题需要安装的版本微微 1.20.6.0kubeadm upgrade plan 验证新版本有没有问题 查看可用版本的包 现有的状态 查看版本 yum list kubeadm --showduplicates |grep 1.20 yum list kubelet --showduplicates |grep 1.20 yum list kubectl --showduplic…

P1016 [NOIP1999 提高组] 旅行家的预算

网址如下: P1016 [NOIP1999 提高组] 旅行家的预算 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 考前练练手 一道 普及/提高 难度的题 秒了 想到以前高中的时候被普及难度的题按在地上摩擦,现在能秒洛谷普及难度的题,有点泪目 代码如下…

记账导出excel表格,用表格导出账目数据

我们每天都在跟金钱打交道,记账则是更好地管理自己财务的一种方式,传统记账不仅繁琐,还容易出错。那么,有没有简单、高效的记账方式呢?答案是肯定的!今天,我们就向大家推荐一款全新的记账软件——晨曦记账本…

电子公章软件,怎么实现批量自动盖章?

在商务合作中,企业电子公章软件在提高办公效率、确保文件的法律效力方面发挥着关键作用。微签是国内电子公章软件领域的拓荒者之一,有19年的电子签研发应用经验,专注于审批场景中的安全签章。 今天,微签给大家带来了详细的“批量…

【电商】AI模特 高清放大

目录 实战一:模特人偶 实战二:3D OPEN POSE 生成 模特 高清放大(可开启ADetailer) 实战三:半身模特 随机生成 高清放大(可开启ADetailer) 实战四:人偶生成模特图 实战一&#x…

文献速递:生成对抗网络医学影像中的应用——3DGAUnet:一种带有基于3D U-Net的生成器的3D生成对抗网络

文献速递:生成对抗网络医学影像中的应用——3DGAUnet:一种带有基于3D U-Net的生成器的3D生成对抗网络 给大家分享文献的主题是生成对抗网络(Generative adversarial networks, GANs)在医学影像中的应用。文献的研究内容包括同模态…

线上服务有哪些稳定性指标?

在分布式高可用设计中,系统监控非常重要,系统监控做好了,可以提前对异常情况进行报警,避免很多线上故障的产生。系统监控做得好不好,也是评价一家互联网公司基础建设水平的重要标准,今天一起来讨论一下&…

Vue和React的运行时,校验引入包的上下文差异

背景 系统使用 webpack 5 模块联邦实现微前端,有关如何实现跨应用的代码共享,可参考 如何优雅的实现跨应用的代码共享 里的第三大点。 总之,这里是其他应用使用了某个应用共享出来的reg文件,引入方式为: import REG …

Dbeaver如何连接Oceanbase?

Dbeaver & Oceanbase 一、新增驱动二、连接数据库 一、新增驱动 1、新建驱动 点击数据库 -> 驱动管理器 -> 新建 2、设置驱动 驱动名称可随意填写注意驱动类型要是Generichost:port填写实际的host和port 库中新增下载的oceanbase驱动jar包 二、连接数据库 1、找…

ECMAScript 6 - 通过Promise输出题理解Promise

1 题目(1) 题目背景:分享洛千陨 珍藏题 const p1 () > (new Promise((resolve, reject) > {console.log(1);let p2 new Promise((resolve, reject) > {console.log(2);const timeOut1 setTimeout(() > {console.log(3);resolve(4);}, 0)resolve(5)…

【前端框架React】原理

React设计思想 1.原生JS React相比于vue来说更接近原生JS,因为在react内部,jsx模板经babel转化后是一个对象,所有的操作都是基于这个对象和其对应的fiber结构来操作的,而vue.js通过编译将templete模板转换成渲染函数(render),执…

工具系列:TensorFlow决策森林_(3)使用dtreeviz可视化

文章目录 介绍设置安装 TF-DF 和 dtreeviz导入库 可视化分类树加载、清洗和准备数据分割训练/测试集并训练模型训练一个随机森林分类器显示决策树检查叶节点统计信息决策树如何对实例进行分类特征空间划分 可视化回归树加载、清洗和准备数据分割训练/测试集并训练模型训练一个随…

漏洞处理-未设置X-Frame-Options

漏洞名称&#xff1a;iFrame注入 风险描述&#xff1a;系统未设置x-frame-options头 风险等级&#xff1a;低 整改建议&#xff1a;为系统添加x-frame-options头 知识 X-Frame-Options 响应头 X-Frame-Options HTTP 响应头是用来给浏览器指示允许一个页面可否在 <fram…

一体式读卡器:引领数据读取新潮流

一体式读卡器&#xff1a;引领数据读取新潮流 随着科技的发展&#xff0c;读卡器在各个领域的应用越来越广泛&#xff0c;如工业自动化生产、身份认证、门禁控制、数据采集等。读卡器主要有两种类型&#xff1a;一体式读卡器和分体式读卡器。这两种类型的读卡器各有其优缺点&a…

带你读懂SoBit 跨链桥教程

从BTC网络到Solana网络桥接BRC20 1.打开SoBit平台&#xff1a;在您的网络浏览器中启动SoBit Bridge应用程序。 2.连接您的钱包&#xff1a; 选择SoBit界面右上角的比特币网络来连接您的数字钱包。 3.选择源链、目标链和您想桥接的代币&#xff1a; 从下拉菜单中选择’BTC’作为…

通过 conda 安装 的 detectron2

从 detectron2官网 发现预编译的版本最高支持 pytorch1.10、cuda11.3。&#xff08;2023-12-26&#xff09; 1、安装 conda 环境。 conda create --name detectron2 python3.8 2、安装 pytorch1.10 和 cuda11.3。 pip3 install torch1.10.0cu113 torchvision0.11.1cu113 torc…