异常向量与VBAR_ELx:Linux entry.S 中的vectors 布局

当 CPU 发生同步异常、IRQ、FIQ 或 SError 时,硬件根据当前异常级别(EL)和异常类型,跳转到 VBAR_ELx 指向的向量表条目。Linux 内核在 entry.S 中构造这张表,并在 setup_arch 早期通过 cpu_setup() 把物理地址写入 VBAR_EL1。理解 vectors 的分区与 kernel_ventry 宏,是分析缺页、系统调用、中断入口的第一把钥匙------本文聚焦向量表本身,不重复 EL 权限模型与 head.S 早期启动流程。

源码锚点

路径 作用
arch/arm64/kernel/entry.S vectors 表、kernel_ventrykernel_entry
arch/arm64/kernel/entry-common.c C 侧异常处理、do_el0_svc
arch/arm64/kernel/traps.c 非法指令、undef、panic 路径
arch/arm64/kernel/irq.c handle_arch_irq 函数指针
arch/arm64/kernel/setup.c cpu_setup() 设置 VBAR
arch/arm64/include/asm/exception.h struct pt_regs、异常帧布局

向量表主体(每个 slot 128 字节对齐):

asm 复制代码
/* arch/arm64/kernel/entry.S */
	.align	11
ENTRY(vectors)
	kernel_ventry	1, sync_invalid			// Synchronous EL1t
	kernel_ventry	1, irq_invalid			// IRQ EL1t
	kernel_ventry	1, fiq_invalid			// FIQ EL1t
	kernel_ventry	1, error_invalid		// Error EL1t

	kernel_ventry	1, sync				// Synchronous EL1h
	kernel_ventry	1, irq				// IRQ EL1h
	kernel_ventry	1, fiq				// FIQ EL1h
	kernel_ventry	1, error			// Error EL1h

	kernel_ventry	0, sync				// Synchronous 64-bit EL0
	kernel_ventry	0, irq				// IRQ 64-bit EL0
	kernel_ventry	0, fiq				// FIQ 64-bit EL0
	kernel_ventry	0, error			// Error 64-bit EL0

kernel_ventry 在栈上分配 struct pt_regs 并保存通用寄存器:

asm 复制代码
	.macro kernel_ventry, el, label, regsize = 64
	.align 7
.Lventry_start\@:
	sub	sp, sp, #S_FRAME_SIZE
	/* 保存 x0-x29、lr、elr_el1、spsr_el1 等到 pt_regs */
	b	\label
	.endm

VBAR 安装(每 CPU 在 bring-up 时执行):

c 复制代码
/* arch/arm64/kernel/setup.c --- cpu_setup 概念路径 */
void __init cpu_setup(char *fdt)
{
	/* ... */
	write_sysreg((u64)vectors, vbar_el1);
	isb();
}

EL0 系统调用从 sync 向量进入 el0_svc_common

asm 复制代码
/* entry.S --- el0_svc 附近 */
el0_svc:
	adrp	x16, vectors
	b	el0_svc_common

调用链

text 复制代码
硬件异常(例:EL0 发 svc #0)
  → PC 跳至 VBAR_EL1 + offset(EL0 sync slot)
      → kernel_ventry 0, sync
          → 构造 pt_regs,b el0_sync
              → el0_svc / el0_da / el0_ia / el0_ti ...
                  → do_el0_svc(regs)     /* 系统调用 */
                  → do_mem_abort()       /* 缺页/权限 fault */
              → ret_to_user → eret

硬件 IRQ(EL0/EL1)
  → vectors → kernel_ventry → el0_irq / el1_irq
      → enter_el1_irq_or_nmi
          → irq_handler(regs)
              → handle_arch_irq(regs)   /* 由 GIC driver 注册 */
                  → generic_handle_domain_irq()
              → irq_exit()
          → ret_to_user / ret_to_kernel

VBAR 变更场景:

text 复制代码
cpu_startup_entry() / secondary_start_kernel()
  → cpu_setup() 或 smp 路径再次确认 vbar_el1
KVM/VHE:host 可能在 EL2 使用 vbar_el2(与本篇 EL1 Linux 主路径分离)

重点知识

16 个向量 slot: AArch64 规定每个异常类型 ×(当前 EL + SP 选择)共 16 组入口;Linux 主要使用 EL1h(内核用 SP_EL1)与 EL0(用户态)四组;EL1t 多为 *_invalid 陷阱误用 SP_EL0 的内核代码。

128 字节对齐: 每条 kernel_ventry 占 128 字节(.align 7),便于 VBAR 基址低 11 位为零;修改向量表需保证链接脚本不把 vectors 拆散。

pt_regseret 异常返回依赖 elr_el1(返回 PC)与 spsr_el1(返回 PSTATE);内核 patch 这些字段可实现信号 delivery、ptrace 单步。

IRQ 与 preempt: el0_irq 路径在 irq_exit() 中检查 TIF_NEED_RESCHED;理解向量入口栈(sync 用 task 内核栈 vs IRQ stack)对 lockdep 与 stack overflow 排障至关重要。

SError: error 向量处理异步外部 abort(如 AXI 错误);未注册 handler 时可能 panic;设备驱动 DMA 错误有时经此上报。

与 VBAR_EL3 区别: TF-A BL31 在 EL3 有自己的 vbar_el3 处理 SMC;Linux 运行在 EL1,仅写 vbar_el1。EL2 存在时(KVM nVHE)另有独立向量表。

调试: crashdis vectors;ftrace function_graphel0_svc 跟踪;/proc/kallsymsvectors 符号地址应与 VBAR_EL1 一致。

Checklist

  • VBAR_EL1 指向 vectors 符号,16 组入口地址随内核版本与配置(KASLR)变化
  • 用户 syscall、缺页、IRQ 分别对应 EL0 sync/irq 路径,而非 EL1t invalid
  • 修改 entry.S 后检查 128 字节对齐与 S_FRAME_SIZE 栈布局
  • IRQ 处理经 handle_arch_irq,与 GICv3 驱动注册一致
  • SError 路径有平台 arm64_serror_panic 或自定义 handler
  • secondary CPU 启动后 VBAR 与 primary 一致,无旧 Bootloader 残留
相关推荐
BlueAsia_Lab17 分钟前
华为 SuperCharge 认证,覆盖哪些产品?全品类梳理
运维·服务器·华为
H_oRIZoN_18 分钟前
Linux入门DAY32(文件 IO、进程、线程、IPC 通信)
linux·运维·服务器
0+11119 分钟前
Linux --Ext系列文件系统
linux·运维·服务器
Yang961124 分钟前
一台顶三台:鼎讯DLJ-1在不同故障类型中的模式切换数据复盘
服务器·网络·数据库
潘正翔29 分钟前
Memcached构建缓存服务器
运维·服务器·数据库·缓存·云原生·memcached
醉颜凉1 小时前
Elasticsearch服务器部署:从零到一完整启动+配置教程
大数据·服务器·elasticsearch
攻城有术1 小时前
专项攻克——研发排查Linux各类问题命令+实战案例
linux·运维·服务器
自动化和Linux2 小时前
【win11+virtual Box简单安装centos7,不使用GPT分区】
linux·gpt·虚拟现实
Acrellea2 小时前
当机柜功率冲向 50kW,配电运维如何跟上算力的进化速度?
大数据·运维