我得到了一个内核BUG,我不知道为什么会触发它。
[ 242.337362] kernel BUG at arch/x86/kernel/cpu/mce/core.c:1364!
[ 242.337366] invalid opcode: 0000 [#1] SMP NOPTI
这是在x86_64上的CentOS 8.5内核4.18.0-348.el8.x86_64。
核心.c线1364是:
nmi_exit();
(上一行在do_machine_check()
内(:
通过检查nmi_exit()
https://elixir.bootlin.com/linux/v4.18/source/include/linux/hardirq.h#L78
#define nmi_exit()
do {
trace_hardirq_exit();
rcu_nmi_exit();
BUG_ON(!in_nmi());
preempt_count_sub(NMI_OFFSET + HARDIRQ_OFFSET);
ftrace_nmi_exit();
lockdep_on();
printk_nmi_exit();
} while (0)
看起来我击中了这个BUG_ON(!in_nmi());
,但我检查了do_machine_check()
,它应该仍然是in_nmi
(因为第1255行是nmi_enter();
(,为什么BUG_ON(!in_nmi());
被触发?
其他:
- 以下是可在centos4.18内核中下载的源代码:
https://vault.centos.org/8.5.2111/BaseOS/Source/SPackages/kernel-4.18.0-348.el8.src.rpm
我得到了一个内核BUG,我不知道为什么会触发它?
您遇到的特定错误试图使用无效的操作码:0000[#1]SMP NOPTI。
我将讨论这个问题,它的原因,以及如何解决这个问题。首先,我将定义一些术语。
什么是不可屏蔽中断(NMI(
NMI是一种硬件中断,不受操作系统启用的任何中断屏蔽的影响(例如,CentOS 8.5(。在几乎所有情况下,它都是对不可恢复的硬件错误的响应。
NMI的一些典型用途是什么1
- 低级调试,例如早期的Apple Macintosh的";程序员按钮">
- ECC内存奇偶校验错误超出了可以纠正的范围,可能会使系统停止运行
- 即将到来的厄运,如突然失去使系统静止的电源
- 如果错过了硬件看门狗定时器,则按常规启用硬件看门狗计时器以使其死机
在处理第一个NMI时,第二个NMI会到达吗
从我记事起,Linux就一直支持英特尔嵌套NMI。2012年,Intel嵌套NMI支持中的一个漏洞令人兴奋。英特尔存在NMI iret缺陷,该缺陷要求NMI处理程序在处理NMI时避免触发页面错误或断点。
2020年5月20日,ARM64和PowerPC中对nest NMI的支持被承诺用于Linux。
BUG_ON((的确切作用是什么
在Linux 2.6中启动BUG_ON((是在出现严重错误时调试宏。如果传递给宏的值为true,那么Linux内核将触发无效指令。这导致CPU抛出一个无效的操作码异常。通常情况下,如果在一个过程中发生这种情况,该过程就会死亡。如果这种情况发生在NMI期间,情况会严重得多。
BUG_ON(!in_nmi(((转换为BUG_ON
因此,in_nmi((是检查当前nmi的当前抢占位是否设置为true。
什么是NOPTI2
Linux使用它来禁用Meltdown(内核页面表隔离(缓解措施。通常,nopti被添加到内核引导选项中以禁用。
补救措施
如果是软件,我该怎么办最有可能
- 如果当前已禁用,请尝试在启用Meltdown的情况下启动系统。或者在禁用的情况下启动(如果启用(
- 如果可能,请将Linux升级至5.4.100或更高版本。英特尔Icelake发布前2年报告的一个错误示例
- 迁移到AlmaLinux或Rocky Linux,CentOS 8.5的精神继承者
如果是硬件缺陷呢可能性较小
- 一次更换一个(在与系统逻辑板兼容的配置中(,直到找到有缺陷的
- 更换系统逻辑板和/或其他PCIe设备
TL;DR
这个问题的一个有效理论是,NMI是由未校正的硬件内存错误引起的,而编码错误造成了在第二个增量增加了preempt_counter之前检查BUG_ON(!in_NMI(((的情况。
在这种特殊情况下,原始海报使用einj_mem_uc工具来生成模拟内存错误。这启动了NMI。