对于 Proxmox VE 上的 Windows 系统从 Windows 7 后系统性能下降明显,即使安装 Virtio 驱动也不会得到明显改善。
Proxmox VE Forums 上的解决方案是用 x86-64-v2 类型的 CPU,但这样会丢失虚拟化特性,高级 AVX 指令集也会不可用。这对嵌套虚拟化(MuMu模拟器)这种用例十分不友好。而至于关闭主机/客户机的 Meltdown / Specture 缓解也不是什么好主意,一点也不安全,而且关掉之后也没有任何明显的性能改进。
求助 AI 无果后,我开始调查这个问题,最终得出结论:
实际上这并不是 Proxmox VE 的问题,也不是 QEMU/KVM 的问题,与基于虚拟化的安全关系也不大。问题在于 Windows 客户机系统,默认情况下运行在 KVM 上时就是会有明显性能损失。
云厂商是怎么做的
使用 KVM 这套的绝对不只有 Proxmox VE 一家,调查一下市面上的云厂商,它们也都提供 Windows 客户机的服务并且没有此类问题,设备管理器还能看到明晃晃的 RedHat 驱动。
那么问题在哪里?
如果你用过一些小厂的控制面板(例如 BuyVM),你肯定见到过一些类似 Hyper-V Enlightment 的开关。描述大概是 “能够明显提升 Windows 客户机的性能,但也可能对 Linux 客户机产生明显的性能影响”。那么这个 Hyper-V Enlightment 就是关键了。
Hyper-V Enlightment
在 QEMU 的官方文档里是这么说的:
In some cases when implementing a hardware interface in software is slow, KVM implements its own paravirtualized interfaces. This works well for Linux as guest support for such features is added simultaneously with the feature itself. It may, however, be hard-to-impossible to add support for these interfaces to proprietary OSes, namely, Microsoft Windows.
KVM on x86 implements Hyper-V Enlightenments for Windows guests. These features make Windows and Hyper-V guests think they’re running on top of a Hyper-V compatible hypervisor and use Hyper-V specific features.
可以看到这个功能就是转为 Windows 设计的,因为 Windows 非常封闭几乎不可能添加相关半虚拟化接口的支持。让 Windows 误以为运行在 Hyper-V 虚拟机上,并提供一套 Hyper-V 的接口,让 Windows 充分利用 QEMU 的各类加速功能。
F*ck, Microsoft.
所以最终解决方案是通过修改 CPU Flags,指示 Windows 调用这些增强接口。官方文档下面提供了很多 Hyper-V 的标志,但并不是所有的都要加。有一些加了反而会导致额外的问题。
最终方案
要解决这个问题,需要在 Proxmox 中注册一个自定义 CPU 类型。输入 nano /etc/pve/virtual-guest/cpu-models.conf 编辑 CPU 类型配置文件,添加下面的内容到文件末尾:
cpu-model: highperf-win
flags +hv-relaxed;+hv-reset;+hv-runtime;+hv-stimer;+hv-synic;+hv-time;+hv-vapic;+hv-vpindex;+hv-frequencies;+hv-avic;+invtsc;+topoext;+host-cache-info;+hypervisor
hv-vendor-id 0123456789AB
phys-bits host
reported-model host
这基本相当于 host 类型 + Hyper-V Enlightment。
最后在虚拟机的配置界面配置一下刚刚新添加的 CPU 类型就好了:

此方法也可以和客户机禁止 Meltdown / Spectre 缓解措施一同使用,进一步提高性能。但如果 Proxmox 要跑什么重要东西或者不可信代码,最好还是保持两个缓解措施保持开启。







