新系统跑不起来,报 “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。