CPU 虚拟化的已知限制¶
当 CPU 功能的完美模拟不可能或过于困难时,KVM 必须在完全不实现该功能或引入虚拟机和裸机系统之间的行为差异之间做出选择。
此文件记录了 KVM 在虚拟化 CPU 功能方面的一些已知限制。
x86¶
KVM_GET_SUPPORTED_CPUID
问题¶
x87 功能¶
与大多数其他 CPUID 功能位不同,如果存在功能,则 CPUID[EAX=7,ECX=0]:EBX[6] (FDP_EXCPTN_ONLY) 和 CPUID[EAX=7,ECX=0]:EBX]13] (ZERO_FCS_FDS) 被清除,如果不存在功能,则被设置。
在 CPUID 中清除这些位对客户机的操作没有影响; 如果这些位在硬件上设置,则在硬件上运行的任何虚拟机上都不会存在这些功能。
解决方法: 建议始终在客户机 CPUID 中设置这些位。 但是请注意,任何期望这些功能存在的软件(例如 WIN87EM.DLL
)都可能早于这些 CPUID 功能位,因此无论如何都不知道要检查它们。
KVM_SET_VCPU_EVENTS
问题¶
关于错误代码的无效 KVM_SET_VCPU_EVENTS 输入可能会导致 Intel CPU 上的 VM 进入失败。 Pre-CET Intel CPU 要求通过 VMCS 注入的异常正确设置“错误代码有效”标志,例如,在注入 #GP 时需要设置该标志,在注入 #UD 时清除该标志,在注入软异常时清除该标志等。将 IA32_VMX_BASIC[56] 枚举为 '1' 的 Intel CPU 放宽了 VMX 的一致性检查,而 AMD CPU 没有任何限制。 KVM_SET_VCPU_EVENTS 不会对向量与“has_error_code”进行健全性检查,即 KVM 的 ABI 遵循 AMD 的行为。
嵌套虚拟化功能¶
待定
x2APIC¶
启用 KVM_X2APIC_API_USE_32BIT_IDS 时,KVM 会激活一个黑客/怪癖,允许使用其 x2APIC ID 向单个 vCPU 发送事件,即使目标 vCPU 启用了传统的 xAPIC,例如,在具有 > 255 个 vCPU 的虚拟机上通过 INIT-SIPI 启动热插拔的 vCPU。该怪癖的副作用是,如果多个 vCPU 具有相同的物理 APIC ID,则 KVM 将仅将以该 APIC ID 为目标的事件传递给具有最低 vCPU ID 的 vCPU。如果未启用 KVM_X2APIC_API_USE_32BIT_IDS,则 KVM 在处理中断时遵循 x86 架构(所有与目标 APIC ID 匹配的 vCPU 都会接收到中断)。
MTRR¶
KVM 不虚拟化客户机 MTRR 内存类型。 KVM 模拟对 MTRR MSR 的访问,即客户机中的 {RD,WR}MSR 将按预期运行,但 KVM 在确定有效内存类型时不遵守客户机 MTRR,而是将所有客户机内存视为具有回写 (WB) MTRR。
CR0.CD¶
KVM 不虚拟化 Intel CPU 上的 CR0.CD。 与 MTRR MSR 类似,KVM 模拟 CR0.CD 的访问,以便从/到 CR0 的加载和存储按预期运行,但设置 CR0.CD=1 对客户机内存的缓存性没有影响。
请注意,此勘误表不会影响 AMD CPU,AMD CPU 在硬件中完全虚拟化 CR0.CD,即当 CR0.CD=1 时,即使在客户机中运行,也会将 CPU 缓存置于“不填充”模式。