KVM 不可用:三类报错的分诊、修复与 TCG 兜底
给 QEMU 加上 -enable-kvm 想跑硬件加速,虚拟机却直接退出,打印一行 failed to initialize kvm——这是新手在云主机上最常撞上的墙。KVM 不可用不是一种单一故障,从 CPU 本身没有虚拟化能力,到内核模块没加载、设备节点权限不对,每一环断掉都会让 QEMU 拿不到 KVM 加速,而报错文本各不相同。本篇把实测中复现出的三类报错按「症状 → 根因 → 修复 → 验证」逐一拆开,再用一个反证实验讲清 /dev/kvm 节点存在与真正具备 KVM 能力之间的区别。对 QEMU 基本工作方式还陌生的读者,先读 认识 QEMU:从零看懂虚拟机、镜像与快照 建立背景。
本文要回答的问题
Operation not supported、No such file or directory、Permission denied三种报错分别断在 KVM 链路的哪一环?- 云主机上 CPU 没有
vmx/svm标志意味着什么,为什么modprobe kvm成功而kvm_intel失败? - 手工建一个权限 666 的
/dev/kvm占位节点,报错为什么反而变成No such device? - 同一台没有 KVM 能力的机器,怎样把虚拟机照常跑起来?
一、KVM 不可用的三类报错:一张分诊图先收敛
三类报错看似分散,本质上对应 KVM 链路上三个依次把关的环节:先看 CPU 有没有硬件虚拟化能力,再看内核有没有加载 KVM 模块并生成 /dev/kvm 节点,最后看当前用户有没有权限打开这个节点。QEMU 启动时依次尝试,断在哪一环就打印哪一环的错误,所以读报错文本就能反向定位。
读这张漏斗抓住一条主线:越往下游的环节越容易修,权限问题一条命令解决,而最底层的 CPU 无虚拟化能力只能换机器或换加速方式。下表把三类报错与处置方向先摆在一起,后续小节再逐个展开。
| 报错关键词 | 断掉的环节 | 根因 | 处置方向 |
|---|---|---|---|
Operation not supported | CPU 硬件虚拟化 | 无 vmx/svm 标志,如云主机未开嵌套虚拟化 | 换支持嵌套虚拟化的规格,或改用 TCG |
No such file or directory | 设备节点 | KVM 模块未加载,/dev/kvm 不存在 | modprobe kvm 与对应厂商模块 |
Permission denied | 节点权限 | 节点为 root:600,当前用户不在 kvm 组 | 加入 kvm 组后重新登录 |
No such device(反证) | ioctl 能力 | 占位节点能 open 但内核无 KVM 实现 | 回到前两环查模块与 CPU 能力 |
二、报错类 1:Operation not supported,CPU 没有虚拟化能力
实验用的云主机规格不支持嵌套虚拟化,进入系统后查 CPU 标志位,vmx(Intel VT-x)与 svm(AMD-V)一个都没有。这时候手动加载模块,通用的 kvm 模块可以进内核,但厂商相关的 kvm_intel 直接被内核拒绝:
modprobe kvm exit=0
modprobe: ERROR: could not insert 'kvm_intel': Operation not supported
modprobe kvm_intel exit=1Operation not supported 在这里不是权限问题,而是内核探测不到 CPU 的虚拟化扩展,模块初始化阶段就放弃了。物理机上遇到同样报错,先进 BIOS/UEFI 找 Intel VT-x 或 AMD-V 的开关,默认关闭的主板并不少见;云主机上则没有 BIOS 可进,嵌套虚拟化由实例规格与宿主机决定,需要换一款明确支持嵌套虚拟化的规格,或在控制台确认相应开关。这一环是 KVM 链路的地基,地基不存在时,后面的节点和权限都无从谈起。
三、报错类 2:No such file or directory,设备节点不存在
模块没加载成功,直接后果是 /dev/kvm 这个字符设备节点不会被创建。QEMU 打开节点失败,连抛两行错误后以退出码 1 结束:
ls: cannot access '/dev/kvm': No such file or directory
Could not access KVM kernel module: No such file or directory
qemu-system-x86_64: failed to initialize kvm: No such file or directory
qemu exit=1正常机器上,modprobe kvm 再加载 kvm_intel(或 kvm_amd)成功后,内核会自动生成主设备号 10、次设备号 232 的 /dev/kvm。所以这一类报错的标准动作是先查模块:lsmod | grep kvm 看在不在,不在就按上一节的顺序加载,加载失败则说明根因其实在更上游的 CPU 能力环。注意区分两种「没有节点」:模块没加载是软故障,加载后仍不生成节点,则要回到第一节怀疑硬件能力。
四、报错类 3:Permission denied,以及 666 占位节点的反证
第三类报错发生在节点确实存在、但当前用户打不开它的时候。实验中用 root 建了一个属主 root:root、权限 600 的节点,普通用户启动 QEMU 立刻被拒:
crw------- 1 root root 10, 232 Nov 8 12:11 /dev/kvm
Could not access KVM kernel module: Permission denied
qemu-system-x86_64: failed to initialize kvm: Permission denied
qemu exit=1正规修复不是把节点权限放开,而是走用户组:主流发行版的 KVM 包都会创建 kvm 组并让 /dev/kvm 属组可读写,执行 sudo usermod -aG kvm $USER 后重新登录即可。接下来是整个实验最反直觉的一段——把这个节点 chmod 666 对所有人开放,报错并没有消失,而是换了一张面孔:
Could not access KVM kernel module: No such device
qemu-system-x86_64: failed to initialize kvm: No such device
qemu exit=1Permission denied 变成了 No such device(errno 为 ENODEV)。原因在于打开设备和使用设备是两步:open() 只校验文件权限,666 之后这一步放行了;QEMU 随后发出 KVM_CREATE_VM 等 ioctl,内核里却没有注册 KVM 驱动来响应,于是回一句「没有这个设备」。这个反证把一个常见误解钉死了:设备节点只是一个入口编号,真正的 KVM 能力活在内核模块与 CPU 里,手工 mknod 凑出的节点只是空壳。排错时看到节点存在就宣布 KVM 可用,是会被这个反证打脸的。
下面这张决策流程图把三类报错与反证、兜底串成一条排查路径,读图时注意颜色语义:红色是现象与根因,蓝色是排查动作,橙色是修复动作,绿色是复测通过,紫色是硬件无能力时的绕行路线。
图中紫色支路是这台无嵌套虚拟化云主机实际走通的路线:既然 CPU 能力环无解,就不再纠缠 KVM,直接退到 QEMU 自带的 TCG 加速。
五、TCG 兜底:同一台机器,去掉 -enable-kvm 照常启动
TCG(Tiny Code Generator)是 QEMU 内置的纯软件指令翻译引擎,不依赖任何 CPU 虚拟化扩展,性能不如 KVM,但在任何机器上都能用。下面的终端实录截取自权限拒绝与占位节点反证这一段,可以清楚看到错误类型如何随节点权限变化。
实录前半段是 root:600 节点下的 Permission denied,后半段节点放开为 666 后转为 No such device,两次退出码都是 1,恰好对应第四节的 open 与 ioctl 两步论。实验最后用 -accel help 查看这个 QEMU 二进制支持的加速后端:
Accelerators supported in QEMU binary:
tcg
kvm列表里同时有 tcg 和 kvm,但要注意这个列表只说明编译进来了哪些后端,不代表当前硬件能用——KVM 后端在这台机器上已经被前三节的实验证明不可用。真正落地的启动方式是去掉 -enable-kvm,或显式写 -accel tcg,QEMU 便回到软件模拟,x86 客户机照常开机。功能验证、固件调试、跨架构学习这类不追求吞吐的场景,TCG 完全够用;KVM 与 TCG 的加速原理、性能差距与选型口径,在 KVM 不可用时怎么选:系统模拟、用户模式与 TCG/KVM 加速 里展开。
上面的终端实录从上到下分五段:先是 CPU 无 vmx/svm 的环境事实与 kvm_intel 加载失败,接着是无节点时的 No such file or directory,中段是 root:600 节点的 Permission denied,然后节点放开 666 后报错转为 No such device,末尾 -accel help 列出 tcg 与 kvm 两个后端。一次运行把四个错误号和兜底路径全部固定下来,回头查表即可对号入座。
实验环境
- 机器/系统:macOS 本机(无
/dev/kvm,作为天然阴性实验台)+ 一台无嵌套虚拟化的 Linux 云主机(Ubuntu 22.04.5,2C8G) - 工具版本:QEMU 6.2(
-accel help与机型别名pc-i440fx-6.2佐证)、系统自带 modprobe 与 mount - 日期:2026-11-08
- 完整命令序列:
./reproduce.sh一条脚本依次完成 CPU 标志检查、三类报错复现、占位节点反证与-accel help输出,脚本结束自动清理自建的占位节点,输出即本篇引用的完整实录。
代码获取:本篇实验的可复现脚本见公开仓库 derekzhuo/geek-doc.cn 的
experiments/kvm-not-available-errors目录。克隆后进入该目录执行./reproduce.sh,终端会依次打印三类报错、666 占位节点反证与 TCG 兜底信息,与本篇实录逐条对应。
这一篇在知识体系里的位置
本篇是 SoC 与 QEMU 入门路线上的排错答案块,解决「加速器起不来」这一类具体卡点。KVM 与 TCG 的原理差异和选型问题在 KVM 不可用时怎么选:系统模拟、用户模式与 TCG/KVM 加速 继续;虚拟机、镜像、快照等基础概念与完整启动流程在 认识 QEMU:从零看懂虚拟机、镜像与快照 里铺垫。后续在网络、设备模拟环节遇到的启动失败,排查思路同样是「读报错文本 → 定位链路环节 → 对因修复 → 复测验证」。
总结
KVM 不可用按链路分三关:CPU 无 vmx/svm 标志时 kvm_intel 加载报 Operation not supported,云上只能换支持嵌套虚拟化的规格或改走 TCG;模块没加载则没有 /dev/kvm,QEMU 报 No such file or directory,修复靠 modprobe 并向上游追因;节点存在但属主为 root:600 时报 Permission denied,正解是加入 kvm 组而非放开权限。666 占位节点把错误变成 No such device 的反证说明,节点只是入口、能力在内核与 CPU,open 成功不等于 ioctl 可用。所有 KVM 路径都走不通时,去掉 -enable-kvm 让 QEMU 回到 TCG 软件模拟,虚拟机始终能启动。