Intel IA32 Manual VMX Section [Ch. 23~Ch. 33] - GiantVM/KVM-Annotation GitHub Wiki

Overview

  • VMX指令集不能在virtual 8086、compatibility模式下运行
  • 通过VMXON进入VMX operation,VMXOFF退出VMX operation
  • 使用前提
    • 使用前先通过CPUID.1.ECX.VMX[bit 5]检查CPU支持VMX
      • VMX自身的extension通过VMX capability MSR检查
    • 使用前需设置CR4.VMXE[bit 13]=1开启VMX功能,此外IA32_FEATURE_CONTROLMSR可供BIOS提供禁用VMX的功能(bit 1表示在SMX模式中启用VMX,bit 2表示在SMX模式外启用VMX,bit 0为lock bit,必须设为1才能使用VMX,但此后将不能修改该MSR,否则会引起#GP)
  • VMXON指令的操作数为一个指向VMX region的指针(物理地址),每个逻辑核应使用一个不同的VMX region,其大小为4K(实际使用的大小不到4K,具体多少可用IA32_VMX_BASICMSR查询),地址需4K页对齐
    • 执行VMXON前应对VMX region进行初始化,即对前4个Byte的第30:0位设置为31-bit的VMCS revision identifier,第31位清零
    • VMCS revision identifier可以通过IA32_VMX_BASICMSR查询
  • 限制:
    • CR0和CR4的一些bit会被限制为fixed,若不按照其fixed的值(根据IA32_VMX_CR0_FIXED0/1IA32_VMX_CR4_FIXED0/1查询)设置,执行VMXON会引发#GP,进入VMX operation后也无法对这些fixed的bit更改,尝试更改会引发#GP
    • 无法在A20M模式下执行VMXON(会引发#GP),进入VMX operation后A20M interrupt也会被block住
      • 注:A20M是指A20 line mask,即为了兼容80286时代引入的A20 Gate功能而引入的A20M# pin,通过对其发送信号可以引起物理地址在使用时第21位(从0开始数则为第20位)被视作0处理
    • 在VMX root模式下INIT IPI会被block住,直到退出VMX operation才会重新收到

VMCS

  • 每个VMCS对应于一个VMCS region,其大小为4K(实际使用的大小不到4K,具体多少可用IA32_VMX_BASICMSR查询),地址需4K页对齐
    • 所有相关数据结构(包括VMCS)的内存访问模式都应该设置为WB(Write Back),将来若有变动可查询IA32_VMX_BASICMSR
  • Lifecycle:任何时刻只有一个current VMCS,有若干active VMCS,每个VMCS有是否launched这一状态(clear或launched)
    • VMPTRLD(操作数为物理地址)从内存载入一个VMCS,成为current且active的VMCS,VMPTRST将current VMCS pointer写入内存(没有current VMCS则返回值为0xFFFFFFFF_FFFFFFFF)
    • VMCLEAR(操作数为物理地址)将VMCS的launched状态清空,并设置为inactive,若操作数为current VMCS pointer,则current VMCS pointer会设置为0xFFFFFFFF_FFFFFFFF。此外该操作会将CPU中尚未写入内存的VMCS状态flush到内存
    • VMLAUNCH会将VMCS设置为launched状态,VMLAUNCH必须在clear状态下使用,VMRESUME必须在launched状态下使用,否则操作会引起VMFail
  • 若存在current VMCS,执行VMX指令失败后会在VMCS的VM-instruction error field存入error number
  • 读写操作通过VMREADVMWRITE进行,通过一个32位的encoding指定要读写的field
    • Bit 0:Access Type,0为普通模式,1为High-half模式(只对64-bit width有效,用于支持32位访问64位field)
    • Bit 9:1:Index,用于指定具体的field
    • Bit 11:10:Field Type,0为Control(三种合计),1为VM-Exit Information,2为Guest State,3为Host State
    • Bit 12:Reserved(必须为0)
    • Bit 14:13:Width,0表示16-bit,1表示64-bit,2表示32-bit,3表示natural width(32位模式则为32-bit,64位模式则为64-bit)
    • Bit 31:15:Reserved(必须为0)
  • 注意事项:
    • 每个VMCS应该只在一个逻辑核上active,若要进行核间迁移,应先VMCLEAR再在另一个核上VMPTRLD,否则可能造成corrupt
    • 在修改shadow VMCS indicator位时,必须先VMCLEAR再修改,否则可能造成corrupt
    • 在退出VMX operation之前必须对active的VMCS进行VMCLEAR,否则可能造成corrupt
    • 只能使用VMREADVMWRITE读写VMCS,用普通内存访问可能造成corrupt
    • 被VMCS中指针引用到的普通内存,不能在VMX non-root模式下访问

  • Format of VMCS
    • Byte 0-3:第30:0位是VMCS revision identifier,第31位表示是否是shadow VMCS
      • VMCS revision identifier可以通过IA32_VMX_BASICMSR查询,在VMPTRLD一个VMCS前需先初始化这4字节否则将引起VMFail
    • Byte 4-7:VMX-abort indicator:VM Exit时发生错误引起了VMX Abort时CPU会自动设置该field
    • Byte 8-End:Data payload (implementation specific)
  • Guest-State Area
    • Guest Register State:
      • CR0, CR3, CR4, DR7, RSP, RIP, RFLAGS
      • CS, SS, DS, ES, FS, GS, LDTR, TR(包括它们的selector和部分descriptor内容)
      • GDTR, IDTR(base addr和limit)
      • 一些MSR,包括IA32_DEBUGCTL, IA32_SYSENTER_CS, IA32_SYSENTER_ESP, IA32_SYSENTER_EIP, IA32_PERF_GLOBAL_CTRL, IA32_PAT, IA32_EFER, IA32_BNDCFGS(后四个根据设置决定是否启用)
      • SMBASE
    • Guest Non-Register State
      • Activity state:分为Active, HLT(执行了HLT指令), Shutdown(发生了triple fault或其它严重错误), Wait-for-SIPI(在启动过程中,等待Start IPI)四种状态
      • Interruptibility state:表示Guest正在中断被Block住的状态
        • Bit 0, Blocking by STI:STI指令会延迟一条指令启动Maskable Interrupt,用以支持STI; RET的模式
        • Bit 1, Blocking by MOV SS/POP SS:MOV SSPOP SS会在下一条指令禁止中断(禁止本条到下条指令间发生中断),用以支持MOV SS, Sel; MOV ESP, StackTop的模式
        • Bit 2, Blocking by SMI:SMM模式下SMI中断会被block住
        • Bit 3, Blocking by NMI:在当前有NMI或SMI在处理时,接下来的NMI会被block住,直到该handler执行完毕(IRET发生),该位指这种情况,不包括其它NMI暂时被block的情况
        • Bit 4, Enclave Interruption
      • VMCS link pointer:用于指向shadow VMCS,若该功能未启用,应设置为0xFFFFFFFF_FFFFFFFF
      • VMX-preemption timer value:用于支持preemption timer功能
  • Host-State Area
    • CR0, CR3, CR4, RSP, RIP
    • CS, SS, DS, ES, FS, GS, TR(注意没有LDTR)
    • FS, GS, TR, GDTR, IDTR的base addr
    • 一些MSR,包括IA32_SYSENTER_CS, IA32_SYSENTER_ESP, IA32_SYSENTER_EIP, IA32_PERF_GLOBAL_CTRL, IA32_PAT, IA32_EFER(后三个根据设置决定是否启用)

VM-Execution Control

  • 注意事项:
    • 一些field中有一些reserved bits,可能默认为0或1,在一些bits原本是reserved的在新版本中也可能可以由用户设置。IA32_VMX_BASIC[bit 55]若为0,则所有默认为1的bit都必须设置为1,否则VM entry会失败,反之则可能可以设置为0,具体capability通过新增的MSR查询(e.g. IA32_VMX_PINBASED_CTLS->IA32_VMX_TRUE_PINBASED_CTLS
  • Pin-Based VM-Execution Controls
    • Bit 0, External-interrupt exiting:决定是否Maskable外部中断会引起VM Exit还是走Guest IDT
    • Bit 3, NMI exiting:决定是否NMI会引起VM Exit还是走Guest IDT
    • Capability MSR为IA32_VMX_PINBASED_CTLSIA32_VMX_TRUE_PINBASED_CTLS
  • Processor-Based VM-Execution Controls

  • VM-Exit Control
  • VM-Entry Control
  • VM-Exit Information

VM Entries

Features

VMCS Shadowing

  • VMCS可以处于shadow状态,shadow状态的VMCS无法用于VMLAUNCH,而是通过被另一个VMCS用指针引用来使用
  • VMCS shadowing用于支持嵌套虚拟化,Guest VMM使用的VMCS包含一个指向shadow VMCS的指针,当Guest VMM被launch以后,该shadow VMCS进入active状态,并且在Guest VMM中可以直接读写shadow VMCS而不需要进行VM Exit
  • 具体读写哪些内容时退出可以通过一个bitmap控制。其作用在于,由于shadow VMCS不能用于启动nested VM,还需有一个nested VMCS,Host VMM需要将shadow VMCS与nested VMCS同步,因此可以通过该bitmap设置少量field不需要VM Exit即可读写,其余多数很少用到的field仍需要VM Exit,这样可以减少Host VMM同步所需的工作量(减少了不必要的copy)

VMX-Preemption Timer

VPID & EPT