[英]Is it possible to use VMX CPU instructions inside VM?
VM guest虚拟机中的进程是否可能使用VMX(AMD-V,VT-x)CPU指令,然后由外部VMM而不是直接在CPU上处理?
编辑:假设外部VM使用VMX本身来管理其虚拟客户机(即它在Ring -1中运行)。
如果有可能支持模拟/拦截VMX调用(VMware,Parallels,KVM,......)的VMM实现?
英特尔的VT-x和AMD的AMD-V也不支持硬件中的完全递归虚拟化 - 其中CPU以与call
/ ret
对相同的方式保持嵌套虚拟化环境的层次结构。
逻辑处理器仅支持两种操作模式:主机模式(在英特尔术语中称为VMX根模式,在AMD中称为虚拟机管理程序)和访客模式(在AMD的手册和英特尔的VMX非根模式中称为)。
这意味着一个扁平化的层次结构,其中每个虚拟化环境由CPU处理相同 - CPU不知道VM的层次结构有多少级别。
尝试在guest虚拟机内使用虚拟化指令将产生对监视器(VMM)的控制。
但是最近出现了一些对加速常用虚拟指令的支持,使得嵌套VM成为可能。
我将尝试分析实现嵌套虚拟化所面临的问题。
我不是在处理整个事情 - 我正在考虑基本情况,只是忽略了处理硬件虚拟化的所有部分; 本身与软件虚拟化一样有问题的部分。
注意
我不是虚拟化技术方面的专家,根本没有任何经验 - 欢迎更正。
这个答案的目的是让读者在概念上相信嵌套虚拟化是可能的,并概述要面对的问题。
逻辑处理器通过执行vmxon
进入VMX操作 - 一旦进入模式,处理器就处于根模式。
根模式是VMM的模式,它可以启动,恢复和处理VM。
然后,VMM使用vmptrld
设置当前VMCS(VM控制结构) - VMCS包含虚拟化guest虚拟机所需的所有元数据。
该VMCS的读写不是直接内存访问‡但vmread
和vmwrite
说明。
最后,VMM执行vmlaunch
以开始执行guest虚拟机。
现在,逻辑处理器正在虚拟化环境中执行。
假设guest虚拟机本身就是VMM,我们称之为非root VMM - 它需要重复上述步骤。
但英特尔在其手册中很清楚(手册3 - 第25.1.2章):
以下说明导致VM在VMX非root操作中执行时退出 :
[...]
VMX引入的说明也是如此,其中包括:
[...],VMLAUNCH
,VMPTRLD
,[...]和VMXON
vmxon
此指令导致VM退出,根VMM从上一次vmlaunch
之后的指令恢复,可以检查VMCS以查找退出的原因并采取适当的操作。
我不是一个经验丰富的VMM vmxon
所以我不确定根VMM必须做什么才能模拟这条指令 - 因为在VMX根模式下执行vmxon
会失败并执行vmxoff
后跟一个带有VM Region的vmxon
非root VMM似乎是一个安全漏洞(或导致它)我相信所有根VMM必须做的是记录guest虚拟机现在处于“VMX根模式”。
这里需要引号:此模式仅存在于软件中,当根VMM将控制权交还给非根VMM时,CPU将处于非root VMX模式。
之后,非根VMM将尝试使用vmptrld
设置当前VMCS。
vmptrld
将引发VM退出并且根VMM再次处于控制状态 - 如果CPU不支持VMCS镜像,则根VMM必须记录非根VMM给出的指针现在是当前VMCS - 如果CPU确实支持VMCS遮蔽的VMM设置其 VMCS由非根VMM给予VMCS(用于虚拟化的非根VMM的一个)的VMCS链接指针字段。
VMM以这种或那种方式知道哪个虚拟化VMCS是活动的。
非root VMM执行的vmread
和vmwrite
将会或不会导致VM退出。
如果VMCS阴影处于活动状态,则CPU将不执行VM Exit,而是读取活动VMCS(称为影子VMCS )中的VMCS链接指针所指向的VMCS 。
这将加速嵌套VM的虚拟化。
如果VMCS阴影未激活,则CPU将退出VM,并且根VMM必须模拟读/写。
最后,非root VMM将启动其VM - 这是一个嵌套的VM。
vmlaunch
将触发VM Exit。
根VMM必须做一些事情:
vmlaunch
/ vmresume
。 现在CPU正在执行嵌套VM(VVM - 虚拟VM?)。
当敏感指令或事件导致VM退出时会发生什么?
从处理器的角度来看,只有两个级别的虚拟化:根VMX模式和非根VMX模式。
由于guest虚拟机处于非root VMX模式,因此控制权将转移回根VMX模式代码 - 即根VMM。
根VMM现在必须了解该事件是来自其VM还是来自其VM的VM。
这可以通过跟踪vmlaunch
/ vmresume
的使用并检查VMCS中的位来完成。
如果VM Exit指向非根VMM,则根VMM必须加载其原始VMCS,最终在其中设置非根VMM的链接,更新非根VMM VMCS状态位并执行vmresume
。
如果VM Exit指向它,则根VMM将像任何其他VM Exit一样处理它。
如果我们想在嵌套VM中创建VM,该怎么办? 一种虚拟虚拟VM(VVVM)。
有两件事需要注意:
在AMD-v中没有root和非root模式,CPU开始使用vmrun
执行VM,该vmrun
接收指向VMCB(VM控制块)的指针,该VMCB与Intel的VMCS具有相同的用途。
在vmrun
,CPU处于访客模式。
VMCB已缓存,但只能通过常规内存访问来读取。
vmload
/ vmsave
指令显式加载到缓存中并从缓存中保存受缓存影响的VMCB字段。
这个界面比英特尔的界面更容易,但它同样强大 - 即使在嵌套虚拟化方面也是如此。
假设我们在VM中并且代码执行vmrun
- 因此我们正在虚拟化VMM。
从技术上讲,只要vmrun
将触发或不触发VM Exit,VMM就可以选择。
然而,实际上,AMD-v目前要求前者始终如此:
以下条件被视为非法国家组合:[...]
*VMRUN
截取位清零
因此,根VMM(我将使用与英特尔情况相同的术语)将获得控制并且必须模拟vmrun
(因为硬件仅支持单级虚拟化)。
根VMM可以将当前VMCB与非根VMM VMCB保存并合并,并按照英特尔情况继续使用vmrun
。
在退出时,root-VMM必须确定退出是指向它还是指向非根VMM,再次可以跟踪vmrun
和VMCB中的控制位。
我们在VM中建立了一个相对简单的虚拟机 - 现在虚拟机出口会发生什么?
根VMM接收退出,如果定向到非根VMM,则必须恢复其原始VMCB并恢复运行(即使用vmrun
及其原始VMCB)。
AMD-v通过考虑其地址访客地址来支持vmsave
和vmload
指令的快速虚拟化,因此受制于通常的页面嵌套虚拟化。
与英特尔的情况一样,只要VMM支持该功能,就可以再次嵌套虚拟化。
针对英特尔案例的重要安全警告也适用于AMD的案例。
‡由于其实现定义的格式以及内存区域可以用作未实时更新的溢出区域这一事实
在阅读了更多关于虚拟化的内容后,我偶然发现了虚拟机的这张票 。
这是一个功能请求,正是这个功能和阅读评论似乎VMware Workstation已经实现了它,所以它必须确实有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.