目录 25 虚拟机控制结构
25.1 概述
逻辑处理器在进行 VMX 操作时使用虚拟机控制数据结构 (VMCS)。它们管理进出 VMX non-root operation(VM entry和 VM Exits)的转换以及 VMX non-root operation中的处理器行为。该结构由新指令 VMCLEAR、VMPTRLD、VMREAD 和 VMWRITE 操作。
VMM 可以为其支持的每个虚拟机使用不同的 VMCS。对于具有多个逻辑处理器(虚拟处理器)的虚拟机,VMM 可以为每个虚拟处理器使用不同的 VMCS。
逻辑处理器将内存中的一个区域与每个 VMCS 相关联。该区域称为 VMCS 区域。 软件使用区域的 64 位物理地址(VMCS 指针)引用特定的 VMCS。 VMCS 指针必须在 4 KB 边界上对齐(位 11:0 必须为零)。这些指针设置的位不得超出处理器的物理地址宽度。
逻辑处理器可以维护多个活动的VMCS。处理器可以通过在存储器、处理器或两者中维护活动VMCS的状态来优化VMX操作。在任何给定时间,最多一个活动 VMCS 是当前 VMCS。 (本文档经常使用术语“VMCS”来指代当前 VMCS。)VMLAUNCH、VMREAD、VMRESUME 和 VMWRITE 指令仅在当前 VMCS 上运行。
以下各项描述了逻辑处理器如何确定哪些 VMCS 处于活动状态以及哪些 VMCS 是当前的:
VMPTRLD指令的存储器操作数是VMCS的地址。执行该指令后,该 VMCS 在逻辑处理器上既是活动的又是当前的。任何其他曾经处于活动状态的 VMCS 仍然保持活动状态,但没有其他 VMCS 处于当前状态。
当前 VMCS 中的 VMCS 链接指针字段(参见第 25.4.2 节)本身就是 VMCS 的地址。如果通过“VMCS shadowing” VM-execution control的 1 设置成功执行 VM entry,则 VMCS 链接指针字段引用的 VMCS 在逻辑处理器上变为活动状态。当前VMCS的标识不会改变。
VMCLEAR指令的存储器操作数也是VMCS的地址。执行该指令后,VMCS 在逻辑处理器上既不是活动的也不是当前的。如果VMCS在逻辑处理器上是当前的,则逻辑处理器不再具有当前的VMCS。
VMPTRST 指令将逻辑处理器当前 VMCS 的地址存储到指定的内存位置(如果当前没有 VMCS,则存储值 FFFFFFFF_FFFFFFFFH)。
VMCS 的启动状态决定了该 VMCS 应该使用哪个 VM entry指令:VMLAUNCH 指令需要启动状态为“清除”的 VMCS; VMRESUME 指令需要启动状态为“已启动”的 VMCS。逻辑处理器在相应的VMCS区域中维护VMCS的启动状态。以下各项描述了逻辑处理器如何管理 VMCS 的启动状态:
如果当前VMCS的启动状态为“清除”,则成功执行VMLAUNCH指令将启动状态更改为“已启动”。
VMCLEAR指令的存储器操作数是VMCS的地址。执行指令后,VMCS 的启动状态为“清除”。
没有其他方法可以修改 VMCS 的启动状态(无法使用 VMWRITE 进行修改),也没有直接的方法来发现它(无法使用 VMREAD 进行读取)。
图 25-1 说明了 VMCS 的不同状态。它使用“X”来指代 VMCS,使用“Y”来指代任何其他 VMCS。因此:“VMPTRLD X”始终使 X 当前且处于活动状态; “VMPTRLD Y”总是使 X 不是当前的(因为它使 Y 成为当前的);如果 X 是当前的且其启动状态为“清除”,则 VMLAUNCH 使 X 的启动状态“已启动”; VMCLEAR X 始终使 X 处于非活动状态且不是当前状态,并使其启动状态“clear”。
该图没有示出不修改与这些参数相关的VMCS状态的操作(例如,当X已经是当前时执行VMPTRLD X)。请注意,即使 X 的当前状态未定义(例如,即使 X 尚未初始化),VMCLEAR X 也会使 X 成为“非活动的、非当前的且清除的”。参见第 25.11.3 节。
由于影子 VMCS(请参阅第 25.10 节)不能用于 VM entries,因此影子 VMCS 的启动状态没有意义。图 25-1 并未说明使影子 VMCS 处于活动状态的所有方式。
25.2 VMCS 区域的格式
VMCS 区域最多包含 4 KB。VMCS 区域的格式在表 25-1 中给出。
VMCS 区域的前 4 个字节包含位 30:0 处的 VMCS 修订标识符。以不同格式(见下文)维护 VMCS 数据的处理器使用不同的 VMCS 修订标识符。这些标识符使软件能够避免在使用不同格式的处理器上使用为一个处理器格式化的 VMCS 区域。该 4 字节区域的第 31 位指示 VMCS 是否为影子 VMCS(请参阅第 25.10 节)。
在将 VMCS 区域用于 VMCS 之前,软件应将 VMCS 修订标识符写入 VMCS 区域。 VMCS 修订标识符永远不会由处理器写入;如果其操作数引用其 VMCS 修订标识符与处理器使用的 VMCS 修订标识符不同的 VMCS 区域,则 VMPTRLD 会失败。 (如果影子 VMCS 指示器为 1 并且处理器不支持“VMCS 影子”VM 执行控制的 1 设置,VMPTRLD 也会失败;请参阅第 25.6.2 节)软件可以发现处理器使用的 VMCS 修订标识符通过读取 VMX 功能 MSR IA32_VMX_BASIC(参见附录 A.1)。
软件应根据 VMCS 是普通 VMCS 还是影子 VMCS 来清除或设置影子 VMCS 指示符(请参见第 25.10 节)。如果设置了影子 VMCS 指示符并且处理器不支持“VMCS 影子”VM 执行控制的 1 设置,则 VMPTRLD 会失败。软件可以通过读取 VMX 功能 MSR IA32_VMX_PROCBASED_CTLS2 来发现对此设置的支持(请参阅附录 A.3.3)。
VMCS 区域的接下来 4 个字节用于 VMX 中止指示符。这些位的内容不以任何方式控制处理器操作。如果发生 VMX 中止,逻辑处理器会将非零值写入这些位(请参见第 28.7 节)。软件也可以写入该字段。
VMCS 区域的其余部分用于 VMCS 数据(VMCS 中控制 VMX non-root operation和 VMX 转换的部分)。这些数据的格式是特定于实现的。 VMCS 数据在第 25.3 节到第 25.9 节中讨论。为了确保 VMX 操作中的正确行为,软件应在回写可缓存内存中维护 VMCS 区域和相关结构(第 25.11.4 节中列举)。未来的实现可能允许或需要不同的内存类型。软件应参考 VMX 功能 MSR IA32_VMX_BASIC(参见附录 A.1)
25.3 VMCS数据的组织
VMCS 数据分为六个逻辑组:
Guest-state区。处理器状态在 VM Exits时保存到客户状态区域,并在 VM entry时从那里加载。
Host-state地区。处理器状态在 VM Exits时从host状态区域加载。
VM 执行控制字段。这些字段控制 VMX non-root operation中的处理器行为。它们在一定程度上决定了虚拟机退出的原因。
VM Exits控制字段。这些字段控制VM Exits。
VM entry控制字段。这些字段控制VM条目
VM Exits信息字段。这些字段接收有关 VM Exits的信息并描述 VM Exits的原因和性质。在某些处理器上,这些字段是只读的。
VM执行控制字段、VM退出控制字段和VM进入控制字段有时统称为VMX控制。
25.4 Guest-state区
本节描述 VMCS 的guest 状态区域中包含的字段。 VM entries从这些字段加载处理器状态,VM 出口将处理器状态存储到这些字段中。详细信息请参见第 27.3.2 节和第 28.3 节。
25.4.1 Guest Register状态
客户态区域中的以下字段对应于处理器寄存器:
控制寄存器 CR0、CR3 和 CR4(各 64 位;在不支持 Intel 64 架构的处理器上为 32 位)。
调试寄存器 DR7(64 位;在不支持 Intel 64 架构的处理器上为 32 位)。
RSP、RIP 和 RFLAGS(各 64 位;在不支持 Intel 64 架构的处理器上为 32 位)。
每个寄存器 CS、SS、DS、ES、FS、GS、LDTR 和 TR 的以下字段:
每个寄存器 GDTR 和 IDTR 的以下字段:
基地址(64 位;在不支持 Intel 64 架构的处理器上为 32 位)。
限制(32 位)。限制字段包含 32 位,即使这些字段在架构中仅指定为 16 位。
以下 MSR:
IA32_DEBUGCTL(64 位)
IA32_SYSENTER_CS(32 位)
IA32_SYSENTER_ESP 和 IA32_SYSENTER_EIP(64 位;在不支持 Intel 64 架构的处理器上为 32 位)
IA32_PERF_GLOBAL_CTRL(64 位)。仅在支持“加载 IA32_PERF_GLOBAL_CTRL”VM entries控制的 1 设置的处理器上才支持此字段。
IA32_PAT(64 位)。仅在支持“加载 IA32_PAT”VM entry控制或“保存 IA32_PAT”VM Exits控制 1 设置的处理器上才支持此字段。
IA32_EFER(64 位)。仅在支持“加载 IA32_EFER”VM entry控制的 1 设置或“保存 IA32_EFER”VM Exits控制的 1 设置的处理器上才支持此字段。
— IA32_BNDCFGS(64 位)。仅在支持“加载 IA32_BNDCFGS”VM entry控制的 1 设置或“清除 IA32_BNDCFGS”VM Exits控制的处理器上支持此字段。
IA32_RTIT_CTL(64 位)。该字段仅在支持“加载 IA32_RTIT_CTL”VM entry控制的 1 设置或“清除 IA32_RTIT_CTL”VM Exits控制的处理器上受支持。
IA32_LBR_CTL(64 位)。仅在支持“加载guest IA32_LBR_CTL”VM entry控制的 1 设置或“清除 IA32_LBR_CTL”VM Exits控制的 1 设置的处理器上才支持此字段。
IA32_S_CET(64 位;在不支持 Intel 64 架构的处理器上为 32 位)。该字段仅在支持“加载 CET 状态”VM entries控制 1 设置的处理器上受支持。
IA32_INTERRUPT_SSP_TABLE_ADDR(64 位;在不支持 Intel 64 架构的处理器上为 32 位)。该字段仅在支持“加载 CET 状态”VM entries控制 1 设置的处理器上受支持。
IA32_PKRS(64 位)。仅在支持“加载 PKRS”VM entries控制 1 设置的处理器上才支持此字段。
影子堆栈指针寄存器 SSP(64 位;在不支持 Intel 64 架构的处理器上为 32 位)。该字段仅在支持“加载 CET 状态”VM entries控制 1 设置的处理器上受支持。
寄存器 SMBASE(32 位)。该寄存器包含逻辑处理器的 SMRAM 映像的基地址。
25.4.2 Guest Non-Register状态
除了第 25.4.1 节中描述的寄存器状态之外,客户状态区域还包括以下表征客户状态但不对应于处理器寄存器的字段:
活动状态(32 位)。该字段标识逻辑处理器的活动状态。当逻辑处理器正常执行指令时,它处于活动状态。某些指令的执行和某些事件的发生可能导致逻辑处理器转变到停止执行指令的非活动状态。
定义了以下活动状态:
0:活跃。逻辑处理器正在正常执行指令
1:HLT。逻辑处理器处于非活动状态,因为它执行了 HLT 指令
2:关机。逻辑处理器处于非活动状态,因为它发生了三重故障 2 或某些其他严重错误。
3:等待SIPI。逻辑处理器处于非活动状态,因为它正在等待启动 IPI (SIPI)。
未来的处理器可能包括对其他活动状态的支持。软件应读取 VMX 功能 MSR IA32_VMX_MISC(请参阅附录 A.6)以确定支持哪些活动状态。
中断状态(32 位)。 IA-32 架构包括允许某些事件被阻止一段时间的功能。该字段包含有关此类阻止的信息。该字段的详细信息和格式如表 25-3 所示。
待处理的调试异常(64 位;在不支持 Intel 64 架构的处理器上为 32 位)。 IA-32 处理器可能会识别一个或多个调试异常,但不会立即传送它们。1 该字段包含有关此类异常的信息。该字段的描述如表25-4所示。
VMCS 链接指针(64 位)。如果“VMCS 影子”VM 执行控制为 1,则 VMREAD 和 VMWRITE 指令访问该指针引用的 VMCS(请参见第 25.10 节)。否则,软件应将此字段设置为 FFFFFFFF_FFFFFFFFH 以避免 VM entry失败(请参见第 27.3.1.5 节)。
VMX-抢占定时器值(32 位)。仅支持“激活 VMX 抢占计时器”VM 执行控制 1 设置的处理器支持此字段。该字段包含 VMX 抢占计时器在具有该设置的下一个 VM entries之后将使用的值。请参见第 26.5.1 节和第 27.7.4 节。
页目录指针表条目(PDPTE;每个 64 位)。这四 (4) 个字段(PDPTE0、PDPTE1、
PDPTE2 和 PDPTE3)仅在支持“启用 EPT”VM 执行控制设置 1 的处理器上受支持。它们对应于使用 PAE 分页时 CR3 引用的 PDPTE(请参阅英特尔® 64 和 IA-32 架构软件开发人员手册第 3A 卷中的第 4.4 节)。仅当“启用 EPT”VM 执行控制为 1 时才使用它们。
guest 中断状态(16 位)。仅在支持“虚拟中断传送”VM 执行控制 1 设置的处理器上才支持该字段。它描述了客户虚拟 APIC 状态的一部分,并且不对应于任何处理器或 APIC 寄存器。它包含两个 8 位子字段:
请求虚拟中断 (RVI)。这是guest 中断状态的低字节。处理器将此值视为正在请求服务的最高优先级虚拟中断的向量。 (值 0 表示没有此类中断。)
服务虚拟中断 (SVI)。这是guest 中断状态的高字节。处理器将此值视为正在服务的最高优先级虚拟中断的向量。 (值 0 表示没有此类中断。)
有关该字段使用的更多信息,请参阅第 30 章。
PML 索引(16 位)。该字段仅在支持“启用 PML”VM 执行控制 1 设置的处理器上受支持。它包含页面修改日志中下一个条目的逻辑索引。由于页面修改日志包含 512 个条目,因此 PML 索引通常是 0-511 范围内的值。页面修改日志和 PML 索引的使用的详细信息在第 29.3.6 节中给出。
25.5 Host-state区域
本节描述 VMCS 的host状态区域中包含的字段。如前所述,处理器状态在每个 VM Exits时从这些字段加载(参见第 28.5 节)。
host状态区域中的所有字段都对应于处理器寄存器:
CR0、CR3 和 CR4(各 64 位;在不支持 Intel 64 架构的处理器上为 32 位)。
RSP 和 RIP(各 64 位;在不支持 Intel 64 架构的处理器上为 32 位)
段寄存器 CS、SS、DS、ES、FS、GS 和 TR 的选择器字段(每个 16 位)。 LDTR 选择器的host状态区域中没有字段。
FS、GS、TR、GDTR 和 IDTR 的基地址字段(各 64 位;在不支持 Intel 64 架构的处理器上为 32 位)。
以下 MSR:
IA32_SYSENTER_CS(32 位)
IA32_SYSENTER_ESP 和 IA32_SYSENTER_EIP(64 位;在不支持 Intel 64 架构的处理器上为 32 位)。
IA32_PERF_GLOBAL_CTRL(64 位)。仅在支持“加载 IA32_PERF_GLOBAL_CTRL”VM Exits控制设置为 1 的处理器上才支持此字段。
IA32_PAT(64 位)。该字段仅在支持“加载 IA32_PAT”VM Exits控制 1 设置的处理器上受支持。
IA32_EFER(64 位)。仅在支持“加载 IA32_EFER”VM Exits控制的 1 设置的处理器上才支持此字段。
IA32_S_CET(64 位;在不支持 Intel 64 架构的处理器上为 32 位)。该字段仅在支持“加载 CET 状态”VM Exits控制 1 设置的处理器上受支持。
IA32_INTERRUPT_SSP_TABLE_ADDR(64 位;在不支持 Intel 64 架构的处理器上为 32 位)。仅在支持“加载 CET 状态”VM Exits控制 1 设置的处理器上才支持此字段。
IA32_PKRS(64 位)。仅在支持“加载 PKRS”VM Exits控制 1 设置的处理器上才支持此字段。
影子堆栈指针寄存器 SSP(64 位;在不支持 Intel 64 架构的处理器上为 32 位)。该字段仅在支持“加载 CET 状态”VM Exits控制 1 设置的处理器上受支持。
除了此处标识的状态之外,某些处理器状态组件在每个 VM Exits时都加载有固定值;host状态区域中没有与这些组件对应的字段。有关如何在 VM Exits时加载状态的详细信息,请参阅第 28.5 节。
25.6 VM 执行控制字段
VM 执行控制字段管理 VMX non-root operation。这些在第 25.6.1 节到第 25.6.8 节中进行了描述。
25.6.1 基于引脚的 VM 执行控制
基于引脚的 VM 执行控件构成一个 32 位向量,用于管理异步事件(例如:中断)的处理。1 表 25-5 列出了控件。请参阅第 28 章,了解这些控制如何影响 VMX non-root operation中的处理器行为。
该字段中的所有其他位均被保留,有些为 0,有些为 1。软件应参考 VMX 功能 MSR IA32_VMX_PINBASED_CTLS 和 IA32_VMX_TRUE_PINBASED_CTLS(请参阅附录 A.3.1)来确定如何设置保留位。未能正确设置保留位会导致后续 VM entries失败(请参阅第 27.2.1.1 节)。
第一批支持虚拟机扩展的处理器仅支持位 1、2 和 4 的 1 设置。VMX 功能 MSR IA32_VMX_PINBASED_CTLS 将始终报告这些位必须为 1。支持任何位的 0 设置的逻辑处理器这些位中的一些将支持 VMX 功能 MSR IA32_VMX_TRUE_PIN_BASED_CTLS MSR,并且软件应查阅此 MSR 以发现对这些位的 0 设置的支持。不知道这些位中任何一位的功能的软件应将该位设置为 1。
25.6.2 基于处理器的VM执行控制
基于处理器的 VM 执行控制构成了三个向量,它们管理同步事件的处理,主要是由特定指令的执行引起的事件。1 这些是基于处理器的主 VM 执行控制(32 位)、辅助处理器-基于 VM 执行控制(32 位)和三级 VM 执行控制(64 位)。
表 25-6 列出了主要的基于处理器的 VM 执行控制。有关这些控制如何影响 VMX non-root operation中处理器行为的更多详细信息,请参阅第 26 章。
该字段中的所有其他位均被保留,有些为 0,有些为 1。软件应参考 VMX 功能 MSR IA32_VMX_PROCBASED_CTLS 和 IA32_VMX_TRUE_PROCBASED_CTLS(请参阅附录 A.3.2)来确定如何设置保留位。未能正确设置保留位会导致后续 VM entries失败(请参阅第 27.2.1.1 节)。
第一批支持虚拟机扩展的处理器仅支持位 1、4–6、8、13–16 和 26 的 1 设置。VMX 功能 MSR IA32_VMX_PROCBASED_CTLS 将始终报告这些位必须为 1。 逻辑处理器支持任何这些位的 0 设置将支持 VMX 功能 MSR IA32_VMX-_TRUE_PROCBASED_CTLS MSR,并且软件应查阅此 MSR 以发现对这些位的 0 设置的支持。不知道这些位中任何一位的功能的软件应将该位设置为 1。
基于主处理器的VM执行控制的位31确定是否使用基于辅助处理器的VM执行控制。如果该位为 0,VM entries和 VMX non-root operation的作用就好像所有基于辅助处理器的 VM 执行控制均为 0。仅支持基于主处理器的 VM 执行的位 31 的 0 设置的处理器控件不支持基于辅助处理器的 VM 执行控件。
表 25-7 列出了基于辅助处理器的 VM 执行控制。有关这些控制如何影响 VMX non-root operation中处理器行为的更多详细信息,请参阅第 26 章。
该字段中的所有其他位都保留为 0。软件应参考 VMX 功能 MSR IA32_VMX_PROCBASED_CTLS2(请参阅附录 A.3.3)来确定哪些位可以设置为 1。未能清除保留位会导致后续 VM entries失败(请参阅第 1 节)。 27.2.1.1)。
基于主处理器的VM执行控制的位17确定是否使用基于第三处理器的VM执行控制。如果该位为 0,则 VM entries和 VMX non-root operation的作用就好像所有基于第三处理器的 VM 执行控制均为 0。仅支持基于主处理器的 VM 执行的位 17 的 0 设置的处理器控件不支持基于第三级处理器的 VM 执行控件。
表 25-8 列出了基于第三处理器的 VM 执行控制。有关这些控制如何影响 VMX non-root operation中处理器行为的更多详细信息,请参阅第 26 章。
该字段中的所有其他位都保留为 0。软件应参考 VMX 功能 MSR IA32_VMX_PROCBASED_CTLS3(请参阅附录 A.3.4)来确定哪些位可以设置为 1。未能清除保留位会导致后续 VM entries失败(请参阅第27.2.1.1)。
25.6.3 异常位图
异常位图是一个 32 位字段,其中每个异常包含一位。当异常发生时,其向量用于选择该字段中的一位。如果该位为 1,则异常会导致 VM Exits。如果该位为 0,则使用与异常向量对应的描述符通过 IDT 正常传递异常。
页面错误(向量 14 的异常)是否导致 VM Exits由异常位图中的位 14 以及页面错误产生的错误代码和 VMCS 中的两个 32 位字段(页面错误错误 -代码掩码和页面错误错误代码匹配)。详细信息请参见第 26.2 节。
25.6.4 I/O 位图地址
VM执行控制字段包括I/O位图A和B的64位物理地址(每个位图的大小为4KB)。 I/O 位图 A 在 0000H 到 7FFFH 范围内为每个 I/O 端口包含一位; I/O 位图 B 包含 8000H 到 FFFFH 范围内的端口位。
当且仅当“使用 I/O 位图”控制为 1 时,逻辑处理器才使用这些位图。如果使用位图,则当 I/O 位图中的任何位对应于它访问的端口是1。详细信息请参见26.1.3节。如果使用位图,则它们的地址必须按 4 KB 对齐。
25.6.5 时间戳计数器偏移和乘法器
VM执行控制字段包括64位TSC偏移字段。如果“RDTSC退出”控制为0并且“使用TSC偏移”控制为1,则该字段控制RDTSC和RDTSCP指令的执行。它还控制从 IA32_TIME_STAMP_COUNTER MSR 读取的 RDMSR 指令的执行。对于所有这些,TSC 偏移量的值会添加到时间戳计数器的值中,并将总和返回到 EDX:EAX 中的客户软件。
支持“使用 TSC 缩放”控制 1 设置的处理器还支持 64 位 TSC 乘数字段。如果该控制为 1(且“RDTSC 退出”控制为 0,“使用 TSC 偏移”控制为 1),则该字段还会影响上面标识的 RDTSC、RDTSCP 和 RDMSR 指令的执行。具体地,在加上TSC偏移之前,时间戳计数器的内容首先乘以TSC乘数。
有关 VMX 非 root 操作中 RDTSC、RDTSCP 和 RDMSR 行为的详细处理,请参阅第 26 章。
25.6.6 CR0 和 CR4 的guest /host掩码和读取影子
VM 执行控制字段包括客户/host掩码以及 CR0 和 CR4 寄存器的读取影子。这些字段控制访问这些寄存器的指令的执行(包括 CLTS、LMSW、MOV CR 和 SMSW)。它们在支持 Intel 64 架构的处理器上为 64 位,在不支持 Intel 64 架构的处理器上为 32 位。
一般来说,guest /host掩码中设置为 1 的位对应于host“拥有”的位:
guest 尝试将它们(使用 CLTS、LMSW 或 MOV 到 CR)设置为与相应读取影子中的相应位不同的值,导致 VM Exits。
guest 读取(使用 CR 或 SMSW 中的 MOV)从相应的读取影子中返回这些位的值。
清除为 0 的位对应于guest “拥有”的位;guest 尝试修改它们成功,并且guest 从控制寄存器本身读取这些位的返回值。
有关这些字段如何影响 VMX 非 root 操作的详细信息,请参阅第 28 章。
25.6.7 CR3-目标控件
VM 执行控制字段包括一组 4 个 CR3 目标值和 CR3 目标计数。 CR3 目标值在支持 Intel 64 架构的处理器上均为 64 位,在不支持 Intel 64 架构的处理器上为 32 位。所有处理器上的 CR3 目标计数均为 32 位。
如果源操作数与这些值之一匹配,则在 VMX non-root operation中执行 MOV 到 CR3 不会导致 VM Exits。如果 CR3 目标计数为 n ,则仅考虑前 n 个 CR3 目标值;如果 CR3 目标计数为 0,则 MOV 到 CR3 始终会导致 VM Exits
CR3 目标值的写入值没有限制。如果 CR3 目标计数大于 4,VM entries将失败(请参阅第 27.2 节)。
未来的处理器可能支持不同数量的 CR3 目标值。软件应读取 VMX 功能 MSR IA32_VMX_MISC(请参阅附录 A.6)以确定支持的值的数量。
25.6.8 APIC 虚拟化的控制
软件访问逻辑处理器本地 APIC 寄存器的机制有以下三种:
如果本地 APIC 处于 xAPIC 模式,则它可以对 IA32_APIC_BASE MSR 中的物理地址引用的 4 KB 页中的地址执行内存映射访问(请参见第 11.4.4 节“本地 APIC 状态和位置”)英特尔® 64 和 IA-32 架构软件开发人员手册,第 3A 卷和英特尔® 64 架构处理器拓扑枚举技术论文)。
如果本地 APIC 处于 x2APIC 模式,则它可以使用 RDMSR 和 WRMSR 指令访问本地 APIC 的寄存器(请参阅英特尔® 64 架构处理器拓扑枚举技术论文)。
在64位模式下,它可以使用MOV CR8指令访问本地APIC的任务优先级寄存器(TPR)。
一些基于处理器的 VM 执行控制(参见第 25.6.2 节)控制此类访问。它们是“使用 TPR 影子”、“虚拟化 APIC 访问”、“虚拟化 x2APIC 模式”、“虚拟中断传递”、“APIC 寄存器虚拟化”和“IPI 虚拟化”。这些控件与以下字段交互:
APIC 访问地址(64 位)。该字段包含 4 KB APIC 访问页的物理地址。如果“虚拟化 APIC 访问”VM 执行控制为 1,则访问此页面可能会导致 VM Exits或被处理器虚拟化。参见第 30.4 节。
APIC 访问地址仅存在于支持“虚拟化 APIC 访问”VM 执行控制设置 1 的处理器上。
虚拟 APIC 地址(64 位)。该字段包含 4 KB 虚拟 APIC 页的物理地址。处理器使用虚拟 APIC 页来虚拟化对 APIC 寄存器的某些访问并管理虚拟中断;参见第 30 章。
根据前面指出的控件的设置,可以通过以下操作访问虚拟 APIC 页面:
MOV CR8 指令(参见第 30.3 节)。
此外,如果“虚拟化 APIC 访问”VM 执行控制为 1(请参见第 30.4 节),则访问 APIC 访问页面。
此外,如果 ECX 的值在 800H–8FFH 范围内(指示 APIC MSR)并且“虚拟化 x2APIC 模式”VM 执行控制为 1,则使用 RDMSR 和 WRMSR 指令(请参见第 30.5 节)。
如果“使用 TPR 影子”VM 执行控制为 1,VM entries将确保虚拟 APIC 地址是 4 KB 对齐的。虚拟 APIC 地址仅存在于支持“使用 TPR 影子”VM 执行控制的 1 设置的处理器上。
TPR 阈值(32 位)。该字段的位 3:0 确定阈值,VTPR(参见第 30.1.1 节)的位 7:4 不能低于该阈值。如果“虚拟中断传送”VM执行控制为0,则在将这些位的值降低到TPR阈值以下的操作(例如,执行MOV到CR8)之后发生VM退出。参见第 30.1.2 节。
TPR 阈值仅存在于支持“使用 TPR 影子”VM 执行控制的 1 设置的处理器上。
EOI 退出位图(4 个字段;每个字段 64 位)。这些字段仅在支持“虚拟中断传送”VM 执行控制 1 设置的处理器上受支持。它们用于确定哪些虚拟化写入 APIC 的 EOI 寄存器会导致 VM Exits:
EOI_EXIT0 包含从 0(位 0)到 63(位 63)的向量位。
EOI_EXIT1 包含从 64(位 0)到 127(位 63)的向量位
EOI_EXIT2 包含从 128(位 0)到 191(位 63)的向量位。
EOI_EXIT3 包含从 192(位 0)到 255(位 63)的向量位
有关该字段使用的更多信息,请参阅第 30.1.4 节
中断后通知向量(16 位)。该字段仅在支持“进程发布中断”VM 执行控制 1 设置的处理器上受支持。它的低 8 位包含中断向量,用于通知逻辑处理器虚拟中断已发出。有关使用该字段的更多信息,请参阅第 30.6 节。
中断后描述符地址(64 位)。该字段仅在支持“进程发布中断”VM 执行控制 1 设置的处理器上受支持。它是 64 字节对齐的已发布中断描述符的物理地址。有关使用该字段的更多信息,请参阅第 30.6 节。
PID 指针表地址(64 位)。该字段包含 PID 指针表的物理地址。如果“IPI 虚拟化”VM 执行控制为 1,则逻辑处理器使用此表中的条目来虚拟化 IPI。参见第 30.1.6 节。
最后一个 PID 指针索引(16 位)。该字段包含 PID 指针表中最后一个条目的索引。
25.6.9 MSR 位图地址
在支持“使用 MSR 位图”VM 执行控制设置为 1 的处理器上,VM 执行控制字段包括四个连续 MSR 位图的 64 位物理地址,每个位图大小为 1 KB。该字段在不支持该控件的 1 设置的处理器上不存在。这四个位图是:
读取低 MSR 的位图(位于 MSR 位图地址)。这对于 00000000H 到 00001FFFH 范围内的每个 MSR 地址包含一位。该位确定应用于该 MSR 的 RDMSR 的执行是否会导致 VM Exits。
读取高 MSR 的位图(位于 MSR 位图地址加 1024 处)。这对于 C0000000H 到 C0001FFFH 范围内的每个 MSR 地址包含一位。该位确定应用于该 MSR 的 RDMSR 的执行是否会导致 VM Exits。
写入低 MSR 的位图(位于 MSR 位图地址加 2048 处)。这对于 00000000H 到 00001FFFH 范围内的每个 MSR 地址包含一位。该位确定应用于该 MSR 的 WRMSR 执行是否会导致 VM Exits。
写入高 MSR 的位图(位于 MSR 位图地址加 3072 处)。这对于 C0000000H 到 C0001FFFH 范围内的每个 MSR 地址包含一位。该位确定应用于该 MSR 的 WRMSR 执行是否会导致 VM Exits。
当且仅当“使用 MSR 位图”控制为 1 时,逻辑处理器才使用这些位图。如果使用位图,并且 RCX 的值不在该位图覆盖的范围内,则执行 RDMSR 或 WRMSR 会导致 VM Exits。位图或 MSR 位图中的相应位(对应于指令和 RCX 值)是否为 1。有关详细信息,请参阅第 26.1.3 节。如果使用位图,则它们的地址必须按 4 KB 对齐。
25.6.10 执行-VMCS 指针
执行 VMCS 指针是一个 64 位字段,用于系统管理中断 (SMI) 和系统管理模式 (SMM) 的双监视器处理。 SMM VM Exits保存此字段,如第 32.15.2 节所述。从 SMM 返回的 VM entries使用此字段,如第 32.15.4 节中所述。
25.6.11 Extended-Page-Table Pointer (EPTP)
扩展页表指针(EPTP)包含 EPT PML4 表的基地址(参见第29.3.2),以及其他 EPT 配置信息。 该字段的格式如表25-9所示。
笔记:
软件应读取 VMX 功能 MSR IA32_VMX_EPT_VPID_CAP(请参阅附录 A.10)以确定支持哪些 EPT 分页结构内存类型。
并非所有处理器都支持 EPT 的已访问标志和脏标志。软件应读取 VMX 功能 MSR IA32_VMX_EPT_VPID_-CAP(请参阅附录 A.10)以确定处理器是否支持此功能。
并非所有处理器都强制执行影子堆栈页面的访问权限。软件应读取 VMX 功能 MSR IA32_VMX-_EPT_VPID_CAP(请参阅附录 A.10)以确定处理器是否支持此功能。
N 是逻辑处理器支持的物理地址宽度。软件可以通过在 EAX 中执行 CPUID 和 80000008H 来确定处理器的物理地址宽度。物理地址宽度在 EAX 的位 7:0 中返回。
EPTP 仅存在于支持“启用 EPT”VM 执行控制的 1 设置的处理器上。
25.6.12 虚拟处理器标识符 (VPID)
虚拟处理器标识符 (VPID) 是一个 16 位字段。它仅存在于支持“启用 VPID”VM 执行控制 1 设置的处理器上。有关该字段使用的详细信息,请参见第 29.1 节。
25.6.13 PAUSE 循环退出控制
在支持“暂停循环退出”VM 执行控制 1 设置的处理器上,VM 执行控制字段包括以下 32 位字段:
PLE_间隙。软件可以将此字段配置为循环中两次连续执行 PAUSE 之间的时间量上限。
PLE_窗口。软件可以将此字段配置为允许guest 在 PAUSE 循环中执行的时间量的上限。
这些字段基于以与时间戳计数器 (TSC) 相同的速率运行的计数器来测量时间。有关暂停循环退出的更多详细信息,请参见第 26.1.3 节。
25.6.14 VM 功能控制
VM 功能控件构成一个 64 位向量,用于管理 VMX non-root operation中 VMFUNC 指令的使用。仅在支持“激活辅助控制”基于主处理器的 VM 执行控制和“启用 VM 功能”基于辅助处理器的 VM 执行控制的 1 设置的处理器上才支持此字段。
表 25-10 列出了 VM 功能控件。有关这些控制如何影响 VMX non-root operation中处理器行为的更多详细信息,请参阅第 26.5.6 节。
该字段中的所有其他位均保留为 0。软件应参考 VMX 功能 MSR IA32_VMX_VMFUNC(参见附录 A.11)来确定保留哪些位。未能清除保留位会导致后续 VM entries失败(请参见第 27.2.1.1 节)。
支持“EPTP 切换”VM 功能控制 1 设置的处理器还支持称为 EPTP 列表地址的 64 位字段。该字段包含 4 KB EPTP 列表的物理地址。 EPTP 列表包含 512 个 8 字节条目(每个条目一个 EPTP 值),并由 EPTP 交换 VM 功能使用(参见第 26.5.6.3 节)。
25.6.15 VMCS 阴影位图地址
在支持“VMCS 阴影”VM 执行控制设置为 1 的处理器上,VM 执行控制字段包括 VMREAD 位图和 VMWRITE 位图的 64 位物理地址。每个位图的大小为 4 KB,因此包含 32 KB。地址是 VMREAD 位图地址和 VMWRITE 位图地址。
如果“VMCS 阴影”VM 执行控制为 1,VMREAD 和 VMWRITE 的执行可能会参考这些位图(请参见第 25.10 节和第 31.3 节)。
25.6.16 ENCLS-退出位图
ENCLS 现有位图是 64 位字段。如果“启用 ENCLS 退出”VM 执行控制为 1,则如果该字段中与 EAX 的值相对应的位为 1,ENCLS 的执行将导致 VM Exits。如果该位为 0,则指令正常执行。更多信息请参见第 26.1.3 节。
25.6.17 ENCLV-退出位图
ENCLV 退出位图是 64 位字段。如果“启用 ENCLV 退出”VM 执行控制为 1,则如果该字段中与 EAX 的值相对应的位为 1,执行 ENCLV 会导致 VM Exits。如果该位为 0,则指令正常执行。更多信息请参见第 26.1.3 节。
25.6.18 PCONFIG-退出位图
PCONFIG 退出位图是一个 64 位字段。如果“启用 PCONFIG”VM 执行控制为 1,且该字段中对应于 EAX 值的位为 1,则 PCONFIG 的执行会导致 VM Exits。如果该控制为 0,则 PCONFIG 的任何执行都会导致 #UD。更多信息请参见第 26.1.3 节。
25.6.19 页面修改日志记录的控制字段
PML 地址是一个 64 位字段。它是页修改日志的 4 KB 对齐地址。页修改日志由 512 个 64 位条目组成。它用于页面修改日志记录功能。页面修改日志记录的详细信息在第 29.3.6 节中给出。
如果“启用 PML”VM 执行控制为 1,VM entries将确保 PML 地址是 4 KB 对齐的。 PML 地址仅存在于支持“启用 PML”VM 执行控制设置 1 的处理器上。
25.6.20 虚拟化异常的控制
在支持“EPT-violation #VE”VM 执行控制 1 设置的处理器上,VM 执行控制字段包括以下内容:
虚拟化异常信息地址(64位)。该字段包含虚拟化异常信息区域的物理地址。当逻辑处理器遇到虚拟化异常时,将虚拟化异常信息保存在虚拟化异常信息地址处;参见第 26.5.7.2 节。
EPTP 索引(16 位)。当EPT违规导致虚拟化异常时,处理器将该字段的值写入虚拟化异常信息区域。 EPTP-switching VM 功能更新该字段(参见第 26.5.6.3 节)
25.6.21 XSS-退出位图
在支持“启用 XSAVES/XRSTORS”VM 执行控制 1 设置的处理器上,VM 执行控制字段包括 64 位 XSS 退出位图。如果“启用 XSAVES/XRSTORS”VM 执行控制为 1,则 XSAVES 和 XRSTORS 的执行可能会参考该位图(请参阅第 26.1.3 节和第 26.3 节)。
25.6.22 子页面权限表指针(SPPTP)
如果启用了EPT的子页面写权限功能,则可以以128字节的粒度确定EPT写权限(参见第29.3.4节)。这些权限是使用内存中的子页面权限结构的层次结构来确定的。
该层次结构的根由称为子页面权限表指针 (SPPTP) 的 VM 执行控制字段引用。 SPPTP 包含根 SPP 表的基地址(参见第 29.3.4.2 节)。该字段的格式如表25-9所示。
SPPTP 仅存在于支持“EPT 的子页面写入权限”VM 执行控制的 1 设置的处理器上。
25.6.23 与管理程序管理的线性地址转换相关的字段
当“启用 HLAT”VM 执行控制为 1 时,将使用两个字段,启用 HLAT 分页:
HLAT 分页使用管理程序管理的线性地址转换指针(HLAT 指针或 HLATP)来定位和访问用于线性地址转换的第一个分页结构(请参阅第 4.5 节)。该字段的格式如表25-12所示。
HLAT 前缀大小。该字段的值确定哪个线性地址受到 HLAT 分页的约束。参见第 4.5.1 节。
这些字段仅存在于支持“启用 HLAT”VM 执行控制 1 设置的处理器上
25.6.24 与 PASID translation相关的字段
当“PASID 转换”VM 执行控制为 1 时,使用两个 64 位 VM 执行控制字段,启用 PASID 转换以执行 ENQCMD 和 ENQCMDS:低 PASID 目录地址和高 PASID 目录地址。这些分别是低 PASID 目录和高 PASID 目录的物理地址。这些字段仅存在于支持“PASID 转换”VM 执行控制的 1 设置的处理器上。
有关 ENQCMD 和 ENQCMDS 的 PASID 转换过程的信息,请参阅第 26.5.8 节
25.6.25 指令超时控制
在支持“指令超时”VM 执行控制的 1 设置的处理器上,VM 执行控制字段包括 32 位指令超时控制。处理器将此字段的值解释为以晶体时钟周期为单位测量的时间量。1 如果“指令超时”VM 执行控制为 1,则如果某些操作阻止处理器到达指令,则会发生 VM Exits这段时间内的边界。
25.6.26 控制 IA32_SPEC_CTRL MSR 虚拟化的字段
在支持“虚拟化 IA32_SPEC_CTRL”VM 执行控制设置为 1 的处理器上,VM 执行控制字段包括以下 64 位字段:
IA32_SPEC_CTRL 掩码。在此字段中设置一个位可防止客户软件修改 IA32_SPEC_CTRL MSR 中的相应位。
IA32_SPEC_CTRL 阴影。该字段包含客户软件期望在 IA32_SPEC_CTRL MSR 中的值。
第 26.3 节讨论了如何在 VMX non-root operation中使用这些字段。
25.7 VM退出控制字段
VM Exits控制字段控制 VM Exits的行为。它们在第 25.7.1 节和第 25.7.2 节中讨论。
25.7.1 VM Exits控制
VM 出口控件由两个向量组成,用于管理 VM 出口的基本操作。它们是主要 VM Exits控制(32 位)和辅助 VM Exits控制(64 位)。
表 25-13 列出了主要的 VM Exits控制。有关这些控制如何影响 VM Exits的完整详细信息,请参阅第 28 章。
该字段中的所有其他位均被保留,有些为 0,有些为 1。软件应参考 VMX 功能 MSR IA32_VMX_EXIT_CTLS 和 IA32_VMX_TRUE_EXIT_CTLS(参见附录 A.4)来确定应如何设置保留位。未能正确设置保留位会导致后续 VM entries失败(请参阅第 27.2.1.2 节)。
第一批支持虚拟机扩展的处理器仅支持位 0–8、10、11、13、14、16 和 17 的 1 设置。VMX 功能 MSR IA32_VMX_EXIT_CTLS 始终报告这些位必须为 1。 逻辑支持任何这些位的 0 设置的处理器将支持 VMX 功能 MSR IA32_VMX-_TRUE_EXIT_CTLS MSR,并且软件应查阅此 MSR 以发现对这些位的 0 设置的支持。不知道这些位中任何一位的功能的软件应将该位设置为 1。
基于主处理器的 VM Exits控制的位 31 确定是否使用辅助 VM Exits控制。如果该位为 0,则 VM entry和 VM Exits功能就好像所有辅助 VM Exits控制都为 0。仅支持主 VM Exits控制的位 31 的 0 设置的处理器不支持辅助 VM Exits控制。
表 25-14 列出了辅助 VM Exits控制。有关这些控制如何影响 VM Exits的更多详细信息,请参阅第 28 章。
该字段中的所有其他位都保留为 0。软件应参考 VMX 功能 MSR IA32_VMX_EX IT_CTLS2(请参阅附录 A.4.2)来确定哪些位可以设置为 1。未能清除保留位会导致后续 VM entries失败(请参阅第 27.2.1.2 节)
25.7.2 MSR 的 VM Exits控制
VMM可以指定要在VM出口上存储和加载的MSR列表。以下 VM 出口控制字段确定 MSR 如何存储在 VM 出口上:
VM Exits MSR 存储计数(32 位)。该字段指定 VM Exits时要存储的 MSR 数量。建议此计数不要超过 512,否则,在 VM Exits期间可能会导致不可预测的处理器行为(包括机器检查)。
VM Exits MSR 存储地址(64 位)。该字段包含VM-exit MSR-store区域的物理地址。该区域是一个条目表,每个条目 16 字节,其中条目数由 VM Exits MSRstore 计数给出。每个条目的格式如表 25-15 所示。如果 VM Exits MSR 存储计数不为零,则地址必须是 16 字节对齐。
请参阅第 28.4 节了解如何在 VM 出口上使用该区域。
以下 VM 出口控制字段确定如何在 VM 出口上加载 MSR:
VM Exits MSR 加载计数(32 位)。该字段包含 VM Exits时要加载的 MSR 数量。建议此计数不要超过 512。否则,在 VM Exits期间可能会导致不可预测的处理器行为(包括机器检查)。
VM Exits MSR 加载地址(64 位)。该字段包含VM-exit MSR-load区域的物理地址。该区域是一个条目表,每个条目 16 字节,其中条目数由 VM Exits MSR 负载计数给出(参见表 25-15)。如果VM-exit MSR-load计数不为零,则地址必须是16字节对齐的。
请参阅第 28.6 节了解如何在 VM 出口上使用该区域。
25.8 VM entry控制字段
VM entries控制字段控制 VM entries的行为。它们在第 25.8.1 节到第 25.8.3 节中讨论。
25.8.1 VM entry控制
VM entries控件构成一个 32 位向量,用于管理 VM entries的基本操作。表 25-16 列出了支持的控件。请参阅第 25 章了解这些控制如何影响 VM entries。
该字段中的所有其他位均被保留,有些为 0,有些为 1。软件应参考 VMX 功能 MSR IA32_VMX_ENTRY_CTLS 和 IA32_VMX_TRUE_ENTRY_CTLS(参见附录 A.5)来确定应如何设置保留位。未能正确设置保留位会导致后续 VM entries失败(请参阅第 27.2.1.3 节)。
第一批支持虚拟机扩展的处理器仅支持位 0-8 和 12 的 1 设置。VMX 功能 MSR IA32_VMX_ENTRY_CTLS 始终报告这些位必须为 1。支持其中任何位的 0 设置的逻辑处理器位将支持 VMX 功能 MSR IA32_VMX_TRUE_ENTRY_CTLS MSR,并且软件应查阅此 MSR 以发现对这些位的 0 设置的支持。不知道这些位中任何一位的功能的软件应将该位设置为 1。
25.8.2 MSR 的 VM entry控制
VMM可以指定要加载到VM条目上的MSR列表。以下 VM entry控制字段管理此功能:
VM entries MSR 负载计数(32 位)。该字段包含要加载到 VM entries上的 MSR 数量。建议此计数不要超过 512。否则,在 VM entry期间可能会导致不可预测的处理器行为(包括机器检查)。
VM entries MSR 加载地址(64 位)。该字段包含VM-entry MSR-load区域的物理地址。该区域是一个条目表,每个条目 16 字节,其中条目数由 VM entries MSR 负载计数给出。表25-15描述了条目的格式。如果VM-entry MSR-load计数不为零,则地址必须是16字节对齐的。
有关如何在 VM entries上使用该区域的详细信息,请参阅第 27.4 节。
25.8.3 用于事件注入的 VM entry控制
VM entries可以配置为通过 IDT 传递事件来结束(在加载所有guest 状态和 MSR 后)。这个过程称为事件注入,由以下三个VM-entry控制字段控制:
VM入口中断信息字段(32位)。该字段提供有关要注入的事件的详细信息。该字段的含义如表25-17所示。
向量(位 7:0)确定使用 IDT 中的哪个条目或注入哪个其他事件。
中断类型(位 10:8)决定如何执行注入的详细信息。一般来说,VMM 应该对除以下异常之外的所有异常使用类型硬件异常:
断点异常(#BP;VMM 应使用软件异常类型);
溢出异常(#OF VMM 应使用使用类型软件异常);和
由 INT1 生成的那些调试异常 (#DB)(VMM 应使用使用类型特权软件异常)。
other event 类型用于注入不通过 IDT 传递的事件。
对于异常,传递错误代码位(位 11)确定传递是否将错误代码推送到guest 堆栈上。
当且仅当有效位(位 31)为 1 时,VM entry才会注入事件。该字段中的有效位在每次 VM Exits时都会被清除(请参阅第 28.2 节)。
VM entry异常错误代码(32 位)。当且仅当有效位(位 31)和传送错误代码位(位 11)都在 VM entry中断信息字段中设置时,才使用该字段。
VM-entry指令长度(32位)。对于类型为软件中断、软件异常或特权软件异常的事件注入,该字段用于确定压入堆栈的 RIP 值
有关事件注入机制的详细信息,包括中断类型和 VM entry指令长度的使用,请参见第 27.6 节。
VM退出清除VM进入中断信息字段中的有效位(位31)。
25.9 VM退出信息字段
VMCS 包含一段字段,其中包含有关最近 VM Exits的信息
在某些处理器上,尝试使用 VMWRITE 写入这些字段会失败(请参阅第 31 章中的“VMWRITE — 将字段写入虚拟机控制结构”)。
25.9.1 基本 VM Exits信息
以下 VM Exits信息字段提供有关 VM Exits的基本信息:
退出原因(32 位)。该字段对 VM Exits的原因进行编码,其结构如表 25-18 所示。
位 15:0 提供有关 VM Exits(如果位 31 清零)或 VM entry失败(如果位 31 置位)原因的基本信息。附录C列举了基本的退出原因。
位 16 始终清除为 0。
如果逻辑处理器处于 enclave 模式时发生 VM Exits,则位 27 设置为 1。
如果 VM entry注入的事件的传递发生并且guest 中断状态字段指示飞地中断(该字段的位 4 为 1),则 VM 出口也会设置该位。详细信息请参见第 28.2.1 节。
位 28 仅由 SMM VM Exits(参见第 32.15.2 节)设置,该退出优先于如果未发生 SMM VM Exits则可能发生的 MTF VM Exits(参见第 26.5.2 节)。参见第 32.15.2.3 节。
当且仅当发生 VM Exits时处理器处于 VMX root operation时,才会设置位 29。仅当 SMM VM Exits时才会发生这种情况。参见第 32.15.2 节。
由于某些 VM entry故障会从host状态区域加载处理器状态(请参阅第 27.8 节),因此软件必须能够将此类情况与真正的 VM Exits区分开来。位 31 用于此目的。
退出资格(64 位;在不支持 Intel 64 架构的处理器上为 32 位)。该字段包含有关 VM 由于以下原因退出的原因的附加信息: 调试异常;页面错误异常;初创企业 IPI (SIPI);任务切换;投资; INVLPG;INVVPID; LGDT;激光损伤检测; LLDT;长期关系; SGDT; SIDT; SLDT; STR; VM清除; VMPTRLD; VMPTRST;虚拟机读取;虚拟机写入; VMXON; XRSTORS; X保存;控制寄存器访问; MOV 博士; I/O指令;和等待。该字段的格式取决于VM退出的原因。详细信息请参见第 28.2.1 节。
guest 线性地址(64 位;在不支持 Intel 64 架构的处理器上为 32 位)。该字段用于以下情况:
由于尝试使用内存操作数执行 LMSW,VM Exits。
VM 由于尝试执行 INS 或 OUTS 而退出
VM 由于 I/O 指令退出后立即到达的系统管理中断 (SMI) 而退出。
某些虚拟机因 EPT 违规而退出
有关何时以及如何使用此字段的详细信息,请参阅第 28.2.1 节和第 32.15.2.3 节。
guest 物理地址(64 位)。由于 EPT 违规和 EPT 配置错误,VM Exits使用此字段。有关何时以及如何使用该字段的详细信息,请参阅第 28.2.1 节。
25.9.2 由于向量事件导致 VM Exits的信息
为由于以下向量事件而导致的 VM Exits提供特定于事件的信息: 异常(包括由指令 INT3、INTO、INT1、BOUND、UD0、UD1 和 UD2 生成的异常);当“退出时确认中断”VM-exit 控制为 1 时发生的外部中断;和不可屏蔽中断 (NMI)。此信息在以下字段中提供:
VM退出中断信息(32位)。该字段接收与导致 VM Exits的事件关联的基本信息。该字段的说明如表25-19所示。
VM-退出中断错误代码(32位)。对于由硬件异常引起的 VM Exits,这些异常会在堆栈上传递错误代码,此字段会接收该错误代码。
第 28.2.2 节提供了如何在 VM Exits时保存这些字段的详细信息。
25.9.3 事件传递期间发生的 VM Exits信息
提供了有关 VMX non-root operation中事件传递期间发生的 VM Exits的附加信息。1 此信息在以下字段中提供:
IDT 向量信息(32 位)。该字段接收与 VM Exits发生时正在传递的事件关联的基本信息。该字段的说明如表25-20所示。
IDT-向量错误代码(32 位)。对于在交付硬件异常期间发生的 VM Exits,本应在堆栈上交付错误代码,此字段接收该错误代码。
请参阅第 28.2.4 节提供有关如何在 VM Exits时保存这些字段的详细信息
25.9.4 由于指令执行而导致 VM Exits的信息
以下字段用于尝试在 VMX 非 root 操作中执行某些指令而导致 VM Exits:
VM-exit指令长度(32位)。对于指令执行导致的 VM Exits,该字段接收其执行导致 VM Exits的指令的字节长度。1 有关何时以及如何使用该字段的详细信息,请参见第 28.2.5 节。
VM-exit指令信息(32位)。该字段用于由于尝试执行 INS、INVEPT、INVVPID、LIDT、LGDT、LLDT、LTR、OUTS、SIDT、SGDT、SLDT、STR、VMCLEAR、VMPTRLD、VMPTRST、VMREAD、VMWRITE 或 VMXON 而导致 VM Exits。2该字段的格式取决于VM退出的原因。详细信息请参见第 28.2.5 节。
以下字段(每个字段为 64 位;在不支持 Intel 64 架构的处理器上为 32 位)仅用于由于 SMI 在 I/O 指令退出后立即到达而导致的 VM Exits。它们提供有关该 I/O 指令的信息:
输入/输出RCX。 I/O指令开始前RCX的值
输入/输出 RSI。 I/O指令开始前RSI的值
输入/输出 RDI。 I/O指令开始之前RDI的值。
输入/输出 RIP 。 I/O指令开始之前RIP的值(寻址I/O指令的RIP)
25.9.5 VM指令错误字段
32 位 VM 指令错误字段不提供有关最近 VM Exits的信息。事实上,它在虚拟机退出时不会被修改。相反,它提供有关 VMX 指令之一的无故障执行所遇到的错误的信息。
25.10 VMCS 类型:普通和影子
每个 VMCS 要么是普通 VMCS,要么是影子 VMCS。 VMCS 的类型由 VMCS 区域中的影子 VMCS 指示符确定(这是 VMCS 区域前 4 个字节的第 31 位的值;请参见表 25-1):0 表示普通 VMCS,1 表示普通 VMCS影子 VMCS。影子 VMCS 仅在支持“VMCS 影子”VM 执行控制设置 1 的处理器上受支持(请参阅第 25.6.2 节)。
影子 VMCS 与普通 VMCS 有两个不同之处:
普通 VMCS 可用于 VM entry,但影子 VMCS 则不能。当当前 VMCS 是影子 VMCS 时尝试执行 VM entries会失败(请参阅第 27.1 节)。
VMREAD 和VMWRITE 指令可用于VMX non-root operation来访问影子VMCS,但不能访问普通VMCS。这一事实是由以下原因造成的:
如果“VMCS 影子”VM 执行控制为 0,则在 VMX non-root operation中执行 VMREAD 和 VMWRITE 指令始终会导致 VM Exits(请参见第 26.1.3 节)。
如果“VMCS 影子”VM 执行控制为 1,则 VMX non-root operation中 VMREAD 和 VMWRITE 指令的执行可以访问由 VMCS 链接指针引用的 VMCS(请参见第 31.3 节)。
如果“VMCS 影子”VM 执行控制为 1,VM entries确保 VMCS 链接指针引用的任何 VMCS 都是影子 VMCS(请参见第 27.3.1.5 节)。
在 VMX root operation中,可以使用 VMREAD 和 VMWRITE 指令访问两种类型的 VMCS。
软件不应修改活动 VMCS 的 VMCS 区域中的影子 VMCS 指示器。这样做可能会导致 VMCS 损坏(请参阅第 25.11.1 节)。在修改shadow-VMCS指示器之前,软件应该对VMCS执行VMCLEAR以确保其不活动。
25.11 VMCS 的软件使用及相关结构
本节详细介绍了软件在使用 VMCS 和相关结构时应遵守的准则。它还描述了不遵守准则的后果。
25.11.1 虚拟机控制结构的软件使用
为了确保正确的处理器行为,软件在使用活动 VMCS 时应遵守某些准则。
任何 VMCS 都不应该在多个逻辑处理器上处于活动状态。如果要将 VMCS 从一个逻辑处理器“迁移”到另一个逻辑处理器,则第一个逻辑处理器应在另一个逻辑处理器之前为该 VMCS 执行 VMCLEAR(使其在该逻辑处理器上处于非活动状态并确保所有 VMCS 数据都在内存中)。处理器为 VMCS 执行 VMPTRLD(使其在第二个逻辑处理器上处于活动状态)。1 在多个逻辑处理器上处于活动状态的 VMCS 可能会被损坏(见下文)。
软件不应修改活动 VMCS 的 VMCS 区域中的影子 VMCS 指示符(请参见表 25-1)。这样做可能会导致 VMCS 损坏。在修改shadow-VMCS指示器之前,软件应该对VMCS执行VMCLEAR以确保其不活动。
软件应使用 VMREAD 和 VMWRITE 指令来访问当前 VMCS 中的不同字段(请参见第 25.11.2 节)。软件绝不能使用普通内存操作来访问或修改活动 VMCS 的 VMCS 数据,部分原因是用于存储 VMCS 数据的格式是特定于实现的且未在体系结构上定义,还因为逻辑处理器可能会维护以下 VMCS 的某些 VMCS 数据:处理器上的活动 VMCS,而不是 VMCS 区域中的活动 VMCS。以下各项详细介绍了使用普通内存操作访问 VMCS 数据的一些危险:
通过普通内存读取从 VMCS 读取的任何数据都不能可靠地反映 VMCS 的状态。结果可能会随时间或逻辑处理器的不同而变化。
使用普通内存写入写入 VMCS 不能保证对 VMCS 产生确定性影响。这样做可能会导致 VMCS 损坏(见下文)。
(软件可以通过在为该区域执行 VMPTRLD 之前删除到 VMCS 区域的任何线性地址映射,并且在为该区域执行 VMCLEAR 之前不重新映射它来避免这些危险。)
如果逻辑处理器离开 VMX 操作,则该逻辑处理器上活动的任何 VMCS 都可能会损坏(见下文)。为了防止在返回到 VMX 操作之后或在另一个逻辑处理器上使用的 VMCS 的这种损坏,软件应该在执行 VMXOFF 指令或从处理器上移除电源之前执行该 VMCS 的 VMCLEAR(例如,作为转换的一部分)到 S3 和 S4 电源状态)。
本节确定了可能导致 VMCS 损坏的操作。这些操作可能会导致 VMCS 的数据变得不确定。如果该 VMCS 随后在任何逻辑处理器上使用,则行为可能是不可预测的。以下各项详细说明了 VMCS 损坏的一些危害:
VM entries可能会因无法解释的原因而失败,或者可能会加载不需要的处理器状态
处理器可能无法正确支持第 26 章中记录的 VMX 非 root 操作,并且可能会生成意外的 VM Exits。
VM Exits可能会加载不需要的处理器状态、将不正确的状态保存到 VMCS 中或导致逻辑处理器转换为关闭状态。
25.11.2 VMREAD、VMWRITE 和 VMCS 字段的编码
VMCS 的每个字段都与一个 32 位值相关联,该值是其编码。当软件希望读取或写入该字段时,编码在 VMREAD 和 VMWRITE 的操作数中提供。如果在 64 位模式下给定一个将编码位设置为超出位 32 的操作数,这些指令就会失败。有关这些指令的说明,请参阅第 31 章。
VMCS 组件的 32 位编码的结构主要由字段的宽度及其在 VMCS 中的功能决定。参见表25-21。
以下各项详细说明了每种编码中各个位的含义:
字段宽度。位 14:13 编码字段的宽度。
值 0 表示 16 位字段。
值 1 表示 64 位字段。
值 2 表示 32 位字段。
值 3 表示自然宽度字段。此类字段在支持 Intel 64 架构的处理器上为 64 位,在不支持 Intel 64 架构的处理器上为 32 位
编码使用值 1 的字段经过特殊处理,以允许 32 位软件访问该字段的所有 64 位。通过为每个此类字段定义允许直接访问该字段的高 32 位的编码来允许此类访问。见下文。
字段类型。位 11:10 编码 VMCS 字段的类型:控制、客户状态、host状态或 VM Exits信息。 (最后一类还包括 VM 指令错误字段。)
指数。位 9:1 区分具有相同字段宽度和类型的组件。
访问类型。对于除 64 位字段(字段宽度为 1 的字段;参见上文)之外的所有字段,位 0 必须为 0。 A
VMREAD 或 VMWRITE 使用将此位清除为 0 的编码来访问整个字段。对于字段宽度为 1 的 64 位字段,使用将此位设置为 1 的编码的 VMREAD 或 VMWRITE 仅访问该字段的高 32 位。
附录B给出了VMCS中所有字段的编码。
下面根据处理器模式、VMCS字段宽度和访问类型描述VMREAD和VMWRITE的操作:
16 位字段:
VMREAD 返回目标操作数的位 15:0 中的字段值;目标操作数的其他位被清除为 0。
VMWRITE 将源操作数的位 15:0 的值写入 VMCS 字段;不使用源操作数的其他位。
32 位字段:
VMREAD 返回目标操作数的位 31:0 中的字段值;在 64 位模式下,目标操作数的位 63:32 被清除为 0。
VMWRITE 将源操作数的位 31:0 的值写入 VMCS 字段;在 64 位模式下,不使用源操作数的位 63:32。
使用 IA-32e 模式之外的完全访问类型的 64 位字段和自然宽度字段。
VMREAD 返回其目标操作数中字段的位 31:0 的值;该字段的位 63:32 被忽略。
VMWRITE 将其源操作数的值写入该字段的位 31:0 并清除该字段的位 63:32。
64 位字段和在 64 位模式下使用完全访问类型的自然宽度字段(仅在支持 Intel 64 架构的处理器上)。
VMREAD 返回目标操作数的位 63:0 中的字段值
VMWRITE 将源操作数的位 63:0 的值写入 VMCS 字段。
使用高访问类型的 64 位字段。
VMREAD 返回目标操作数的位 31:0 中字段的位 63:32 的值;在 64 位模式下,目标操作数的位 63:32 被清除为 0。
VMWRITE 将源操作数的位 31:0 的值写入字段的位 63:32;在 64 位模式下,不使用源操作数的位 63:32。
寻求在 IA-32e 模式之外读取 64 位字段的软件可以使用具有完全访问类型的 VMREAD(读取字段的位 31:0)和具有高访问类型的 VMREAD(读取字段的位 63:32);两次 VMREAD 执行的顺序并不重要。寻求在 IA-32e 模式之外修改 64 位字段的软件应首先使用具有完全访问类型的 VMWRITE(建立字段的位 31:0,同时清除位 63:32),然后使用具有高访问类型的 VMWRITE(建立字段的位 31:0,同时清除位 63:32)。该字段的位 63:32)。
25.11.3 初始化VMCS
在使用 VMCS 进行 VM entries之前,软件应初始化 VMCS 中的字段(使用 VMWRITE)。否则可能会导致不可预测的行为;例如,VM entry可能会因无法解释的原因而失败,或者成功转换(VM entry或 VM Exits)可能会使用意外值加载处理器状态。
没有必要初始化逻辑处理器不会使用的字段。 (例如,如果“使用 MSR 位图”VM 执行控制为 0,则无需初始化 MSR 位图地址。)
处理器维护一些无法使用 VMWRITE 指令修改的 VMCS 信息;这包括
VMCS 的启动状态(请参阅第 25.1 节)。这样的信息可以存储在VMCS区域的VMCS数据部分中。由于此信息的格式是特定于实现的,因此软件无法知道当它首次分配内存区域用作 VMCS 区域时,处理器将如何根据内存区域的内容确定此信息。
除了其其他功能之外,VMCLEAR 指令还初始化其操作数引用的 VMCS 区域中的任何特定于实现的信息。为了避免特定于实现的行为的不确定性,软件应在首次使用 VMPTRLD 激活相应的 VMCS 之前在 VMCS 区域上执行 VMCLEAR。 (图 25-1 说明了 VMCLEAR 的执行如何将 VMCS 置于明确定义的状态。)
以下软件使用符合这些限制:
VMCLEAR 应在首次用于 VM entries之前对 VMCS 执行
在为该 VMCS 执行 VMCLEAR 后,VMLAUNCH 应用于使用 VMCS 的第一个 VM entries。
VMRESUME 应用于使用 VMCS 的任何后续 VM entries(直到下一次针对 VMCS 执行 VMCLEAR)。
一般来说,VMRESUME 的延迟预计会低于 VMLAUNCH。由于将 VMCS 从一个逻辑处理器“迁移”到另一个逻辑处理器需要使用 VMCLEAR(请参阅第 25.11.1 节),它将 VMCS 的启动状态设置为“清除”,因此此类迁移需要使用 VMLAUNCH 执行下一个 VM entries。软件开发人员可以通过避免将 VMCS 从一个逻辑处理器不必要地迁移到另一个逻辑处理器来避免增加 VM entry延迟所带来的性能成本。
25.11.4 软件访问相关结构
除了 VMCS 区域本身中的数据之外,VMX non-root operation还可以通过 VMCS 中的指针引用的数据结构(例如,I/O 位图)进行控制。虽然指向这些数据结构的指针是 VMCS 的一部分,但数据结构本身却不是。它们不能使用 VMREAD 和 VMWRITE 访问,而是可以通过普通内存写入访问。
软件应确保仅当没有具有引用该数据结构的当前 VMCS 的逻辑处理器处于 VMX non-root operation时才修改每个此类数据结构。否则可能会导致不可预测的行为(包括第 25.11.1 节中确定的行为)。以下数据结构例外(在所示章节中有详细讨论): EPT 分页结构和用于定位 SPP 向量的数据结构(第 29.4.3 节);虚拟 APIC 页面(第 30.1 节);发布的中断描述符(第 30.6 节);和虚拟化异常信息区域(第 26.5.7.2 节)。
25.11.5 VMXON 区域
在执行 VMXON 之前,软件会分配逻辑处理器用来支持 VMX 操作的内存区域(称为 VMXON 区域)1。该区域的物理地址(VMXON 指针)在操作数中提供给 VMXON。 VMXON 指针受到适用于 VMCS 指针的限制:
VMXON 指针必须是 4 KB 对齐(位 11:0 必须为零)
VMXON 指针不得设置超出处理器物理地址宽度的任何位。
在执行 VMXON 之前,软件应将 VMCS 修订标识符(请参阅第 25.2 节)写入 VMXON 区域。 (具体来说,它应该将 31 位 VMCS 修订标识符写入 VMXON 区域前 4 个字节的位 30:0;位 31 应清除为 0。)它不需要以任何其他方式初始化 VMXON 区域。软件应为每个逻辑处理器使用单独的区域,并且不应在该逻辑处理器上执行 VMXON 和 VMXOFF 之间访问或修改该逻辑处理器的 VMXON 区域。否则可能会导致不可预测的行为(包括第 25.11.1 节中确定的行为)。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2024-5-6 14:25
被zhang_derek编辑
,原因: