手动将 CPU 标志暴露给来宾 VM 以进行测试

Posted

技术标签:

【中文标题】手动将 CPU 标志暴露给来宾 VM 以进行测试【英文标题】:Manually exposing a CPU Flag to Guest VM for testing purposes 【发布时间】:2016-11-18 19:04:11 【问题描述】:

我有一个带有 Intel E5-26xx v3 处理器的 Ubuntu(在 14.04 或 16.04 上试用)KVM 主机。

我需要向来宾 VM 公开某个标志,但 QEMU/libvirt 并没有公开它,即使我在我的 VM libvirt XML 定义中使用了cpu mode='host-passthrough'。我相信这是由于此文件 /usr/share/libvirt/cpu_map.xml 中定义的内容,其中未定义我想要暴露的标志。

所以,我希望能够修改 cpu_map.xml 并手动添加 CPU 标志定义,但我不知道如何/在哪里可以获得 CPUID 函数的结果以及它们是否'重新输入ebx/ecx 等。任何指针表示赞赏。

免责声明:我没有涉足 CPU 架构,所以我在这方面的知识非常有限。

【问题讨论】:

【参考方案1】:

CPUID instruction 检索结果非常简单:

检查 EFLAGS 寄存器中的 ID 标志(第 21 位)是否设置,表示CPUID 指令的可用性 将EAXECX 寄存器设置为特定值 致电CPUID 解释EAXEBXECXEDX 寄存器的值

许多 网站讨论结果的解释。其中之一是LowLevel。其中许多只涵盖了可能结果的一个子集。

A thread on the specifics of CPUID in VMs 将此基础知识扩展到:

UserCPUID 是使用二进制翻译时本地运行的来宾 Ring-3 代码可见的内容。对于二进制翻译,通常只有 Ring-0(或 IOPL-3)代码需要进行二进制翻译。大多数 Ring-3 代码在本机运行(以我们称为“直接执行”的模式。)

在引入CPUID faulting 之前,当guest 在直接执行下运行时,无法拦截guest 对CPUID 指令的执行。某些 CPU 支持覆盖某些 CPUID 叶子的结果(在逐个寄存器的基础上)的有限能力,即使没有拦截 CPUID 指令。因此,userCPUID 基于hostCPUID,但可以被覆盖的寄存器具有guestCPUID 值。

【讨论】:

【参考方案2】:

主机直通模型旨在向客户机公开每个主机 CPU 功能,但此规则有一些例外。如果 CPU 特性很新,那么 QEMU、KVM 和 libvirt 可能不知道它的存在。 KVM 默认是保守的,所以不会暴露任何它不知道的特性。在这种情况下,仅仅编辑 cpu_map.xml 并没有帮助,因为它只会告诉 libvirt - 你仍然需要 QEMU 和 KVM 来了解它,这需要更改代码。第二种情况是某些 CPU 功能不能安全地暴露给来宾,因此 KVM 会显式阻止它们。

您可以通过使用“virsh 功能”来查看 libvirt 认为主机具有什么

【讨论】:

以上是关于手动将 CPU 标志暴露给来宾 VM 以进行测试的主要内容,如果未能解决你的问题,请参考以下文章

如何从另一个 virtualbox 来宾访问 vagrant 来宾?

在 Linux 主机上运行的 Windows 10 来宾 VM 中运行 WSL2

如何使用星号将 X-Lite 软电话从主机连接到来宾 vm?

除了实例化 DAL 的 BLL 之外,还有啥选项允许在 n 层解决方案中进行单元测试,而不会将 DAL 暴露给 UI 或将 BLL 暴露给 DAL?

如何封装AngularJS函数但仍然可以测试它

无法从主机访问 VM 来宾(使用正在运行的 *** 客户端)