本文共 11998 字,大约阅读时间需要 39 分钟。
VMCS结构
VMCS是保持在内存中的数据结构,包含了虚拟cpu的相关寄存器的内容和虚拟cpu相关的控制信息,每个VMCS对应一个虚拟CPU。VMCS在使用时需要与物理CPU绑定。在任意给定时候,VMCS与物理CPU是一对一的绑定关系,即一个物理CPU只能绑定一个VMCS,一个VMCS也只能与一个物理CPU绑定。VMCS在不同的时候可以绑定到不同的物理CPU,如在某个VMCS先和物理CPU1绑定,并在某个时候解除绑定关系,并重新绑定到物理CPU2.这种绑定关系的变化称为VMCS的迁移。VT-x提供了二条指令用于VMCS的绑定与解除绑定。VMPTRLD <VMCS地址>: 将指定的VMCS与执行该指令的物理CPU绑定。VMCLEAR: 将执行该指令的物理CPU与它的VMCS解除绑定。该指令会将物理CPU缓存中的VMCS结构同步到内存中去,从而保证VMCS和新的物理CPU绑定时,内存中的值是最新的。VT-x定义了VMCS的具体格式和内容。规定它是一个最大不超过4KB的内存块,并且要求是4KB对齐。VMCS的格式,各域描述如下:偏移0处是VMCS版本标识,表示VMCS数据格式的版本号。偏移4处是VMX中止指示,VM-Exit执行不成功时产生VMX中止,CPU会在此处存入VMX中止的原因,以方便调试。偏移8处时VMCS数据域,该域的格式是CPU相关的,不同型号的CPU可能使用不同格式,具体使用哪种格式由VMCS版本标识确定。VMCS主要的信息存放在VMCS数据域,VT-x提供了二条指令用于访问VMCS。VMREAD < 索引>:读VMCS 中索引 指定的域。VMWRITE <索引><数据>:写VMCS中索引指定的域。VT-x为VMCS数据域的每个字段也定义了相应的索引,通过上述二条指令也可以直接访问VMCS数据域中的各个域。具体而言,VMCS数据域包括下列六大类信息。VM-Exit信息域:提供VM-Exit事件的原因及明细信息,VMM利用这些信息来决定如何管理和控制VM,VM-Exit信息域只是只读的。
VMCS中各个域的详细分析:
VM-execution控制类字段
VIRTUAL_PROCESSOR_ID = 0x00000000, /SECONDARY_EXEC_ENABLE_VPID为1,有效,提供16位的VPID/POSTED_INTR_NV = 0x00000002, /PIN_BASED_POSTED_INTR为1时有效/IO_BITMAP_A = 0x00002000, /CPU_BASED_USE_IO_BITMAPS启用时,该字段生效/IO_BITMAP_A_HIGH = 0x00002001,IO_BITMAP_B = 0x00002002,IO_BITMAP_B_HIGH = 0x00002003,/当CPU_BASED_USE_MSR_BITMAPS为1时有效,当某位1时,访问该位所对应的MSR将产生VM-exit,MSR bitmap区域为4k,低半部分read bitmap,对应MSR范围从00000000H到00001FFFH,用来控制MSR的读访问;高半部分read bitmap,对应MSR范围从C0000000H到C0001FFFH,用来控制MSR的读访问;低半部分write bitmap,对应MSR范围从00000000H到00001FFFH,用来控制MSR的写访问;高半部分write bitmap,对应MSR范围从C0000000H到C0001FFFH,用来控制MSR的写访问;MSR bitmap的某位为0时,访问该位所对应的MSR不会产生VM-exit/MSR_BITMAP = 0x00002004,MSR_BITMAP_HIGH = 0x00002005,EXCUTIVE_VMCSP = 0x0000200c,EXCUTIVE_VMCSP_HIGH = 0x0000200d,/CPU_BASED_USE_TSC_OFFSETING为1时,该字段提供64位的偏移值,执行RDTSC,RDTSCP,RDMSR指令读取TSC时,返回的值为TSC+TSC offset/TSC_OFFSET = 0x00002010,TSC_OFFSET_HIGH = 0x00002011,/当CPU_BASED_TPR_SHADOW为1时,该字段有效,需要提供一个物理地址作为4k的页面/VIRTUAL_APIC_PAGE_ADDR = 0x00002012, /Virtual-APIC address (full)/VIRTUAL_APIC_PAGE_ADDR_HIGH = 0x00002013, /Virtual-APIC address (high)//当SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES为1时,该字段有效,需要提供一个物理地址作为4k的页面/APIC_ACCESS_ADDR = 0x00002014, /APIC-access address (full)/APIC_ACCESS_ADDR_HIGH = 0x00002015, /APIC-access address (high)/POSTED_INTR_DESC_ADDR = 0x00002016,POSTED_INTR_DESC_ADDR_HIGH = 0x00002017,/当SECONDARY_EXEC_ENABLE_EPT为1时,支持guest端物理地址转换为host端的最终物理地址bit2:0指示EPT paging-structure的内存类型(uc或WB);bit5:3指示EPT页表结构层级,这个值加1才是真正的级数;bit6 =1指示EPT页表结构项里的access与dirty标志位有效(EPT表项的bit8:9),处理器会更新EPT表项的这二个标志位bit N-1:12提供EPT PML4T表的物理地址。EPT 页表被载入专门的 EPT 页表指针寄存器 EPTP。EPT 页表对地址的映射机理与客户机页表对地址的映射机理相同 /
EPT_POINTER = 0x0000201a, /EPT pointer (EPTP; full)/EPT_POINTER_HIGH = 0x0000201b, /EPT pointer (EPTP; high)//当SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY为1时,该字段有效,用于控制发送EOI命令时是否产生VM-exit,对应的位为1时,将产生VM-exit/
EOI_EXIT_BITMAP0 = 0x0000201c, /对应向量号从0H到3FH/EOI_EXIT_BITMAP0_HIGH = 0x0000201d,EOI_EXIT_BITMAP1 = 0x0000201e, /对应向量号从40H到7FH/EOI_EXIT_BITMAP1_HIGH = 0x0000201f,EOI_EXIT_BITMAP2 = 0x00002020, /对应向量号从80H到BFH/EOI_EXIT_BITMAP2_HIGH = 0x00002021,EOI_EXIT_BITMAP3 = 0x00002022, /对应向量号从C0H到FFH/EOI_EXIT_BITMAP3_HIGH = 0x00002023,/VMCS Shadowing Bitmap Addresses/VMREAD_BITMAP = 0x00002026,VMWRITE_BITMAP = 0x00002028,/ bit0 =1 发生外部中断则产生VM-exit;bit2:1 保留位,固定为1;bit3 =1 发生NMI则产生VM-exit;bit4 保留位,固定为1;bit5 =1 定义virtual NMI;bit6 =1 启用VMX-preemption定时器;bit7 =1 启用posted-interrupt processing机制处理虚拟中断;bit31:8 保留位,固定为0/
PIN_BASED_VM_EXEC_CONTROL = 0x00004000, /Pin-based VM-execution controls//bit0 保留位,固定为0;bit1 保留位,固定为1;bit2 =1在IF=1并且中断没被阻塞时,产生VM-exit;bit3 =1读取TSC值时,返回TSC值加上偏移值;bit6:4 保留值,固定为1;bit7 =1执行HLT指令产生VM-exit;bit8 保留值,固定为1;bit9 =1执行INVLPG指令产生VM-exit;bit10 =1执行MWAIT指令产生VM-exit;bit11 =1执行RDPMC指令产生VM-exit;bit12 =1执行RDTSC指令产生VM-exit;bit14:13保留值,固定为1;bit15 =1写CR3寄存器产生VM-exit;bit16 =1读CR3寄存器产生VM-exit;bit18:17保留值,固定为1;bit19 =1写CR8寄存器产生VM-exit;bit20 =1读CR8寄存器产生VM-exit;bit21 =1启用virtual-APIC page页面虚拟化local APIC;bit22 =1开virtual-NMI window时产生VM-exit;bit23 =1读写DR寄存器产生VM-exit;bit24 =1执行IN/OUT或INS/OUTS类指令产生VM-exit;bit25 =1启用I/O bitmap;bit26 保留位,固定为1;bit27 =1启用MTF调试功能;bit28 =1启用MSR bitmap;bit29 =1执行MONITOR指令产生VM-exit;bit30 =1执行PAUSE指令产生VM-exit;bit31 =1Secondary processor-based VM-execution controls字段有效/
CPU_BASED_VM_EXEC_CONTROL = 0x00004002, /Primary processor-based VM-execution controls//EXCEPTION_BITMAP字段是一个32位的值,每位对应一个异常向量,在VMX non-root中,如果发生异常, 处理器检查EXCEPTION_BITMAP相应的位,该位为1时则产生VM-exit,为0时通过guest-IDT执行异常处理例程,当triple-fault发生时,直接产生VM-exit/
EXCEPTION_BITMAP = 0x00004004, /Exception bitmap,异常控制/PAGE_FAULT_ERROR_CODE_MASK = 0x00004006,PAGE_FAULT_ERROR_CODE_MATCH = 0x00004008,/最大值为4/CR3_TARGET_COUNT = 0x0000400a,/当CPU_BASED_TPR_SHADOW为1时,该字段有效,提供中断优先级的门槛值,低于该值,VM-exit/
TPR_THRESHOLD = 0x0000401c,/*bit0 =1虚拟化访问APIC-access page;bit1 =1启用EPT;bit2 =1访问GDTR,LDTR,IDTR,TR
产生VM-exit;
bit3 =0执行RDTSCP指令产生#UD异常;bit4 =1虚拟化访问x2APIC MSR;bit5 =1启用VPID机制;bit6 =1执行WBINVD指令产生VM-exit;bit7=1guest可以使用非分页保护模式或者实模式;bit8 =1支持访问virtual-APIC page内的虚拟寄存器;bit9 =1支持虚拟中断的delivery;bit10 =1决定PASUE指令是否产生VM-exit;bit11 =1执行RDRAND指令产生VM-exit;bit12 =1执行INVPCID指令产生#UD异常;bit13 =1VMX non-root operation可以执行VMFUNC指令;bit31:14保留位,固定为0/SECONDARY_VM_EXEC_CONTROL= 0x0000401e, /Secondary processor-based VM-execution controls*/PLE_GAP = 0x00004020,PLE_WINDOW = 0x00004022,/位为1时,表示该位权利属于host所有,为0时,表示该位guest有权设置/
CR0_GUEST_HOST_MASK = 0x00006000, /加速客户机写CR0指令/CR4_GUEST_HOST_MASK = 0x00006002,CR0_READ_SHADOW = 0x00006004, /加速客户机读CR0指令/CR4_READ_SHADOW = 0x00006006,CR3_TARGET_VALUE0 = 0x00006008,CR3_TARGET_VALUE1 = 0x0000600a,CR3_TARGET_VALUE2 = 0x0000600c,CR3_TARGET_VALUE3 = 0x0000600e,VM-entry控制类字段
VM_ENTRY_MSR_LOAD_ADDR = 0x0000200a,VM_ENTRY_MSR_LOAD_ADDR_HIGH = 0x0000200b,/*bit1:0 保留位,固定为1;bit2 =1加载debug寄存器;bit8:3保留位,固定为1; bit9 =1进入IA-32e模式;bit10 =1进入SMM模式;bit11 =1返回executive monitor,关闭SMM双重监控处理; bit12保留位,固定为1;bit13 =1加载IA32_PERF_GLOBAL_CTRL;bit14 =1加载IA32_PAT; bit15 =1加载IA32_EFER;bit31:16保留值,固定为0*/
VM_ENTRY_CONTROLS= 0x00004012, /VM-Entry Controls,由寄存器MSR_IA32_VMX_ENTRY_CTLS控制/
VM_ENTRY_MSR_LOAD_COUNT = 0x00004014,/*bit7:0中断或异常向量号; bit10:8Interruption type: 0: External interrupt 1: Reserved 2: Non-maskable interrupt (NMI) 3: Hardware exception 4: Software interrupt 5: Privileged software exception 6: Software exception 7: Other event bit11 =1指示有错误码需要提交;bit30:12保留位; bit31 =1指示VM_ENTRY_INTR_INFO_FIELD字段有效*/
VM_ENTRY_INTR_INFO_FIELD = 0x00004016, /事件注入控制字段/
VM_ENTRY_EXCEPTION_ERROR_CODE = 0x00004018, /VM-entry exception error code/VM_ENTRY_INSTRUCTION_LEN = 0x0000401a, /VM-entry instruction length/VM-exit控制类字段
VM_EXIT_MSR_STORE_ADDR = 0x00002006,VM_EXIT_MSR_STORE_ADDR_HIGH = 0x00002007,VM_EXIT_MSR_LOAD_ADDR = 0x00002008,VM_EXIT_MSR_LOAD_ADDR_HIGH = 0x00002009,/bit1:0保留值,固定为1;bit2 =1保存debug寄存器;bit8:3保留值,固定为1;bit9=1返回到IA-32e模式;bit11:10保留值,固定为1;bit12=1加载IA32_PERF_GLOBAL_CTRL;bit14:13保留值,固定为1;bit15=1VM-exit时处理器响应中断控制器,读取中断向量号;bit17:16保留值,固定为1;bit18=1保存IA32_PAT;bit19=1加载IA32_PAT;bit20=1保存IA32_EFER;bit21=1加载IA32_EFER;bit22=1VM-exit时保存VMX定时器计数值;bit31:23保留值,固定为0/VM_EXIT_CONTROLS = 0x0000400c, /VM-exit controls/VM_EXIT_MSR_STORE_COUNT = 0x0000400e,VM_EXIT_MSR_LOAD_COUNT = 0x00004010,VM-exit信息类字段
VM_INSTRUCTION_ERROR = 0x00004400, /指令失败类//基本信息类/GUEST_PHYSICAL_ADDRESS = 0x00002400, /Guest-physical address保存由于EPT violation或者/GUEST_PHYSICAL_ADDRESS_HIGH= 0x00002401,/EPT misconfiguration故障引起VM-exit时的GPA值/VM_EXIT_REASON = 0x00004402, /Exit reason/EXIT_QUALIFICATION = 0x00006400, /执行指令VM-exit原因,不同指令,该字段有不同的格式/GUEST_LINEAR_ADDRESS = 0x0000640a, /保存导致VM-exit的某些事件的线性地址值//直接向量事件类/VM_EXIT_INTR_INFO = 0x00004404, /VM-exit interruption information虚拟机退出原因/VM_EXIT_INTR_ERROR_CODE = 0x00004406,/间接向量事件类信息字段/IDT_VECTORING_INFO_FIELD = 0x00004408,IDT_VECTORING_ERROR_CODE = 0x0000440a,/指令信息类/VM_EXIT_INSTRUCTION_LEN = 0x0000440c,VMX_INSTRUCTION_INFO = 0x0000440e,/end VM-exit信息类字段//start guest-state区域字段/GUEST_DR7 = 0x0000681a, /调试寄存器/GUEST_RSP = 0x0000681c, /栈指针/GUEST_RIP = 0x0000681e, /指令指针/GUEST_RFLAGS = 0x00006820, /标志寄存器//控制寄存器/GUEST_CR0 = 0x00006800,GUEST_CR3 = 0x00006802,GUEST_CR4 = 0x00006804,/6个数据/代码段寄存器字段,分别为ES,CS,SS,DS,FS,GS寄存器,2个系统段寄存器,分别是LDTR和TR寄存器。每个段寄存器有4个字段对应,分别描述段寄存器的各个域:selector:16位字段;base:64位系统为64位,否则为32位;limit:32位;access right:32位access right字段格式:bit3:0 type段类型值;bit4 0=system,1=code/data;bit6:5段的访问权限;bit7: 0=no present,1=present;bit11:8 保留;bit12 系统软件可用;bit13在IA-32e模式下为L标志,在legacy下为保留位;bit14默认操作数size,0=16位,1=32位;bit15段limit粒度,0=1byte,1=4kb;bit16 0=usable,1=unusable;bit31:17保留//ES/GUEST_ES_SELECTOR = 0x00000800,GUEST_ES_LIMIT = 0x00004800,GUEST_ES_AR_BYTES = 0x00004814,GUEST_ES_BASE = 0x00006806,/CS/GUEST_CS_SELECTOR = 0x00000802,GUEST_CS_LIMIT = 0x00004802,GUEST_CS_AR_BYTES = 0x00004816,GUEST_CS_BASE = 0x00006808,/SS/GUEST_SS_SELECTOR = 0x00000804,GUEST_SS_LIMIT = 0x00004804,GUEST_SS_AR_BYTES = 0x00004818,GUEST_SS_BASE = 0x0000680a,/DS/GUEST_DS_SELECTOR = 0x00000806,GUEST_DS_LIMIT = 0x00004806,GUEST_DS_AR_BYTES = 0x0000481a,GUEST_DS_BASE = 0x0000680c,/FS/GUEST_FS_SELECTOR = 0x00000808,GUEST_FS_LIMIT = 0x00004808,GUEST_FS_AR_BYTES = 0x0000481c,GUEST_FS_BASE = 0x0000680e,/GS/GUEST_GS_SELECTOR = 0x0000080a,GUEST_GS_LIMIT = 0x0000480a,GUEST_GS_AR_BYTES = 0x0000481e,GUEST_GS_BASE = 0x00006810,/LDTR局部描述符表寄存器,指令LLDT指令装载到LDTR/GUEST_LDTR_SELECTOR = 0x0000080c,GUEST_LDTR_LIMIT = 0x0000480c,GUEST_LDTR_AR_BYTES = 0x00004820,GUEST_LDTR_BASE = 0x00006812,/TR任务寄存器/GUEST_TR_SELECTOR = 0x0000080e,GUEST_TR_LIMIT = 0x0000480e,GUEST_TR_AR_BYTES = 0x00004822,GUEST_TR_BASE = 0x00006814,/二个描述符寄存器,GDTR和IDTR.由二个字段组成: base:提供描述符表基地址;limit:提供描述符表的长度. GDTR全局描述符表寄存器,LGDT指令将GDT的入口地址装入此寄存器。/GUEST_GDTR_LIMIT = 0x00004810,GUEST_GDTR_BASE = 0x00006816, /IDTR中断描述符表寄存器/GUEST_IDTR_LIMIT = 0x00004812,GUEST_IDTR_BASE = 0x00006818,/MSR/GUEST_IA32_DEBUGCTL = 0x00002802,GUEST_IA32_DEBUGCTL_HIGH = 0x00002803,GUEST_IA32_PAT = 0x00002804,GUEST_IA32_PAT_HIGH = 0x00002805,GUEST_IA32_EFER = 0x00002806,GUEST_IA32_EFER_HIGH = 0x00002807,GUEST_IA32_PERF_GLOBAL_CTRL = 0x00002808,GUEST_IA32_PERF_GLOBAL_CTRL_HIGH= 0x00002809,GUEST_SYSENTER_CS = 0x0000482A,GUEST_SYSENTER_ESP = 0x00006824,GUEST_SYSENTER_EIP = 0x00006826,非寄存器类字段GUEST_INTR_STATUS = 0x00000810,/指示虚拟中断的状态/VMCS_LINK_POINTER = 0x00002800,VMCS_LINK_POINTER_HIGH = 0x00002801,GUEST_PDPTR0 = 0x0000280a, /开启EPT使用的字段/GUEST_PDPTR0_HIGH = 0x0000280b,GUEST_PDPTR1 = 0x0000280c,GUEST_PDPTR1_HIGH = 0x0000280d,GUEST_PDPTR2 = 0x0000280e,GUEST_PDPTR2_HIGH = 0x0000280f,GUEST_PDPTR3 = 0x00002810,GUEST_PDPTR3_HIGH = 0x00002811,GUEST_ACTIVITY_STATE = 0X00004826,/guest-state指示虚拟机进入/退出,虚拟处理器活动状态/GUEST_INTERRUPTIBILITY_INFO = 0x00004824,/当前虚拟处理器的可中断性/VMX_PREEMPTION_TIMER_VALUE = 0x0000482E,GUEST_PENDING_DBG_EXCEPTIONS = 0x00006822,/pending debug exceptions/host-state区域字段
HOST_RSP = 0x00006c14, /栈指针/HOST_RIP = 0x00006c16, /指令指针//控制寄存器/HOST_CR0 = 0x00006c00,HOST_CR3 = 0x00006c02,HOST_CR4 = 0x00006c04,/段选择寄存器/HOST_ES_SELECTOR = 0x00000c00,HOST_CS_SELECTOR = 0x00000c02,HOST_SS_SELECTOR = 0x00000c04,HOST_DS_SELECTOR = 0x00000c06,HOST_FS_SELECTOR = 0x00000c08,HOST_GS_SELECTOR = 0x00000c0a,HOST_TR_SELECTOR = 0x00000c0c,/段基址寄存器/HOST_FS_BASE = 0x00006c06,HOST_GS_BASE = 0x00006c08,HOST_TR_BASE = 0x00006c0a,HOST_GDTR_BASE = 0x00006c0c,HOST_IDTR_BASE = 0x00006c0e,/MSR寄存器/HOST_IA32_PAT = 0x00002c00,HOST_IA32_PAT_HIGH = 0x00002c01,HOST_IA32_EFER = 0x00002c02,HOST_IA32_EFER_HIGH = 0x00002c03,HOST_IA32_PERF_GLOBAL_CTRL = 0x00002c04,HOST_IA32_PERF_GLOBAL_CTRL_HIGH = 0x00002c05,HOST_IA32_SYSENTER_CS = 0x00004c00,HOST_IA32_SYSENTER_ESP = 0x00006c10,HOST_IA32_SYSENTER_EIP = 0x00006c12,转载于:https://blog.51cto.com/zybcloud/2308093