简体   繁体   English

是否可以在VM中使用VMX CPU指令?

[英]Is it possible to use VMX CPU instructions inside VM?

Is it possible that a Process inside a VM guest uses the VMX (AMD-V, VT-x) CPU instructions, that are then processed by the outer VMM instead of directly on the CPU? VM guest虚拟机中的进程是否可能使用VMX(AMD-V,VT-x)CPU指令,然后由外部VMM而不是直接在CPU上处理?

Edit: Assume that the outer VM uses VMX itself to manage its virtual guest machine (ie it runs in Ring -1). 编辑:假设外部VM使用VMX本身来管理其虚拟客户机(即它在Ring -1中运行)。

If it is possible are there any implementations of VMMs that support emulating/intercepting VMX calls (VMware, Parallels, KVM,...)? 如果有可能支持模拟/拦截VMX调用(VMware,Parallels,KVM,......)的VMM实现?

Nor the Intel's VT-x nor the AMD's AMD-V support a fully recursive virtualization in hardware - where the CPU keep a hierarchy of nested virtualized environments in the same fashion of a call / ret pair. 英特尔的VT-x和AMD的AMD-V也不支持硬件中的完全递归虚拟化 - 其中CPU以与call / ret对相同的方式保持嵌套虚拟化环境的层次结构。

