子虚拟机启动卡住且vmstat显示wa高、st高,说明其正大量等待磁盘io,同时因嵌套虚拟化链路断裂导致硬件辅助未穿透,cpu特权指令被迫软件模拟,引发高频vm-exit/vm-entry开销;根本原因是宿主机、母vm或子vm任一层未正确启用并暴露vt-x/amd-v支持。

子虚拟机启动就卡住,vmstat 显示 wa 高、st 也高,说明什么
这表示子虚拟机(即嵌套虚拟机)正在大量等待磁盘IO,同时还有明显的“偷取时间”(st),也就是宿主机上的Hypervisor在调度层面把CPU时间片让给了其他任务——但更关键的是,st 高在嵌套场景下往往不是宿主机真忙,而是**嵌套虚拟化层的指令模拟开销过大**,导致客户机内核反复陷入VM-exit/VM-entry循环。这不是资源不够,是虚拟化路径太深、硬件辅助没穿透到底。
常见诱因包括:
- 宿主机BIOS里开了Intel VT-x/AMD-V,但VMware Workstation或VirtualBox未启用“向客户机公开硬件辅助虚拟化”选项
- 子虚拟机操作系统(比如Ubuntu 22.04)默认启用了KVM模块,但它检测不到底层真正的VT-x支持,只能退到纯软件模拟(
kvm_intel加载失败,dmesg | grep -i kvm会报disabled by BIOS or hypervisor) - Windows宿主机上Hyper-V或内核隔离(VBS)已启用,直接劫持了VT-x,连第一层虚拟机都拿不到硬件加速,更别说第二层
cat /proc/cpuinfo 看不到 vmx 或 svm,但宿主机明明支持,问题出在哪一层
这是嵌套虚拟化链路断裂的典型信号。你得逐层验证:先确认宿主机物理CPU是否真支持(grep -E "vmx|svm" /proc/cpuinfo),再进第一层虚拟机(母VM),在里面执行同样命令——如果这里没输出,说明母VM没把虚拟化扩展暴露给子VM。
不同平台暴露方式不同:
- VMware Workstation:关机状态下编辑虚拟机设置 → 处理器 → 勾选“虚拟化Intel VT-x/EPT”和“向客户机操作系统公开硬件辅助的虚拟化”
- VirtualBox:用命令行开启:
VBoxManage modifyvm "VM名称" --nested-hv on(注意必须关机) - KVM/QEMU:启动时加参数
-cpu host,+vmx,且宿主机内核需加载kvm-intel nested=1(写入/etc/modprobe.d/kvm.conf并modprobe -r kvm-intel && modprobe kvm-intel nested=1)
漏掉任意一层,子虚拟机看到的CPU就是“裸奔”的,所有特权指令都靠软件模拟,性能断崖式下跌。
子虚拟机里跑 kvm-ok 报错 “KVM acceleration can be used” 却仍慢如蜗牛
kvm-ok 只检查KVM模块能否加载、CPU是否报告支持,它不验证嵌套深度是否足够、也不测实际VM-exit频率。即使显示OK,也可能因为以下原因卡顿:
- 母VM分配的vCPU数过多(比如8vCPU),但宿主机只有4物理核心,导致子虚拟机的vCPU频繁争抢调度时间,
esxtop或top里看%RDY(就绪时间)持续 >15%,这就是调度瓶颈 - 子虚拟机用了默认IDE控制器,而非Paravirtual SCSI(
pvscsi)或VMXNET3网卡,I/O路径长、中断多,iostat -x 1会看到await超过100ms - 子虚拟机内核版本太老(如CentOS 7.6默认内核3.10),对嵌套虚拟化的优化不足;建议升级到支持
VMXON指令重定向的内核(4.12+)
实操建议:在子虚拟机里装 perf,运行 perf record -e kvm:kvm_entry,kvm:kvm_exit -a sleep 10,然后 perf script | head -20。如果每秒进出次数超5万次,基本可判定是虚拟化逃逸开销压垮了性能。
为什么关闭宿主机的Hyper-V后,子虚拟机还是启动失败
因为Windows的“内核隔离”(Core Isolation)功能,尤其是“内存完整性”(Memory Integrity),底层依赖HVCI(Hypervisor-protected Code Integrity),它会独占VT-x,且**不随Hyper-V角色开关而释放**。很多人只关了Hyper-V,却忘了关这个。
检查方式:msinfo32 查看“基于虚拟化的安全性”状态;或者PowerShell执行:Get-ComputerInfo | Select-Object DeviceGuard, HypervisorEnforcedCodeIntegrity
关闭路径:
- 设置 → 更新与安全 → Windows 安全中心 → 设备安全性 → 内核隔离 → 关闭“内存完整性”
- 或用管理员PowerShell:
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\HypervisorEnforcedCodeIntegrity" -Name "Enabled" -Value 0,然后重启
这个点最容易被忽略——它不像Hyper-V那样有服务名可查,也不会出现在systemctl或services.msc里,但它是嵌套虚拟化失败的静默杀手。











