新系统跑不起来,报 “CPU does not support x86-64-v2”,根因是现代 OS 默认按较新指令集编译,而默认的 qemu64 模型只提供最基础指令。给虚拟机配上合适的 CPU 指令集就能解决。
现象
一台 primusos2403sp1x64 的虚拟机,没有配置 CPU 指令集的情况下,运行僵死。配置指令集后,就能正常运行了。
排查
用 virsh reset vm-example && virsh console vm-example 可以看到 glibc 打印的错误:
[ 1.536627][ T1] Run /init as init process
Fatal glibc error: CPU does not support x86-64-v2
[ 1.538855][ T1] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00007f00
[ 1.540681][ T1] CPU: 6 PID: 1 Comm: init Not tainted 6.6.0-103.0.0.106.oe2403sp1.x86_64 #1
[ 1.542633][ T1] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014
[ 1.545203][ T1] Call Trace:
[ 1.545959][ T1] <TASK>
[ 1.546568][ T1] dump_stack_lvl+0x32/0x50
[ 1.547593][ T1] panic+0x304/0x340
[ 1.548411][ T1] do_exit+0x3f4/0x410
[ 1.549284][ T1] do_group_exit+0x2d/0x80
[ 1.550272][ T1] __x64_sys_exit_group+0x14/0x20
[ 1.551151][ T1] do_syscall_64+0x55/0x100
[ 1.551963][ T1] entry_SYSCALL_64_after_hwframe+0x78/0xe2
[ 1.553370][ T1] RIP: 0033:0x7f40667d3db5
[ 1.557729][ T1] RSP: 002b:00007ffcb3db2f68 EFLAGS: 00000202 ORIG_RAX: 00000000000000e7
[ 1.559088][ T1] RAX: ffffffffffffffda RBX: 00007f40667cf490 RCX: 00007f40667d3db5
[ 1.560108][ T1] RDX: 0000000000000000 RSI: 00007ffcb3db2630 RDI: 000000000000007f
[ 1.561078][ T1] RBP: 00007ffcb3db3140 R08: 0000000000000010 R09: 0000000000000000
[ 1.562048][ T1] R10: 0000000000000001 R11: 0000000000000202 R12: 00007f40667e2ab0
[ 1.563025][ T1] R13: 0000000000000000 R14: 0000000000000000 R15: 00007f40667b4000
[ 1.563990][ T1] </TASK>
[ 1.564790][ T1] Kernel Offset: 0x38c00000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff)
[ 1.566210][ T1] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x00007f00 ]---
根因
这是已知问题:现代操作系统都开启了指令集优化,纯 qemu 的模拟指令无法满足运行的基本要求,必须配上指令集才能运行。
也可能是我们的 qemu 版本太低了。操作系统是 24 年的,但 qemu 版本还是多年前的 6.2,而最新版本已经是 10.x 了。
先解释报错里的 x86-64-v2:
x86-64-v2 是 GCC 对 x86-64 架构的扩展,要求支持较新的 CPU 指令(如 SSE3、SSSE3、SSE4.1 等)。
较新的 glibc 版本(如 2.34 或更高)可能默认编译为支持 x86-64-v2,而不再兼容旧的 x86-64 CPU。
如果您的 CPU 较旧(如第一代 x86-64 CPU),可能无法运行这些程序。
再看为什么 qemu64 不扩展指令集。查看最新的 qemu 代码,qemu64 其实也没有新的指令扩展。而且 qemu64 就是为了兼容性设计的,不会轻易扩展。
所以问题就变成了:现代操作系统(尤其是 24 年之后的新系统)默认按较新的指令集编译,而默认的 qemu64 模型为了兼容老 CPU 只提供最基础的指令,两者不匹配,系统自然起不来。
小结
- 现代 OS 默认开启指令集优化,纯 qemu 模拟指令无法满足运行要求;
- 遇到新系统跑不起来,优先检查是否配置了合适的 CPU 指令集;
qemu64为了兼容性不会轻易扩展指令,这是设计使然,不是 bug。