导图社区 vol3-27-VM Exits
Intel Software Development Mannel 第28章-VMExits从头到尾跟踪完这个样本,就理解 VMProtect的入口出口,虚拟寄存器、虚拟栈。
编辑于2022-09-16 17:09:43 上海Virtualize APIC Accesses 功能可以单独开启,此时它的作用仅仅是将Guest APIC访问的VM Exit从EPT Violaton改为了APIC Access,对Guest的APIC访问仍需要以Trap-and-Emulate方式实现。
VMCS 的数据区包含了VMX配置信息:VMM在启动虚拟机前配置其哪些操作会触发VMExit。VMExit 产生后,处理器把执行权交给VMM 以完成控制,
系统软件可以通过CPUID指令来判断处理器是否支持VMX,如果CPUID.1.ECX.VMX[bit5] = 1,那么当前处理器支持VMX,否则,当前处理器不支持VMX功能。
社区模板帮助中心,点此进入>>
Virtualize APIC Accesses 功能可以单独开启,此时它的作用仅仅是将Guest APIC访问的VM Exit从EPT Violaton改为了APIC Access,对Guest的APIC访问仍需要以Trap-and-Emulate方式实现。
VMCS 的数据区包含了VMX配置信息:VMM在启动虚拟机前配置其哪些操作会触发VMExit。VMExit 产生后,处理器把执行权交给VMM 以完成控制,
系统软件可以通过CPUID指令来判断处理器是否支持VMX,如果CPUID.1.ECX.VMX[bit5] = 1,那么当前处理器支持VMX,否则,当前处理器不支持VMX功能。
VM Exits
1. 概述
在VM非根模式下,由于部分指令和事件导致VM退出,VM退出表现出以下操作
导致VM退出的信息被记录在VM-exit information field和VM-entry control field,以27.2记录的信息被修改
处理器状态记录在guest-state area(27.3)
MSRs可能被记录在VM-exit MSR-store area(27.4),该操作在激活SMI和SMM的dual-monitor对待的SMM VM exit中不存在
以下操作以并行/任意顺序进行
基于部分host-state area和部分VM-exit control保存处理器状态,在SMM VM exit 中也不存在
address-range监视会被清除
可能会从VM-exit MSR-load area载入MSRs(27.6),在SMM VM exit中该操作不存在
VM exit不会记录在last-branch records中,不要产生branch-trace message,不要更新branch-trace store
27.1说明了在VM exit开始之前的架构状态
27.2-27.6说明了VM退出表现出的操作
34.15描述了SMI和SMM的dual-monitor treatment,该treatment下,传统的转换到SMM模式变为了VM exit到一个分离的SMM monitor,该转换称为SMM VM exits,这些转换发生的原因为,在VMX根操作下,接收到了SMI,或者执行了VMCALL指令.
27.1 VM exit之前的架构状态
注意
如果在exception bitmap中的某个已发生异常的对应位为1,那么该异常直接触发VM exit
如果“NMI exiting” VM-execution control is 1,则一个NMI会直接触发VM exit
如果“external-interrupt exiting” VM-execution control is 1,则一个外部中断会直接触发VM exit
如果处理器状态为wait-for-SIPI activity状态,那么一个SIPI的到达会直接触发VM exit
如果处理器状态不在wait-for-SIPI activity状态,那么INIT信号的到达会直接触发VM exit
如果 exception, NMI, external interrupt, or software interrupt不直接发生,而是交付了一个事件,该事件引起了导致VM exit的nested exception,double fault, task switch, APIC access, EPT violation, EPT misconfiguration, page-modification log-full event , or SPPrelated event ,称为非直接导致VM exit
针对VM exits,决定合适更新/不更新架构状态
如果事件直接导致VM退出,则它不会像没有导致VM退出那样更新架构状态
debug exception
page fault
NMI
external interrupt
flags L0 – L3 in DR7
task switch
last-exception record
处理器inactive状态 -> active状态
MTF VM exits
如果事件导致VM间接退出,则该事件会更新架构状态:
debug exception
page fault
NMI
external interrupt
处理器inactive状态 -> active状态
STI/MOV SS 阻塞
处理器状态、IDT
last-exception records的对待与实现有关
部分处理器做last-exception records
部分处理器不做last-exception records
virtual-NMI blocking 的效力期限
IRET执行遇到部分事件 +“NMI exiting”control为0 -> NMI blocking清除(VM exit开始之前)
IRET执行遇到部分事件 +“virtual NMIs”control为1 -> virtual-NMI blocking清除(VM exit开始之前)
an x87 FPU Floating-Point Error (#MF)或由于an x87 FPU Floating-Point Error (#MF)非阻塞的部分事件直接导致VM退出,那么在VM exit开始时不对STI/MOV SS进行阻塞
last-branch record记录生成条件(IDT)
如果machine-check exception导致VM exit,处理器状态为不确定的,并且该状态会存储到guest-state area. 从这种VM exit resume a guest时应该consult 特定MSR的部分RIPV和EPIV.
执行部分指令时遇到部分异常/事件,那么该指令的数据断点会被识别,并且相关信息会被存储到pending debug exceptions field(除非VM exit清除了该域).
部分VM Exit被认为发生在指令执行之后
debug traps((single-step, I/O breakpoints, and data breakpoints))导致的VM exits
debug exceptions(data breakpoints),其recognition被MOV SS 的阻塞 delay. 该debug exception导致的VM exits
部分machine-check exceptions导致的VM exits
当 “CR8-load exiting” VM-execution control is 0 and the “use TPR shadow” VM-execution control is 1 时,MOV to CR8导致的Trap-like VM exits(只在64bit模式发生)
当“use MSR bitmaps” VM-execution control is 1; the value of ECX is in the range 800H–8FFH; and the bit corresponding to the ECX value in write bitmap for low MSRs is 0; and the “virtualize x2APIC mode” VM-execution control is 1时,WRMSR导致的Trap-like VM exits
APIC-write emulation(APIC访问作为部分指令执行的结果)导致的VM exits
对于这些VM exits,这些指令对架构状态的修改在VM exit发生之前完成. 这些修改包含对逻辑处理器可中断性的修改(Table24-3). 如果在这些指令执行之前,被MOV SS,POP SS,STI阻塞,这些阻塞将不再起作用.
在enclave mode发生的VM exit 将 exit-Reason field的bit27和guest interruptibility-state field的bit4置为1. 在该VM exit交付之前,会发生Asynchronous Enclave Exit (AEX) . AEX会修改架构状态,处理器会建立以下架构状态.
清除RFLAGS中的CF, PF, AF, ZF, SF, OF, and RF
FS和GS恢复为它们在最近enclave entry之前的值
interrupted enclave thread的AEP会被使用以载入RIP
RSP从enclave's state-area(SSA)的URSP field载入
27.6 载入MSRs
VM exit会从VM-exit MSR-load area载入到MSRs中.
VM-exit MSR-load area中的每个条目被按顺序处理,目的是载入以 bit31:0为索引的MSR,利用WRMSR写入到bits127:64中
条目的处理在部分情况下会失败,见27.6
如果任意一个条目的处理失败,就会产生一个VMX abort
如果载入任意一个MSR时,都使用需要TLB flush的方法,这些TLB被更新以在VM exit之后逻辑处理器可以不需要使用任何在transition之前cached的translation.
27.7 VMX Aborts
在VM exit时出现问题,VMX Abort就会发生.
VMX Abort会将处理器的状态设置为shutdown
VMX abort不修改active VMCS中的任何数据,因此在VMX abort之后这些数据都是不可靠的.
VMX abort时,逻辑处理器将一个非零32bit VMX-abort indicator filed保存到VMCS的offset4,该VMCS为导致VMX abort的那个VMCS.
VMX-abort indicator filed中存储着导致VMX abort的原因,有6个. 当原因有多个时,可能会随机使用其中一个.
保存guest MSR出错
PDPTE的host checking出错
current VMCS崩溃导致VM exit无法完成
载入host MSR出错
VM exit时发生machine-check event
VM exit之前逻辑处理器处于IA-32e模式,并且“host address-space size” VM-entry control was 0
逻辑处理器从不读VMCS Region中的VMX-abort indicator,而对于写,只有在发生上面6种情况之一时才会写入32bit非零值.
VMX-abort indicator允许一个逻辑处理器上的软件诊断另一个逻辑处理器上的VMX abort信息.因此建议以VMX root操作运行的软件将其使用的任何VMCS区域中的VMX abort indicator清零.
保存VMX-abort indicator之后,处理器要做的操作取决于该处理器是否处于SMX Operation.
是,则发生Intel TXT shutdown
否,则处理器提交一个特殊bus cycle(通知chipset),并且进入VMX-abort shutdown state. 只有REST event 能够唤醒处于VMX-abort shutdown state的逻辑处理器.像machine-check、 INIT信号、外部中断、NMI、SIPI、SMI都不管用.
27.8 VM Exit期间的machine-check事件
如果VM exit期间发生machine-check事件,以下情况之一会发生
像发生在VM exit之前一样,处理machine-check事件,根据CR4.MCE值不同,处理方法有所不同
machine-check事件在VM exit完成之后会被处理
产生VMX abort,对待该abort像对待其他abort一样. 该abort indicator为5
如果machine-check事件发生在host state载入之后,那么第一种该情况不可能发生. 第二种情况只在VM entry能载入所有host state时可能会发生.
27.5 载入Host State
VM exit时会以以下方式更新处理器状态
部分状态从host-state area载入或取决于host-state area的内容
部分状态取决于VM-exit controls
部分状态在每一次VM exit时都会以相同方式建立
page-directory pointers基于特定控制寄存器载入
顺序不确定
在64bit架构的处理器上,无论VM exit前后逻辑处理器的模式如何, 都会加载每个加载的64位域的完整值(例如,GDTR的基地址)
只有在“host address-space size” VM-exit control is 1时,VM exit之后逻辑处理器才有可能在IA-32e模式. 如果在VM exit之前逻辑处理器处于IA-32e模式,并且该control为0,就会发生VMX abort错误.
除了载入host state,VM exits还清除了address-range monitoring.
只有在稳定载入Host State后,才会发生载入MSR
载入Host Control Registers、Debug Registers、MSRs
VM exits会向host control Register、Debug Register、部分MSRs载入新的值
除了CR0、CR3、CR4的部分域在特定情况下不被更新,部分域在特定情况下设定固定值, 其他域都由对应的CR0、CR3、CR4域(host state field)载入
DR7直接设置为400H
部分MSR被设定为固定值,且根据是否支持64bit模式设置高32bit
根据部分控制(control)设置部分寄存器值
FS.base和GS.base比较特殊,见27.6
载入Host Segment和Descriptor-Table Registers
段寄存器和TR载入时,分为载入selector和base
selector在特定情况下可被载入为0,此时segment unsable
base address
segment limit
type filed 和 S bit
DPL
P bit
CS.L
D/B
G
host-state area中不包含针对LDTR的selector域,LTDR在所有VM exits中都有同样的设置
GTDR和IDTR的base address从host-state area中的对应域载入
载入Host RIP、RSP、RFLAGS
RIP、RSP从host-state area的对应域载入,RFLAGS除了bit1外都清0,bit1一直是1
检查并载入Host Page-Directory-Pointer-Table entry(PDPTE)
逻辑处理器使用PAE paging时,CR3参考的是PDPTE.
当使用PAE paging时,Mov to CR3检查PDPTE的有效性, 如果有效,则将PDPTE载入处理器(中的non-architectural寄存器)
如果VMCS的host-state area的CR4的bit5为1,且the “host address-space size” VM-exit control is 0,那么VMM exit退出到使用PAE paging的VMM. 这样的VM exit可能会检查PDPTEs(VMCS中的Host-state area的CR3参考的PDPTE). 这样的VM exit必须检查PDPTE的有效性(当VM exit之前没有使用PAE paging,或者VM exit改变了CR3 的值). VM exit退出到不使用APE paging的VMM时,不需要检查PDPTEs的有效性.
当PAE paging在使用时,用Mov to CR3载入CR3使用的检查和对PDPTE的有效性检查相同
如果Mov to CR3由于PDPTE的有效性导致了一个#GP,会发生VMX abort. 如果VM exit退出到使用PAE的VMM没有产生VMX abort,那么PDPTE会像使用Mov to CR3一样被载入到CPU中去
更新非寄存器域
VM exit后,逻辑处理器总是处于active状态
事件阻塞
VM exit之后,不存在STI和MOV SS产生的阻塞
NMI直接导致的VM exits导致NMI引起的阻塞. 其他VM exit不影响NMI阻塞
VM exit之后没有挂起的debug exception
invalidate cached mappings
如果“enable VPID” VM-execution control is 0, 逻辑处理器对与VPID 0000H有联系的linear mapping和combined mappings进行invalidate操作.VPID 0000H的combined mapping对所有EP4TA invalidate(EP4TA is the value of bits 51:12 of EPTP)
VM exits无需对任何guest-physical mapping做invalidate,如果 “enable VPID” VM-execution control is 1,页无需对任何linear mapping和combined mapping做invalidate
清除 address-range monitoring
x86软件可以使用MONITOR和MWAIT指令监视特定地址范围.
VM Exit对所有可能起作用的地址范围监视进行清除.
27.4 保存MSRs
当处理器状态保存到guest-state之后,MSRs的值将被保存到VM-exit MSR-store area
每个VM-exit MSR-store area的条目(index的范围由VM-exit MSR-store count指定)以bit31:0为索引按顺序存储到bit127:64的方法处理
条目的处理在以下情况下会失败
bit31:8的值为000008H,意为索引的MSR是一个当local APIC 为x2APIC模式时,允许访问APIC寄存器的MSR
bit31:0指明某个MSR只能在SMM模式下读取,VM exit将不会在SMM模式结束
bit31:0指明某个MSR由于model-specific的原因不能在VM exits时被保存.[某些处理器可能禁止特定MSR不能在VM exits时保存,即使可以使用RDMSR读取]
entry的bit63:32不是全0
如果在CPL=0时使用RDMSR读取以bit31:0索引的MSR,将会发生#GP
如果处理某个条目失败,会发生一个VMX abort
27.3 保存Guest State
VM exits会将处理器状态的特定组件保存到VMCS的guest-state的对应域中
在支持64位架构的CPU上,无论逻辑处理器在VM exit前后处于何种模式, guest-state的每个域的最长宽度都会被全部保存.
通常保存的状态是VM exit开始时逻辑处理器中的状态
以下说明的保存到的域都是Guest state域的子域
保存控制寄存器、Debug寄存器、MSRs
27.3.1说明了保存什么寄存器、什么情况下保存特定寄存器
保存段寄存器和描述符表寄存器
段寄存器的保存取决于在VM exit之前该寄存器是否为unusable.
IDTR和GDTR保存到相应的base-address和limit域中
保存RIP、RSP和RFLAGS
根据导致VM exit的原因的不同,保存到RIP域中的值也相应变化
RSP直接保存到RSP域
除了RF,FLAGS中的其他bit都被保存到guest-state的RFLAGS域中
RF根据导致VM exit的原因不同,保存到RF域中的值也就不同
保存非寄存器域
Activity state
VM exit之前的逻辑处理器activity状态
Interruptibility state
VM exit之前的逻辑处理器的可中断性
根据部分control和所处模式,对特定位有不同的设置
Pending debug exceptions
除了部分VM exit情况,其余情况该域都置0
对于不置0的情况,与breakpoint、INIT信号、machine-check、SMI、TPR below Threshold、monitor trap flag其中的一个或几个有关.
其它bit的设置与各个详细情况有关
VMX-preemption timer value
与一个control有关.
Page-directory-pointer-table entries
与2个control有关.
27.2 记录VM-Exit信息 & 更新VM-Entry控制域
VM exits以记录VM exit的nature和原因到VM-exit信息域开始
除了更新VM exit信息域外,还清除VM entry中断信息域中的有效位(第31位)
如果IA32_VMX_MISC MSR的bit 5 读为1,IA32_EFER.LMA的值会被存储到 “IA-32e mode guest” VM-entry control
基础VM-Exit信息
Exit Reason
Exit Reason(Bit15:0)
如果在逻辑处理器在enclave mode时发生VM exit,bit 27会被置1
此类VM Exits包括中断、NMI、SMI、INIT信号、enclave模式下发生的异常以及将这些事件交付到enclave模式时发生的异常所触发的VM Exits. 如果VM Exit与由VM entry注入的事件的交付有关,并且guest可中断性状态域指示enclave中断(该域的bit4为1),那么VM exit也会置此bit(bit 27)为1
这些域的剩余位会被清除为0(SMM VM exits可能会设置某些bit)
Exit qualification
以下原因造成的VM exits会保存该域
debug exceptions
page-fault exceptions
...
SPP-related events
对于不同的原因,该域包含的信息含义有所不同,具体看27.2.1的Exit qualification部分
对于其它VM exits,该域会被clear
Guest linear address
对于部分VM exits,该域接收属于该VM exits的线性地址,该域根据不同的VM exits有不同的设置,具体见27.2.1的Guest linear address部分
Guest-physical address
对于EPT违规、EPT误配置、SPP相关事件导致的VM exits,该域接收导致了EPT违规或EPT误配置的guest-physical地址.对于其他VM exits,该域为undefined.
如果EPT违规或EPT误配置发生在在enclave mode执行一个指令期间(并且不在向enclave mode交付事件期间),该域的bit11会被清0
由Vectored Events导致的VM Exits信息
27.2.2的开头列出了导致VM exits的Vectored的事件.
VM-exit interruption information
详细说明了根据事件的不同如何设置该域
VM-exit interruption error code
对于对VM-exit interruption information 的bit11和bit31都设置的VM exit, 该域接收错误码,并说明了该域的详细设置.对于其他类型的VM exit,该域为Undefined.
由于IRET导致的NMI unblocking信息
执行IRET时由于部分原因导致的VM exit
Faults
EPT违规
page-modification log full events
SPP-related events
当NMI被阻塞时,开始执行IRET将会解除阻塞NMI,即使发生一个fault/VM exit,被这样的VM exit保存的状态会指明NMI没有被阻塞.
由于上面的原因导致的VM exits会通过保存一个称为NMI unblocking due to IRET的bit提供给软件更多的信息.该bit在3种情况下为"defined".在其他情况下为"undefined".defined的详细bit见27.2.3
either the “NMI exiting” VM-execution control is 0 or the “virtual NMIs” VM-execution control is 1
the VM exit does not set the valid bit in the IDT-vectoring information field
the VM exit is not due to a double fault
对于引起VM exit的原因不同,会由不同的保存信息的方法,见27.2.3倒数第一、二段
在事件交付期间的VM Exit信息
当通过IDT交付事件并且以下情况发生,则触发VM exits
事件交付发生fault导致VM exit
IDT中的task gate引起task switch.VM exit只有 在task switch的出事checks通过之后
事件交付导致APIC Access VM exit
在交付期间发生EPT违规、EPT误配置、page-modification log-full event、SPP-related event.
IDT-vectoring information、IDT-vectoring error code这两个 域只有在事件交付作为VM entry的部分注入时,才会被使用
在以下任何情况下,均不认为在事件传递过程中发生了VM exit
原始event直接触发VM exit
原始event导致的#DF直接触发VM exit
VM exit是由于获取事件交付调用的处理程序的第一条指令而导致的
VM exit是由tripple fault导致的
27.2.4的最后部分展示了IDT-vectoring information、IDT-vectoring error code的细节设置
指令执行导致的VM Exit信息
VM-exit instruction length
在部分情况下接收导致VM exit的指令长度(字节)
如果在交付软件异常、高级软件异常、交付VM entry注入的事件时发生的软件异常过程中发生了VM exit,如果原始事件是作为VM entry的一部分注入的,那么该域接收VM-entry的指令长度(字节)
其他情况下的VM exits对该域为undefined.
如果VM exits在enclave mode发生,该域被置空
VM-exit instruction information.
该域的格式(Table27-8~27-14)取决于导致VM exit的指令本身.
用于接收导致VM exit的指令信息
其他情况下的VM exits对该域为undefined.
如果VM exits在enclave mode发生,该域被置空
I/O RCX, I/O RSI, I/O RDI, I/O RIP
这些域只在SMI在IO指令执行完成后到达导致的SMM VM exits情况下有效
如果VM exits在enclave mode发生,该域被置空