一. ESR_ELn
1、ESR_ELn结构:
63 32 31 26 25 0 +--------------------+----------+----------------+ | RES0 | EC | ISS | +--------------------+----------+----------------+2.EC(Exception Class)
表示异常类别:
ARMv8-A 中ESR_ELn.EC(Exception Class,异常类别)用来描述“为什么进入异常处理”。它位于:共6 bit,可以表示 0~63 共 64 类异常。
| EC值 | 名称 | 说明 | 虚拟化常见场景 |
|---|---|---|---|
| 0x00 | Unknown reason | 未知异常 | 非法指令、未定义异常 |
| 0x01 | Trapped WFI/WFE | WFI/WFE 指令异常 | Guest 等待事件/空闲 |
| 0x03 | Trapped MCR/MRC (AArch32) | AArch32 CP15访问陷入 | 32位Guest访问系统寄存器 |
| 0x04 | Trapped MCRR/MRRC (AArch32) | AArch32双寄存器访问陷入 | 32位系统寄存器访问 |
| 0x05 | Trapped MCR/MRC (AArch32) | AArch32 CP访问 | 协处理器访问 |
| 0x06 | Trapped LDC/STC (AArch32) | Load/Store协处理器异常 | 较少使用 |
| 0x07 | Trapped access to SVE | SVE访问陷入 | 虚拟化SVE |
| 0x0E | Illegal Execution State | 非法执行状态 | CPU状态错误 |
| 0x11 | SVC instruction AArch32 | Supervisor Call | 系统调用 |
| 0x12 | HVC instruction AArch32 | Hypervisor Call | Guest调用Hypervisor |
| 0x13 | SMC instruction AArch32 | Secure Monitor Call | Secure Monitor调用 |
| 0x15 | SVC instruction AArch64 | AArch64系统调用 | Linux syscall |
| 0x16 | HVC instruction AArch64 | AArch64 Hypervisor Call | Guest→EL2通信 |
| 0x17 | SMC instruction AArch64 | Secure Monitor Call | EL3调用 |
| 0x18 | MSR/MRS access trap | 系统寄存器访问陷入 | Guest访问EL2控制寄存器 |
| 0x19 | SVE instruction trap | SVE指令异常 | SVE虚拟化 |
| 0x1C | Pointer Authentication trap | PAC异常 | 指针认证 |
| 0x20 | Instruction Abort from lower EL | 低异常级取指异常 | Guest代码访问异常 |
| 0x21 | Instruction Abort from same EL | 同级取指异常 | EL2自身异常 |
| 0x22 | PC alignment fault | PC未对齐 | 指令地址错误 |
| 0x24 | Data Abort from lower EL | 低异常级数据访问异常 | Guest访问MMIO/内存异常 |
| 0x25 | Data Abort from same EL | 同级数据访问异常 | EL2自身数据异常 |
| 0x26 | SP alignment fault | SP栈指针未对齐 | 栈错误 |
| 0x28 | FP/SIMD exception | 浮点异常 | FP虚拟化 |
| 0x2C | SError interrupt | 系统错误异常 | 硬件错误 |
| 0x2F | SError interrupt | 异步系统错误 | RAS错误处理 |
| 0x30 | Breakpoint from lower EL | Guest断点 | 调试 |
| 0x31 | Breakpoint from same EL | EL2断点 | Hypervisor调试 |
| 0x32 | Software Step exception | 单步调试 | Debug |
| 0x33 | Watchpoint from lower EL | Guest数据观察点 | 调试 |
| 0x34 | Watchpoint from same EL | EL2观察点 | 调试 |
| 0x35 | BKPT instruction AArch32 | 断点指令 | 32位调试 |
| 0x3C | BRK instruction AArch64 | AArch64断点 | 调试异常 |
/* ESR register */ #define ESR_EC_SHIFT (26UL) ///< The shift value for the "Exception Class" (EC) field within the ESR. #define ESR_EC_LEN (6UL) ///< The length (in bits) of the EC field in the ESR. #define ESR_ISS_OFF (0UL) ///< The offset for the "Exception Specific Syndrome" (ISS) field in the ESR. #define ESR_ISS_LEN (25UL) ///< The length (in bits) of the ISS field. #define ESR_IL_OFF (25UL) ///< The offset for the "Illegal Instruction" (IL) field in the ESR. It occupies bit position 25. #define ESR_IL_LEN (1UL) ///< The length (in bits) of the IL field, indicating whether the instruction was illegal. #define EC_UNKNOWN (0X00UL) ///< Unknown exception class. #define EC_WFE_WFI (0x01UL) ///< Exception class for WFE or WFI (Wait For Event/Interrupt) instructions. #define EC_CP15_MRC_MCR_32 (0x03UL) ///< CP15 MRC/MCR (32-bit), typically related to system control #define EC_CP15_MRRC_MCRR_32 (0x04UL) ///< CP15 MRRC/MCRR (32-bit), another type of system control exception. #define EC_CP14_MRC_MCR_32 (0x05UL) ///< CP14 MRC/MCR (32-bit), system control for ARMv7 or earlier. #define EC_FP_SIMD (0x07UL) ///< Floating-point and SIMD exception. #define EC_CP10_MRC_32 (0x08UL) ///< EL2 only #define EC_PAC (0x09UL) ///< EL2 and above #define EC_LD64B_ST64B (0x0AUL) ///< Exception class for load/store 64-byte instructions. #define EC_CP14_MRRC_MCRR_32 (0x0CUL) ///< CP14 MRRC/MCRR (32-bit), another type of exception. #define EC_BTI (0x0DUL) ///< BTI (Branch Target Indicator) exception. #define EC_ILLEGAL (0x0EUL) ///< Illegal exception class. #define EC_SVC32 (0x11UL) ///< Exception caused by the SVC (Supervisor Call) instruction in 32-bit mode. #define EC_HVC32 (0x12UL) ///< EL2 only #define EC_SMC32 (0x13UL) ///< EL2 and above #define EC_MSRR_MRRS_64 (0x14UL) ///< MSRR/MRRS (64-bit) exception. #define EC_SVC64 (0x15UL) ///< Exception caused by the SVC (Supervisor Call) instruction in 64-bit mode. #define EC_HVC64 (0x16UL) ///< EL2 and above #define EC_SMC64 (0x17UL) ///< EL2 and above #define EC_SYS64 (0x18UL) ///< System call exception in 64-bit mode. #define EC_SVE (0x19UL) ///< Exception caused by SVE (Scalable Vector Extension) instructions. #define EC_ERET (0x1AUL) ///< EL2 only #define EC_TME (0x1BUL) ///< TME (Transaction Manager Exception) exception. #define EC_FPAC (0x1CUL) ///< EL1 and above #define EC_SME (0x1DUL) ///< EL1 and above #define EC_RME (0x1EUL) ///< EL3 only #define EC_IMP_DEF (0x1FUL) ///< EL3 only #define EC_IABT_LOW (0x20UL) ///< Instruction Abort (Low Level) #define EC_IABT_CUR (0x21UL) ///< Instruction Abort (Current Level) #define EC_PC_ALIGN (0x22UL) ///< PC Alignment Exception (indicates a misaligned memory access) #define EC_DABT_LOW (0x24UL) ///< Data Abort (Low Level) #define EC_DABT_CUR (0x25UL) ///< Data Abort (Current Level) #define EC_SP_ALIGN (0x26UL) ///< Stack Pointer Alignment Exception #define EC_MOPS (0x27UL) ///< Memory Operations Exception (could represent some form of invalid memory access or operation) #define EC_FP_EXC32 (0x28UL) ///< Floating-Point Exception (32-bit precision) #define EC_FP_EXC64 (0x2CUL) ///< Floating-Point Exception (64-bit precision) #define EC_GCS_EXC (0x2DUL) ///< General Control Status Exception #define EC_SERROR (0x2FUL) ///< SError (System Error Exception, often associated with errors in the system) #define EC_BREAKPT_LOW (0x30UL) ///< Breakpoint (Low Level) #define EC_BREAKPT_CUR (0x31UL) ///< Breakpoint (Current Level) #define EC_SOFTSTP_LOW (0x32UL) ///< Software Step (Low Level) #define EC_SOFTSTP_CUR (0x33UL) ///< Software Step (Current Level) #define EC_WATCHPT_LOW (0x34UL) ///< Watchpoint (Low Level) #define EC_WATCHPT_CUR (0x35UL) ///< Watchpoint (Current Level) #define EC_BKPT32 (0x38UL) ///< Breakpoint (32-bit precision) #define EC_VECTOR32 (0x3AUL) ///< EL2 only #define EC_BKPT64 (0x3CUL) ///< Breakpoint (64-bit precision) #define EC_PMU_EXC (0x3DUL) ///< Performance Monitoring Unit Exception #define ESR_ISS_DA_DSFC_OFF (0UL) ///< The offset for the "Data Fault Status Code" (DSFC) in the ISS for a Data Abort (DA). #define ESR_ISS_DA_DSFC_LEN (6UL) ///< Length of the DSFC field, 6 bits. #define ESR_ISS_DA_WnR_BIT (1UL << 6) ///< A bit mask for the WnR field (bit 6). #define ESR_ISS_DA_FnV_BIT (1UL << 10) ///< Bitmask for the Function Not Valid (FnV) field #define ESR_ISS_DA_SF_OFF (15UL) ///< Offset for the Storage Fault (SF) field #define ESR_ISS_DA_SF_LEN (1UL) ///< Length of the Storage Fault (SF) field #define ESR_ISS_DA_SRT_OFF (16UL) ///< Offset for the Source Register (SRT) field #define ESR_ISS_DA_SRT_LEN (5UL) ///< Length of the Source Register (SRT) field #define ESR_ISS_DA_SSE_OFF (21UL) ///< Offset for the SSE (System Software Exception) field #define ESR_ISS_DA_SSE_LEN (1UL) ///< Length of the SSE (System Software Exception) field #define ESR_ISS_DA_SAS_OFF (22UL) ///< Offset for the SAS (System Address Space) field #define ESR_ISS_DA_SAS_LEN (2UL) ///< Length of the SAS (System Address Space) field #define ESR_ISS_DA_ISV_BIT (1UL << 24) ///< Bitmask for the Invalid Status Vector (ISV) field #define ESR_ISS_DA_DSFC_TRNSLT (0x4UL) ///< Translation fault. #define ESR_ISS_SYSREG_ADDR ((0xfffUL << 10) | (0xfUL << 1)) ///< The system register address mask. #define ESR_ISS_SYSREG_DIR (0x1UL) ///< The direction bit for system register access. #define ESR_ISS_SYSREG_REG_OFF (5UL) ///< The offset for the system register number. #define ESR_ISS_SYSREG_REG_LEN (5UL) ///< The length of the system register number field. #define ESR_ISS_SYSREG_REG2_OFF (10) #define ESR_ISS_SYSREG_REG2_LEN (5)3.ISS(Instruction Specific Syndrome,详细描述异常)
ISS(Instruction Specific Syndrome)用于提供异常相关的详细信息。
需要注意的是:
ISS 并不是固定格式,不同类型的异常(由 EC 字段决定)对应不同的 ISS 位域定义。
也就是说:
- EC 决定如何解释 ISS;
- ISS 提供该异常发生时的具体上下文信息。
例如:
- 当 EC = HVC Instruction 时,ISS 中保存 HVC 指令的立即数(Immediate Value);
- 当 EC = MSR/MRS Trap 时,ISS 中保存访问的系统寄存器编号;
- 当 EC = Data Abort 时,ISS 中保存访问方向、访问大小、访问寄存器以及 Fault 原因等信息。
在 ARMv8 虚拟化场景中,Data Abort 是 Hypervisor 最常处理的异常类型之一,尤其是在:
- Stage-2 地址转换失败;
- Guest 访问虚拟设备 MMIO;
- Guest 访问受保护内存区域;
等场景中,Hypervisor 都需要通过解析 Data Abort 对应的 ISS 来完成异常处理。
按照 Data Abort ISS 格式解析。
其主要字段如下:
Data Abort ISS 31 25 24 23:22 21 20 16 15 10 9 5 4 0 +----------------+----+------+---+----+----------+-------+--------+ | RES0 |ISV | SAS |SSE| SRT| ... | AR | DFSC | +----------------+----+------+---+----+----------+-------+--------+(1)DFSC(Data Fault Status Code)
位置:
ISS[5:0]作用:
描述数据访问失败的具体原因。
常见类型:
| DFSC类型 | 含义 | 虚拟化场景 |
|---|---|---|
| Translation Fault | 地址转换失败 | Guest访问未映射的Stage-2地址 |
| Permission Fault | 权限错误 | Guest访问只读区域 |
| Access Flag Fault | 访问标志错误 | 页表AF位未设置 |
| Alignment Fault | 地址未对齐 | 非对齐访问 |
(2)WnR(Write not Read)
位置:
ISS[6]作用:
判断异常访问是读操作还是写操作。
| 值 | 含义 |
|---|---|
| 0 | Read |
| 1 | Write |
(3)SAS(Size of Access)
位置:
ISS[23:22]作用:
描述触发异常的访问数据大小。
编码:
| SAS | 访问大小 |
|---|---|
| 00 | Byte (8 bit) |
| 01 | Half-word (16 bit) |
| 10 | Word (32 bit) |
| 11 | Double-word (64 bit) |
(4)SRT(Syndrome Register Transfer)
位置:
ISS[20:16]作用:
指示发生异常的数据访问使用了哪个通用寄存器。
(5)ISV(Instruction Syndrome Valid)
位置:
ISS[24]作用:
表示 ISS 中是否包含有效的指令访问信息。
当:
ISV = 1(6)SF(Sixty-Four bit Register Transfer)
作用:
表示访问数据宽度:
| SF | 含义 |
|---|---|
| 0 | 32-bit访问 |
| 1 | 64-bit访问 |
二、FAR_ELn(Fault Address Register)
1. FAR_ELn
Fault Address Register(故障地址寄存器),ARMv8 为每个异常级维护对应的 FAR 寄存器:
FAR_EL1 FAR_EL2 FAR_EL3其中:
- FAR_EL1:记录进入 EL1 异常处理时的故障地址;
- FAR_EL2:记录进入 EL2 异常处理时的故障地址;
- FAR_EL3:记录进入 EL3 异常处理时的故障地址。
2、HPFAR_EL2(Hypervisor IPA Fault Address Register)
这里需要特别说明:HPFAR 不是所有 EL 都有,而是 ARMv8 虚拟化扩展提供给 EL2 使用的寄存器。
它的作用是在stage2地址翻译时故障记录IPA(中间物理地址)。