在虚拟环境里的代码当它执行某些指令或遇到某些事件后会退回到真实的系统环境中,这个状况我们就称为VMEXIT。虚拟环境里的代码是没有办法检测自己所处的运行环境,它也不知道自己的哪条指令触发了VMEXIT。 无条件引发VMEXIT的指令:CPUID、INVD、GETSEC、XSETBV、INVEPT、INVVPID、VMCALL、 VMCLEAR、VMLAUNCH、VMPTRLD、VMPTRST、VMREAD、VMWRITE、VMRESUME、VMXOFF、VMXON。VMFUNC是个例外,如果我们把enableVMfunctions置1它允许在虚拟环境里执行而不产生VMEXIT。 有条件引发VMEXIT的指令:这取决于PinBasedVMExecutionControls、PrimaryProcessorBasedVMExecutionControls、SecondaryProcessorBasedVMExecutionControls这三个VMCS区域的对应位设置。 Allotherbitsinthisfieldarereservedto0。SoftwareshouldconsulttheVMXcapabilityMSRIA32VMXPROCBASEDCTLS2(seeAppendixA。3。3)todeterminewhichbitsmaybesetto1。FailuretoclearreservedbitscausessubsequentVMentriestofail(seeSection26。2。1。1) Intel技术手册上有完整的设置说明,这里不再赘述。 对于无条件引发的vmexit我们必须提供对应的善后处理代码,我们尽量避免有条件引发VMEXIT的指令,以简化代码的工程量。 我们通过指令:learax,VMExitHandler invokevmxvmwrite,HOSTRIP,addrVMExitHandler 告诉CPU当无条件引发VMEXIT的指令执行时CPU从虚拟环境退出到真实环境时从VMExitHandler所指定的位置开始执行代码。 我们通过指令:learax,ExitReason movrcx,VMEXITREASON vmreadExitReason,VMEXITREASON 获取本次VMEXIT场景是由什么原因引起的。我们看下获取的数据结构: 其中前16位就是我们重点关注的对象: 也就是说总共有60多种原因都可以造成VMEXIT,我们将在下一篇中以源码形式讲解无条件引发的vmexit的处理方法以及页面保护。