A logical processor only supports two modes of operation: the host mode (called VMX root mode in Intel terminology, hypervisor in AMD's one) and the guest mode (called as such in AMD's manuals and VMX non-root mode in Intel's ones). 逻辑处理器仅支持两种操作模式:主机模式(在英特尔术语中称为VMX根模式,在AMD中称为虚拟机管理程序)和访客模式(在AMD的手册和英特尔的VMX非根模式中称为)。
This implies a flattened hierarchy where every virtualized environment is treated the same by the CPU - the CPU is unaware of how many levels the hierarchy of VMs is deep. 这意味着一个扁平化的层次结构,其中每个虚拟化环境由CPU处理相同 - CPU不知道VM的层次结构有多少级别。

An attempt to use the virtualization instructions them-selves inside a guest will yield control to the monitor (VMM). 尝试在guest虚拟机内使用虚拟化指令将产生对监视器(VMM)的控制。
But some support for accelerating frequently used virtual instructions has appeared recently making nested VM possible. 但是最近出现了一些对加速常用虚拟指令的支持,使得嵌套VM成为可能。

I'll try to analyse the issues to face to implement a nested virtualization. 我将尝试分析实现嵌套虚拟化所面临的问题。
I'm not dealing with the whole thing - I'm considering the base case only leaving out all the part dealing with the virtualization of the hardware; 我不是在处理整个事情 - 我正在考虑基本情况,只是忽略了处理硬件虚拟化的所有部分; a part that itself is as problematic as the virtualization of the software. 本身与软件虚拟化一样有问题的部分。

Note 注意
I'm not an expert on virtualization technology and have no experience on it at all - corrections are welcome. 我不是虚拟化技术方面的专家,根本没有任何经验 - 欢迎更正。
The purpose of this answer is to make the reader conceptually believe that nested virtualization is possible and outline the problems to face. 这个答案的目的是让读者在概念上相信嵌套虚拟化是可能的,并概述要面对的问题。

VT-x VT-X

A logical processor enters the VMX operation by executing vmxon - as soon as the mode is entered the processor is in root mode. 逻辑处理器通过执行vmxon进入VMX操作 - 一旦进入模式,处理器就处于根模式。
Root mode is the mode of the VMM, it can launch, resume and handle the VMs. 根模式是VMM的模式,它可以启动,恢复和处理VM。

The VMM then set the current VMCS (VM Control Structure) with vmptrld - the VMCS contains all the metadata necessary to virtualise a guest. 然后,VMM使用vmptrld设置当前VMCS(VM控制结构) - VMCS包含虚拟化guest虚拟机所需的所有元数据。
The VMCS is read and written not with direct memory accesses but with vmread and vmwrite instructions. 该VMCS的读写不是直接内存访问vmreadvmwrite说明。

Finally, the VMM executes vmlaunch to start executing the guest. 最后,VMM执行vmlaunch以开始执行guest虚拟机。

Incepting a VM 接受虚拟机

Now the logical processor is executing in a virtualized environment. 现在,逻辑处理器正在虚拟化环境中执行。
Suppose the guest is a VMM itself and let's call this the non-root VMM - it needs to repeat the steps above. 假设guest虚拟机本身就是VMM,我们称之为非root VMM - 它需要重复上述步骤。

But Intel is clear in its manuals (Manual 3 - Chapter 25.1.2): 但英特尔在其手册中很清楚(手册3 - 第25.1.2章):

The following instructions cause VM exits when they are executed in VMX non-root operation: 以下说明导致VM在VMX非root操作中执行时退出
[...] [...]
This is also true of instructions introduced with VMX, which include: VMX引入的说明也是如此,其中包括:
[...], VMLAUNCH , VMPTRLD , [...] and VMXON [...], VMLAUNCHVMPTRLD ,[...]和VMXON

vmxon this instruction causes a VM Exit, the root VMM resume from the instruction after its last vmlaunch , can inspect the VMCS for the reason of the exit and take appropriate action. vmxon此指令导致VM退出,根VMM从上一次vmlaunch之后的指令恢复,可以检查VMCS以查找退出的原因并采取适当的操作。
I'm not a seasoned VMM writer so I'm not sure what the root VMM have to do exactly to emulate this instruction - since executing a vmxon in VMX root mode will fail and doing a vmxoff followed by a vmxon with VM Region given by the non-root VMM seems a security vulnerability (or a lead to it) I believe that all the root VMM has to do is record that the guest is now in "VMX root mode". 我不是一个经验丰富的VMM vmxon所以我不确定根VMM必须做什么才能模拟这条指令 - 因为在VMX根模式下执行vmxon会失败并执行vmxoff后跟一个带有VM Region的vmxon非root VMM似乎是一个安全漏洞(或导致它)我相信所有根VMM必须做的是记录guest虚拟机现在处于“VMX根模式”。
The quotes are necessary here: this mode exists only in software when the root VMM will handle the control back to the non-root VMM the CPU will be in non-root VMX mode. 这里需要引号:此模式仅存在于软件中,当根VMM将控制权交还给非根VMM时,CPU将处于非root VMX模式。

After that, the non-root VMM will attempt to use vmptrld to set the current VMCS. 之后,非根VMM将尝试使用vmptrld设置当前VMCS。
vmptrld will induce a VM exit and the root VMM is in control once again - if the CPU doesn't support VMCS shadowing the root VMM has to record that the pointer given by the non-root VMM is now the current VMCS - if the CPU does support VMCS shadowing the VMM set the VMCS link pointer field of its VMCS (the one used to virtualise the non-root VMM) to the VMCS given by the non-root VMM. vmptrld将引发VM退出并且根VMM再次处于控制状态 - 如果CPU不支持VMCS镜像,则根VMM必须记录非根VMM给出的指针现在是当前VMCS - 如果CPU确实支持VMCS遮蔽的VMM设置 VMCS由非根VMM给予VMCS(用于虚拟化的非根VMM的一个)的VMCS链接指针字段。
One way or another the VMM knows which virtualised VMCS is active. VMM以这种或那种方式知道哪个虚拟化VMCS是活动的。

vmread and vmwrite executed by the non-root VMM will or will not cause a VM exit. 非root VMM执行的vmreadvmwrite将会或不会导致VM退出。
If VMCS shadowing is active the CPU won't do a VM Exit and instead will read the VMCS pointed by the VMCS link pointer in the active VMCS (called the shadow VMCS ). 如果VMCS阴影处于活动状态,则CPU将不执行VM Exit,而是读取活动VMCS(称为影子VMCS )中的VMCS链接指针所指向VMCS
This will speed up virtualization of nested VMs. 这将加速嵌套VM的虚拟化。
If VMCS shadowing is not active the CPU will VM exit and the root VMM has to emulate the read/write. 如果VMCS阴影未激活,则CPU将退出VM,并且根VMM必须模拟读/写。

Finally, the non-root VMM will launch its VM - this is a nested VM. 最后,非root VMM将启动其VM - 这是一个嵌套的VM。
vmlaunch will trigger a VM Exit. vmlaunch将触发VM Exit。
The root VMM has to do a few things: 根VMM必须做一些事情:

  • Save its VMCS somewhere. 将VMCS保存在某处。
  • Merge the current VMCS and the non-root VMM VMCS - Since the VMCS controls, for example, what events cause a VM Exit the merged one must be the union of the two in this regard. 合并当前VMCS和非根VMM VMCS - 由于VMCS控制,例如,哪些事件导致VM退出,合并的VMD必须是这两者的联合。
  • Load the merged VMCS as the CPU's current one 将合并的VMCS加载为CPU的当前VMCS
  • Do a vmlaunch / vmresume . 做一个vmlaunch / vmresume

Inside the dream 梦想里面

Now the CPU is executing the nested VM (a VVM - Virtual VM?). 现在CPU正在执行嵌套VM(VVM - 虚拟VM?)。
What happens when a sensitive instruction or an event causes a VM Exit? 当敏感指令或事件导致VM退出时会发生什么?

From the processor point of view, there are only two levels of virtualization: the root VMX mode and the non-root VMX mode. 从处理器的角度来看,只有两个级别的虚拟化:根VMX模式和非根VMX模式。
Since the guest is in non-root VMX mode, control is transferred back to the root VMX mode code - ie the root VMM. 由于guest虚拟机处于非root VMX模式,因此控制权将转移回根VMX模式代码 - 即根VMM。

The root VMM now must understand if that event is from its VM or from its VM's VM. 根VMM现在必须了解该事件是来自其VM还是来自其VM的VM。
This can be done by tracking the use of vmlaunch / vmresume and checking the bits in the VMCS. 这可以通过跟踪vmlaunch / vmresume的使用并检查VMCS中的位来完成。

If the VM Exit is directed to the non-root VMM the root VMM has to load its original VMCS, eventually set in it the link the non-root VMM, update the non-root VMM VMCS status bits and do a vmresume . 如果VM Exit指向非根VMM,则根VMM必须加载其原始VMCS,最终在其中设置非根VMM的链接,更新非根VMM VMCS状态位并执行vmresume
If the VM Exit is directed to it, the root VMM will handle it as any other VM Exit. 如果VM Exit指向它,则根VMM将像任何其他VM Exit一样处理它。

A dream within a dream within a dream 梦中的梦想

What if we want to create a VM inside the nested VM? 如果我们想在嵌套VM中创建VM,该怎么办? Kind of a Virtual Virtual VM (VVVM). 一种虚拟虚拟VM(VVVM)。

There are two things to notice: 有两件事需要注意:

  1. The root VMM is still the one invoked during every VM Exit. 根VMM仍然是在每个VM Exit期间调用的VMM。
    Even if the VVVM is three levels deep it is not the non-root-non-root VMM the first and/or the only manager used to virtualise it. 即使VVVM深度为三级,也不是非根非根VMM是第一个和/或唯一用于虚拟化它的管理器。
    From a security point of view, the root VMM is the weak link. 从安全角度来看,根VMM是弱链接。
  2. The hardware doesn't really support arbitrary deep nesting. 硬件并不真正支持任意深度嵌套。
    A VMM may not need too much effort to go from supporting 1-level of nesting to n-levels of nesting (again I'm not seasoned here) but special support as outlined above is still needed. VMM可能不需要太多努力就可以从支持1级嵌套到n级嵌套(我再次在这里没有经验丰富),但仍然需要如上所述的特殊支持。
    It is not as easy as launch the VM and everything else will be taken care by the CPU. 它并不像启动VM那么容易,CPU会处理其他所有事情。

AMD-v AMD-V

There is no root vs non-root mode in AMD-v, the CPU starts executing a VM with vmrun that takes a pointer to a VMCB (VM Control Block) that serves the same purpose of the Intel's VMCS. 在AMD-v中没有root和非root模式,CPU开始使用vmrun执行VM,该vmrun接收指向VMCB(VM控制块)的指针,该VMCB与Intel的VMCS具有相同的用途。
Upon a vmrun the CPU is in guest mode. vmrun ,CPU处于访客模式。

The VMCB is cached but it can only be read with usual memory accesses. VMCB已缓存,但只能通过常规内存访问来读取。
The vmload / vmsave instructions explicitly load into and save from the cache the VMCB fields subject to caching. vmload / vmsave指令显式加载到缓存中并从缓存中保存受缓存影响的VMCB字段。

This interface is easier than Intel's one but it is as powerful - even when it comes to nesting virtualization. 这个界面比英特尔的界面更容易,但它同样强大 - 即使在嵌套虚拟化方面也是如此。

Assume we are inside a VM and the code executes a vmrun - thus we are virtualizing a VMM. 假设我们在VM中并且代码执行vmrun - 因此我们正在虚拟化VMM。

Technically a VMM can choose whenever vmrun will or will not trigger a VM Exit. 从技术上讲,只要vmrun将触发或不触发VM Exit,VMM就可以选择。
Practically, however, AMD-v currently require the former to always be the case: 然而,实际上,AMD-v目前要求前者始终如此:

The following conditions are considered illegal state combinations: [...] 以下条件被视为非法国家组合:[...]
* The VMRUN intercept bit is clear * VMRUN截取位清零

Thus the root VMM (I'll use the same terminology as in the Intel case) will gain control and has to emulate a vmrun (since the hardware only support a single level of virtualisation). 因此,根VMM(我将使用与英特尔情况相同的术语)将获得控制并且必须模拟vmrun (因为硬件仅支持单级虚拟化)。

The root VMM can save and merge the current VMCB with the non-root VMM VMCB and go ahead with the vmrun as in the Intel case. 根VMM可以将当前VMCB与非根VMM VMCB保存并合并,并按照英特尔情况继续使用vmrun

Upon an exit the root-VMM has to determine if the exit was directed to it or to the non-root VMM, again this can be done tracking the vmrun and the control bits in the VMCB. 在退出时,root-VMM必须确定退出是指向它还是指向非根VMM,再次可以跟踪vmrun和VMCB中的控制位。

Dreaming again 再次做梦

We have set up a VM inside a VM relatively easy - now what happens upon a VM Exit? 我们在VM中建立了一个相对简单的虚拟机 - 现在虚拟机出口会发生什么?
The root VMM receives the exit and if directed to the non-root VMM is has to restore its original VMCB and resume the run (ie use vmrun with its original VMCB). 根VMM接收退出,如果定向到非根VMM,则必须恢复其原始VMCB并恢复运行(即使用vmrun及其原始VMCB)。

AMD-v supports a fast virtualisation of the vmsave and vmload instructions by considering their addresses guest addresses and thus subject to the usual page-nesting virtualisation. AMD-v通过考虑其地址访客地址来支持vmsavevmload指令的快速虚拟化,因此受制于通常的页面嵌套虚拟化。

Bringing up Inception again 再次启动Inception

As with the Intel case, the virtualization can be nested again as long as the VMM support that features. 与英特尔的情况一样,只要VMM支持该功能,就可以再次嵌套虚拟化。

The critical security warning noted for the Intel's case is valid for the AMD's one as well. 针对英特尔案例的重要安全警告也适用于AMD的案例。


Due to its implementation-defined format and the fact the memory area can be used just as a spill area that is not updated in real time 由于其实现定义的格式以及内存区域可以用作未实时更新的溢出区域这一事实

After reading up a lot more on virtualization I stumbled onto this ticket at virtualbox. 在阅读了更多关于虚拟化的内容后,我偶然发现了虚拟机的这张

It is a feature request for exactly this functionality and reading through the comments it seems that VMware Workstation has already implemented it, so it must indeed be working. 这是一个功能请求,正是这个功能和阅读评论似乎VMware Workstation已经实现了它,所以它必须确实有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 VM 说明 如果可以退出? - VM Instructions If an exit is possible? 是否可以使用`as`组装和运行原始CPU指令? - Is it possible to assemble and run raw CPU instructions using `as`? CPU:CPU 内部的程序,用于确定指令的确切原理(?!) - CPU: Program inside CPU that determines exact principal of instructions (?!) cpu指令如何工作? - How do cpu instructions work? CPU如何重新排序指令 - How does CPU reorder instructions 使用单个变量/寄存器存储2个值(并通过位掩码和/或特定的CPU指令读取它们的字长) - Use a single variable/register for storing 2 values (and reading them by bitmask and/or specific CPU instructions for word size) 是否可以在实模式下使用32位寄存器/指令? - Is it possible to use 32 bits registers/instructions in real mode? BIOS 如何区分中断(08h-12h)和 INT 指令,以及 CPU 内部的实际异常? - How does the BIOS distinguish Interrupt(08h-12h) from INT instructions, vs. actual exceptions inside the CPU? 如何记录由Python程序执行的CPU指令? - How to log CPU instructions executed by a Python program? 通过计算汇编指令来测量 CPU 速度 - Measure CPU speed by counting assembly instructions
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM