1.SError定义
本段解释来自来自arm官网,截图如下:
翻译如下:
System Error (SError) 是一种异常类型,旨在由内存系统响应意外事件而生成。我们不期望发生这些事件,但需要知道它们是否发生。这些异常是异步报告的,因为触发事件的指令可能已经执行完成。
SError 的典型示例是先前称为外部异步中止的情况。SError 中断的示例包括:
- 内存访问通过所有MMU检查,但然后在内存总线上遇到错误
- 对某些RAM进行奇偶校验或错误纠正码(ECC)检查,例如内置缓存中的RAM
- 由缓存行中的脏数据写回到外部存储器触发的中止
SError 被视为一种单独的异步异常类别,因为通常针对这些情况会有单独的处理程序。SError 的生成是实现定义的。
2.SError的处理
Linux内核中,对SError进行了捕获,设置了相应的中断向量,当并未做实际的处理,只是上报异常,并终止内核,因为对于内核来说,SError是致命的,内核自身不知道具体原因,也不知道如何修复。
SYM_CODE_START_LOCAL(el1_error)
kernel_entry 1
mrs x1, esr_el1
enable_dbg
mov x0, sp
bl do_serror
kernel_exit 1
SYM_CODE_END(el1_error)
在do_serror跳转到arm64_serror_panic
asmlinkage void noinstr do_serror(struct pt_regs *regs, unsigned int esr)
{
arm64_enter_nmi(regs);
/* non-RAS errors are not containable */
if (!arm64_is_ras_serror(esr) || arm64_is_fatal_ras_serror(regs, esr))
arm64_serror_panic(regs, esr);
arm64_exit_nmi(regs);
}
最终,dump出所有regs的值,然后产生panic,最后进入wfe或者wfi状态。
void __noreturn arm64_serror_panic(struct pt_regs *regs, u32 esr)
{
console_verbose();
pr_crit("SError Interrupt on CPU%d, code 0x%08x -- %s\n",
smp_processor_id(), esr, esr_get_class_string(esr));
if (regs)
__show_regs(regs);//dump下来所有寄存器的值
nmi_panic(regs, "Asynchronous SError Interrupt");
cpu_park_loop();//通过wfe和wfi指令,让当前cpu进入low-power standby模式
unreachable();//无法到达这里
}