arm64异常向量表

news2024/12/27 14:38:06

arm64异常向量表

  • 1 arm64异常向量表
  • 2 linux arm64异常向量表
  • 3 kernel_ventry宏
  • 4 异常向量表的保存
    • 4. VBAR_ELx寄存器
    • 4.2 __primary_switched
    • 4.3 __primary_switched

1 arm64异常向量表

在这里插入图片描述
When an exception occurs, the processor must execute handler code which corresponds to the exception. The location in memory where the handler is stored is called the exception vector. In the ARM architecture, exception vectors are stored in a table, called the exception vector table. Each Exception level has its own vector table, that is, there is one for each of EL3, EL2 and EL1. The table contains instructions to be executed, rather than a set of addresses. Vectors for individual exceptions are located at fixed offsets from the beginning of the table. The virtual address of each table base is set by the Vector Based Address Registers VBAR_EL3, VBAR_EL2 and VBAR_EL1.
Each entry in the vector table is 16 instructions long. This in itself represents a significant change compared to ARMv7, where each entry was 4 bytes. This spacing of the ARMv7 vector table meant that each entry would almost always be some form of branch to the actual exception handler elsewhere in memory. In AArch64, the vectors are spaced more widely, so that the
top-level handler can be written directly in the vector table.
The base address is given by VBAR_ELn and then each entry has a defined offset from this base address. Each table has 16 entries, with each entry being 128 bytes (32 instructions) in size. The table effectively consists of 4 sets of 4 entries.
Which entry is used depends upon a number of factors:

  • 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 SPx)
  • If the exception is being taken at a lower Exception level, the execution state of the next lower level (AArch64 or AArch32)
    Considering an example might make this easier to understand.
    If kernel code is executing at EL1 and an IRQ interrupt is signaled, an IRQ exception occurs. This particular interrupt is not associated with the hypervisor or secure environment and is also handled within the kernel, also at SP_EL1, and the SPSel bit is set, so you are using SP_EL1. Execution is therefore from address VBAR_EL1 + 0x280.
    In the absence of LDR PC, [PC, #offset] in the ARMv8-A architecture, you must use more instructions to enable the destination to be read from a table of registers. The choice of spacing of the vectors is designed to avoid cache pollution for typical sized instruction cache lines from vectors that are not being used. The Reset Address is a completely separate address, which is
    IMPLEMENTATION DEFINED, and is typically set by hardwired configuration within the core. This address is visible in the RVBAR_EL1/2/3 register.
    Having a separate exception vector for each exception, either from the current Exception level or from the lower Exception level, gives the flexibility for the OS or hypervisor to determine the AArch64 and AArch32 state of the lower Exception levels. The SP_ELn is used for exceptions generated from lower levels. However, the software can switch to use SP_EL0 inside the
    handler. When you use this mechanism, it facilitates access to the values from the thread in the handler.

2 linux arm64异常向量表

/*                          
 * Exception vectors.       
 */                         
        .pushsection ".entry.text", "ax" 
                               
        .align  11          
SYM_CODE_START(vectors)    
        kernel_ventry   1, t, 64, sync          // Synchronous EL1t 
        kernel_ventry   1, t, 64, irq           // IRQ EL1t 
        kernel_ventry   1, t, 64, fiq           // FIQ EL1t 
        kernel_ventry   1, t, 64, error         // Error EL1t 
                               
        kernel_ventry   1, h, 64, sync          // Synchronous EL1h 
        kernel_ventry   1, h, 64, irq           // IRQ EL1h 
        kernel_ventry   1, h, 64, fiq           // FIQ EL1h 
        kernel_ventry   1, h, 64, error         // Error EL1h 
                            
        kernel_ventry   0, t, 64, sync          // Synchronous 64-bit EL0
        kernel_ventry   0, t, 64, irq           // IRQ 64-bit EL0
        kernel_ventry   0, t, 64, fiq           // FIQ 64-bit EL0
        kernel_ventry   0, t, 64, error         // Error 64-bit EL0                                                                                                                                        
                            
        kernel_ventry   0, t, 32, sync          // Synchronous 32-bit EL0
        kernel_ventry   0, t, 32, irq           // IRQ 32-bit EL0
        kernel_ventry   0, t, 32, fiq           // FIQ 32-bit EL0
        kernel_ventry   0, t, 32, error         // Error 32-bit EL0
SYM_CODE_END(vectors)
  • .pushsection “.entry.text”, “ax” 表示要将当前的异常向量表放到.entry.text段,属性为"ax"
  • .align 11表示异常向量表的起始地址要2K对齐(2^11 = 2048),这和VBAR_ELx的寄存器定义是一致的。
  • SYM_CODE_START(vectors) 声明异常向量表

3 kernel_ventry宏

  • kernel_ventry是异常向量表的一部分通用处理宏,会依据参数跳转到不同的异常处理函数,对于kernel_ventry 1, h, 64, irq,则会跳转到el1h_64_irq处理函数流程中。
  • .align 7 表示当前的入口要按照128B对齐的方式去存放,这和异常向量表每个entry的大小为128B是匹配的
	.macro kernel_ventry, el:req, ht:req, regsize:req, label:req
	.align 7
.Lventry_start\@:
	.if	\el == 0
	/*
	 * This must be the first instruction of the EL0 vector entries. It is
	 * skipped by the trampoline vectors, to trigger the cleanup.
	 */
	b	.Lskip_tramp_vectors_cleanup\@
	.if	\regsize == 64
	mrs	x30, tpidrro_el0
	msr	tpidrro_el0, xzr
	.else
	mov	x30, xzr
	.endif
.Lskip_tramp_vectors_cleanup\@:
	.endif

	sub	sp, sp, #PT_REGS_SIZE
#ifdef CONFIG_VMAP_STACK
	/*
	 * Test whether the SP has overflowed, without corrupting a GPR.
	 * Task and IRQ stacks are aligned so that SP & (1 << THREAD_SHIFT)
	 * should always be zero.
	 */
	add	sp, sp, x0			// sp' = sp + x0
	sub	x0, sp, x0			// x0' = sp' - x0 = (sp + x0) - x0 = sp
	tbnz	x0, #THREAD_SHIFT, 0f
	sub	x0, sp, x0			// x0'' = sp' - x0' = (sp + x0) - sp = x0
	sub	sp, sp, x0			// sp'' = sp' - x0 = (sp + x0) - x0 = sp
	b	el\el\ht\()_\regsize\()_\label

0:
	/*
	 * Either we've just detected an overflow, or we've taken an exception
	 * while on the overflow stack. Either way, we won't return to
	 * userspace, and can clobber EL0 registers to free up GPRs.
	 */

	/* Stash the original SP (minus PT_REGS_SIZE) in tpidr_el0. */
	msr	tpidr_el0, x0

	/* Recover the original x0 value and stash it in tpidrro_el0 */
	sub	x0, sp, x0
	msr	tpidrro_el0, x0

	/* Switch to the overflow stack */
	adr_this_cpu sp, overflow_stack + OVERFLOW_STACK_SIZE, x0

	/*
	 * Check whether we were already on the overflow stack. This may happen
	 * after panic() re-enables interrupts.
	 */
	mrs	x0, tpidr_el0			// sp of interrupted context
	sub	x0, sp, x0			// delta with top of overflow stack
	tst	x0, #~(OVERFLOW_STACK_SIZE - 1)	// within range?
	b.ne	__bad_stack			// no? -> bad stack pointer

	/* We were already on the overflow stack. Restore sp/x0 and carry on. */
	sub	sp, sp, x0
	mrs	x0, tpidrro_el0
#endif
	b	el\el\ht\()_\regsize\()_\label
.org .Lventry_start\@ + 128	// Did we overflow the ventry slot?
	.endm

4 异常向量表的保存

异常向量表的保存分为两个部分,一个是主核的启动流程,另一个是副核的启动流程处理的。其处理函数分别为__primary_switched和__primary_switched

4. VBAR_ELx寄存器

VBAR_EL1, Vector Base Address Register (EL1),Holds the vector base address for any exception that is taken to EL1.
在这里插入图片描述

  • Bits [63:11]
    • Vector Base Address. Base address of the exception vectors for exceptions taken to EL1.
    • If the implementation does not support ARMv8.2-LVA, then:
      • If tagged addresses are being used, bits [55:48] of VBAR_EL1 must be the same or else the use of the vector address will result in a recursive exception.
      • If tagged addresses are not being used, bits [63:48] of VBAR_EL1 must be the same or else the use of the vector address will result in a recursive exception.
    • If the implementation supports ARMv8.2-LVA, then:
      • If tagged addresses are being used, bits [55:52] of VBAR_EL1 must be the same or else the use of the vector address will result in a recursive exception.
      • If tagged addresses are not being used, bits [63:52] of VBAR_EL1 must be the same or else the use of the vector address will result in a recursive exception.
        其访问方式如下所示:
  • MRS , VBAR_EL1 读取VBAR_EL1寄存器中保存的异常向量表地址到xt寄存器中
  • MSR VBAR_EL1, 将xt寄存器中保存的异常向量表地址写入VBAR_EL1寄存器中。

4.2 __primary_switched

对于主核的启动流程来说,其处理是如下两步,首先将vectors地址加载到x8寄存器中,随后通过msr指令,将其值写入vbar_el1寄存器中。

  • adr_l x8, vectors // load VBAR_EL1 with virtual
  • msr vbar_el1, x8 // vector table address
/*
 * The following fragment of code is executed with the MMU enabled.
 *
 *   x0 = __pa(KERNEL_START)
 */
SYM_FUNC_START_LOCAL(__primary_switched)
	adr_l	x4, init_task
	init_cpu_task x4, x5, x6

	adr_l	x8, vectors			// load VBAR_EL1 with virtual
	msr	vbar_el1, x8			// vector table address
	isb

	stp	x29, x30, [sp, #-16]!
	mov	x29, sp

	str_l	x21, __fdt_pointer, x5		// Save FDT pointer

	ldr_l	x4, kimage_vaddr		// Save the offset between
	sub	x4, x4, x0			// the kernel virtual and
	str_l	x4, kimage_voffset, x5		// physical mappings

	mov	x0, x20
	bl	set_cpu_boot_mode_flag

	// Clear BSS
	adr_l	x0, __bss_start
	mov	x1, xzr
	adr_l	x2, __bss_stop
	sub	x2, x2, x0
	bl	__pi_memset
	dsb	ishst				// Make zero page visible to PTW

#if VA_BITS > 48
	adr_l	x8, vabits_actual		// Set this early so KASAN early init
	str	x25, [x8]			// ... observes the correct value
	dc	civac, x8			// Make visible to booting secondaries
#endif

#ifdef CONFIG_RANDOMIZE_BASE
	adrp	x5, memstart_offset_seed	// Save KASLR linear map seed
	strh	w24, [x5, :lo12:memstart_offset_seed]
#endif
#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
	bl	kasan_early_init
#endif
	mov	x0, x21				// pass FDT address in x0
	bl	early_fdt_map			// Try mapping the FDT early
	mov	x0, x20				// pass the full boot status
	bl	init_feature_override		// Parse cpu feature overrides
	mov	x0, x20
	bl	finalise_el2			// Prefer VHE if possible
	ldp	x29, x30, [sp], #16
	bl	start_kernel
	ASM_BUG()
SYM_FUNC_END(__primary_switched)

4.3 __primary_switched

对于副核的启动流程来说,其处理是如下两步,首先将vectors地址加载到x5寄存器中,随后通过msr指令,将其值写入vbar_el1寄存器中。

  • adr_l x5, vectors
  • msr vbar_el1, x5
SYM_FUNC_START_LOCAL(__secondary_switched)
	mov	x0, x20
	bl	set_cpu_boot_mode_flag
	str_l	xzr, __early_cpu_boot_status, x3
	adr_l	x5, vectors
	msr	vbar_el1, x5
	isb

	adr_l	x0, secondary_data
	ldr	x2, [x0, #CPU_BOOT_TASK]
	cbz	x2, __secondary_too_slow

	init_cpu_task x2, x1, x3

#ifdef CONFIG_ARM64_PTR_AUTH
	ptrauth_keys_init_cpu x2, x3, x4, x5
#endif

	bl	secondary_start_kernel
	ASM_BUG()
SYM_FUNC_END(__secondary_switched)

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

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

相关文章

电力系统谐波影响及治理

1.谐波 众所周知&#xff0c;理想的电力系统向用户提供的是一个恒定工频的正弦波形电压&#xff0c;但是由于各种原因&#xff0c;使这种理想状态在实际中无法存在。当正弦波电压施加在非线性电路上时&#xff0c;电流就变成非正弦波&#xff0c;非正弦电流在电网阻抗上产生压…

机器学习:基于逻辑回归和高斯贝叶斯对人口普查数据集的分类与预测

机器学习:基于逻辑回归和高斯贝叶斯对人口普查数据集的分类与预测作者:i阿极 作者简介:Python领域新星作者、多项比赛获奖者:博主个人首页 😊😊😊如果觉得文章不错或能帮助到你学习,可以点赞👍收藏📁评论📒+关注哦!👍👍👍 📜📜📜如果有小伙伴需要…

【python】采集每日必看黄色软件数据~

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 环境使用: Python 3.8 Pycharm 模块使用: requests >>> pip install requests re csv 安装模块&#xff1a;win R 输入cmd 输入安装命令 pip install 模块名 如果出现爆红 可能是因为 网络连接超时 切换国内…

【云原生】Dockerfile制作WordPress镜像,实现compose编排部署

文章目录 &#x1f479; 关于作者前言环境准备目录结构 dockerfile制作镜像yum 脚本Dockerfile-mariadb 镜像Dockerfile-service 镜像docker compose 编排 提升✊ 最后 &#x1f479; 关于作者 大家好&#xff0c;我是秋意临。 &#x1f608; CSDN作者主页 &#x1f60e; 博客…

谷歌Colab云端部署Stable Diffusion 进行绘图

系列文章目录 本地部署Stable Diffusion教程&#xff0c;亲测可以安装成功 Stable Diffusion界面参数及模型使用 文章目录 系列文章目录前言一、Colab是什么&#xff1f;二、操作步骤1.找到对应的脚本2.在谷歌Colab里执行脚本3.装载想要的模型4.开始绘图 前言 在之前的博客里…

设计模式:创建者模式 - 工厂模式

文章目录 1.概述2.简单工厂模式&#xff08;非23种&#xff09;2.1 结构2.2 实现2.3 优缺点2.4 扩展 3.工厂方法模式3.1 概念3.2 结构3.3 实现3.4 优缺点 4.抽象工厂模式4.1 概念4.2 结构4.3 实现4.4 优缺点4.5 使用场景 5.模式扩展6.JDK源码解析-Collection.iterator方法 1.概…

【Linux】线程安全——补充|互斥、锁|同步、条件变量

文章目录 一、知识补充线程的ID局部存储验证Thread.hpp——线程的封装 二、线程安全问题三、Linux线程互斥互斥相关概念互斥量mutexmutex的使用全局锁的使用局部锁的使用 mutex的理解Mutex.hpp——mutex的封装可重入VS线程安全死锁 四、Linux线程同步条件变量条件变量接口理解条…

工序流转二维码的应用和制作方法

很多中小型生产企业还在使用纸制的“工序流转卡”&#xff0c;每天交给专员人工录入到电脑上&#xff0c;不仅费时费力&#xff0c;还容易出错&#xff0c;更重要的是管理员不能实时掌握各个订单的进展情况&#xff0c;因此经常会发生订单延期交付的情况&#xff0c;给企业带来…

centos7.9系统部署NFS详细流程—2023.04

文章目录 NFS与RPC关系前提关闭防火墙和selinux安装 NFS 和 RPC测试取消挂载 NFS与RPC关系 简单点可以这么理解&#xff0c;RPC和NFS的关系&#xff1a;NFS是一个文件系统&#xff0c;而RPC是负责负责信息的传输。 NFS&#xff08;Network File System&#xff09;即网络文件…

Python数据分析项目实战

现成案例分享 Python数据分析&#xff1a;股票数据分析案例 步骤&#xff1a; 准备数据可视化数据、审查数据处理数据根据ACF、PACF定阶拟合ARIMA模型预测 作者&#xff1a;python分享站 链接&#xff1a;https://www.zhihu.com/question/280744341/answer/1651341817 来源&…

Windows下载redis

下载微软的 Redis和配置 Windows下载redis1&#xff0c;下载redis2&#xff0c;解压压缩包3&#xff0c;启动Redis临时服务4&#xff0c;启动Redis客户端测试连接5, Redis配置 &#xff08;可选&#xff09;1&#xff0c; 配置系统环境变量2&#xff0c;添加Redis服务3&#xf…

数据结构——排序(5)

作者&#xff1a;几冬雪来 时间&#xff1a;2023年4月14日 内容&#xff1a;数据结构排序内容讲解 目录 前言&#xff1a; 1.非递归归并排序&#xff1a; 2.越界情况&#xff1a; 3.计数排序&#xff1a; 结尾&#xff1a; 前言&#xff1a; 在上一篇博客中我们对归…

硬件语言Verilog HDL牛客刷题day10 华W部分 和 DJ部分

1. VL63 并串转换 1.题目&#xff1a; 设计一个模块进行并串转换&#xff0c;要求每四位d输为转到一位dout输出&#xff0c;输出valid_in表示此时的输入有效。 2.解题思路 2.1 计数记录输出的位数。 2.2 数据 有一个延时。 2.3 思路就是 搞一个寄存器存储数据&#xff0c;然后…

【蓝桥系列】为什么不会「输入输出」,你一道题都做不出来?(输入输出模板)

欢迎各位旅行者&#xff0c;来到小蓝の蓝桥城&#xff01; 全文目录 &#x1f4d6;第一幕 「藏宝地图」 &#x1f33c; 输入 &#x1f331;输入一行 &#x1f331;输入多行 &#x1f33c; 输出 &#x1f331;输出 一个数 &#x1f331;输出 一维列表 &#x1f331;输出…

TCP知识

计算机网络模型 OSC(Open System Interconnect)采用分层的结构化技术&#xff0c;共分七层&#xff1a;物理层&#xff0c;数据链路层&#xff0c;网络层&#xff0c;传输层&#xff0c;会话层&#xff0c;表示层&#xff0c;应用层。 TCP/IP模型共分四层&#xff1a;链路层&…

干货分享 | 图解如何写出优秀的项目总结?

不论是公司&#xff0c;还是个人&#xff0c;要不断地提升&#xff0c;就要不断地进行总结与改进&#xff0c;再总结再改进&#xff0c;如此循环&#xff0c;通过不断地总结与改进&#xff0c;改善我们的工作方法、优化工作流程、提升工作效率。 ​这就是PDCA基本思路&#xf…

ROS 教程之 vision : 用笔记本摄像头获取图像

如何用笔记本自带的摄像头采集图像 尝试一&#xff1a;安装Webcam 驱动 参考 大神白巧克力亦唯心博客&#xff1a; 链接: ROS 教程之 vision : 用各种摄像头获取图像. sudo apt-get install git-core cd ~/catkin_ws/src #catkin_ws/src对应你自己建立的catkin工作空间…

区间动态规划

区间DP 石子合并&#xff1a;前缀和动态规划最长合法子序列环形石子合并石子合并 II城镇国王超级括号序列炸弹人 区间DP&#xff1a; 状态&#xff1a;区间左右端点 dp[i][j]阶段&#xff1a;区间长度转移&#xff1a;由外到内 石子合并&#xff1a;前缀和动态规划 问题特征&…

第3章 数据科学的5个步骤

第3章 数据科学的5个步骤 文章目录 第3章 数据科学的5个步骤3.1 数据科学简介3.2 5个步骤概览3.2.1 提出有意思的问题3.2.2 获取数据3.2.3 探索数据3.2.4 数据建模3.2.5 可视化和分享结果3.3.1 数据探索的基本问题3.3.2 数据集1&#xff1a;Yelp点评数据DataFrameSeries定性数据…

Steam无法载入网页 - 解决方案

前言 用户在使用Steam客户端时经常会遇到无法载入网页的情况&#xff0c;如下图。下文介绍解决方案。 解决方案 检查防火墙 打开Windows设置&#xff0c;选择更新和安全&#xff0c;选择Windows安全中心 - 防火墙和网络保护&#xff0c;如下图&#xff1a; 点击允许应用通…