【问题标题】:VMresume failed with unlaunched VMCS, how to deal with it?VMresume 因未启动 VMCS 而失败,如何处理?
【发布时间】:2018-05-12 07:56:08
【问题描述】:

我正在开发一个 Linux 内核模块和一个用户空间程序来测试 VMX。
该代码在带有 Broadwell CPU 的 Ubuntu16.04 笔记本电脑上运行。

用户空间程序会调用内核模块代码执行VMX指令来运行一个测试VM,比如vmxon, vmclear, vmptrld, vmlaunch, vmxoff来vmlaunce VM,或者vmxon, vmptrld, vmresume, vmxoff来恢复VM执行。

VMexit 后(切换回用户空间程序检查 VM 状态,然后返回内核空间继续 VMX 操作),模块将调用 vmresume 恢复 VM,但 vmresume 失败,指令错误号为 5 ,这意味着“使用未启动的 VMCS 调用 vmresume”。

然后,我更改了代码,没有切换回用户空间,只需在内核空间(内核模块)运行vmlaunch,(vmexit)和vmresume,它就可以正常工作了。

为了检查失败的原因,我改回使用用户空间。并使用“sched_setaffinity”将我所有的 VMX 执行绑定到一个 CPU 内核中,并在每个 vmexit 或 vmx 指令错误上转储 VMCS。

我仍然遇到这个错误,即使内核日志显示这些 VMX 操作都在一个 CPU 中执行,例如CPU0。并且 VMCS 转储在失败后显示几乎为空的 VMCS。

我不知道为什么使用单个 VMCS 区域并绑定到 CPU 内核会出现此错误。

我错过了什么重要的事情吗?

【问题讨论】:

  • 为确保它不是由逻辑处理器之间的线程迁移引起的,我建议在 BIOS 中暂时禁用除一个内核(无多核、无超线程)之外的所有内核,直到您调试并解决问题。
  • 是否加载了其他管理程序模块,例如kvm 还是 xen? lsmod | grep kvm 和 lsmod | grep xen 应该为空
  • 听起来你是在vmexit之后使用vmxoff。您需要在 vmxoff 之前执行 vmclear。并且在将 vmclear 与特定 vmcs 一起使用后,您需要使用 vmlaunch,而不是 vmresume。我建议你根本不要使用 vmxoff。
  • 我没有找到禁用此戴尔笔记本电脑中其他 CPU/内核的 BIOS 选项,我会进一步尝试。 Linux 主机中没有加载其他管理程序。我在 IVB 笔记本电脑(相同的 Linux 版本)中发现,2 核(4 线程),代码运行良好。但在 BroadWell(2 核/4 线程)中失败了。 @prl,我仅在 vmexit 并返回用户空间时才调用 vmxoff 。当用户空间(如 QEMU)决定继续 VM 时,它会调用内核,然后内核会调用 vmxon、vmptrld。我想测试 vmresume,避免 vmclearing 以获得更好的性能。

标签: linux x86 x86-64 virtualization


【解决方案1】:

在使用 vmxoff 之前,您首先需要在任何您希望能够再次使用的 VMCS 上使用 vmclear。

任何时候您想使用已完成 vmclear 的 VMCS 恢复 VM,都需要使用 vmlaunch,而不是 vmresume。

所以,如果要使用 vmresume,一定不能做 vmclear 或 vmxoff。

请参阅 SDM 的第 24.1 和 24.11 节。

【讨论】:

  • 我刚试过你的 cmets,禁用调用 vmxoff,它成功了!我想使用 vmresume 来测试它的功能。我在 VMExit 时使用了 vmxoff,它进入用户空间来处理该 VMExit,以“保护”VMX 开启的错误。但我真的不明白为什么 VMXOFF 会触及 VMCS。 VMCS 是一个内存区域(可能被 CPU 缓存),我假设字段保存在其中,因此 VMXON、VMPTRLD、VMRESUME、VMXOFF 将可以安全地恢复 VM。你觉得 VMXON VMPTRLD VMLAUNCH VMPTRST VMXOFF,然后 VMXON VMPTRLD VMRESUME VMXOFF 会起作用吗?
  • 不,vmptrst 只是保存 VMCS 的地址,它不会刷新缓存。在 vmxoff 之前确实需要 vmclear。 (但我仍然不建议使用 vmxoff,只要您有活跃的访客。)
  • 所以你的意思是,我应该在客人退出时调用 vmxoff,对吧?如果是这样,在来宾处于活动状态期间让 VMX 处于开启状态是否有任何风险,例如在内核和用户空间中执行其他操作?
  • 当我尝试根据您的 cmets 调整 VMX 指令的代码序列时遇到了另一个问题。内核模块定义了一组文件系统函数来处理用户空间。如果我在 device_open 的 CR4 中设置 VMXE,第一次调用 vmlaunch 将失败并显示“无效主机状态”,随后调用 vmlaunch 工作正常。如果我在 module_init 函数的 CR4 中设置 VMXE,则不存在此类问题。我的主机Linux是Ubuntu-16.04,Linux-4.4.0-119 64bit。
猜你喜欢
  • 1970-01-01
  • 2014-11-09
  • 1970-01-01
  • 1970-01-01
  • 2012-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-16
相关资源
最近更新 更多