晓木虫
学术数据库客户端

关于VMCS(VIRTUAL-MACHINE CONTROL STRUCTURES)

 找回密码
 注册会员

QQ登录

微信登录

关于VMCS(VIRTUAL-MACHINE CONTROL STRUCTURES)

跳转到指定楼层
有人有好的相关资料么?先谢谢了!关于VMCS(VIRTUAL-MACHINE CONTROL STRUCTURES)

VMX

分为root模式和non root模式,


VMCS通过VMPTRST,VMPTRLD修改。

VMREAD,VMWRITE修改VMCS内容。

VMXON,VMXOFF打开关闭VMX。

VMLAUNCH,VMRESUME


VMCS状态的状态管理?

VMPTRLD,转化为active,current

active,current


VMCS的几个区域:

1.Guest-state area

2.Host-state area

3.VM-execution cotrol fields

4.vm-exit control fields

5.vm-entry cotrol fields

6.vm-exit information fileds


Intel寄存器说明:

IDTR:中断描述表指针

GDTR:全局段描述表指针

LDTR:局部段描述表指针


segment selector:包含index,LDTorGDT,访问权限。

CS,SS,DS,ES,FS,GS


TSS段:TSS段的作用。TR寄存器指定。

RSP RIP PFLAGS 栈指针,代码段指针,标示位。

EAX,EBX,ECX,等通用寄存器。

CR0,CR1,CR3,CR4等控制寄存器。CR3指向页表。


那些寄存器需要保留: 理论上需要保留所有的状态信息,以便虚拟机退出再进入的时候,可以正常运行。


实际上硬件VMCS会自动保存和恢复哪些寄存器呢?

CR0,CR3,CR4   


RSP RIP PFLAGS

LDTR

TR

GDTR

IDTR

MSR:

CS, SS, DS, ES, FS, GS

CR1,CR2为什么不保留?

CR2保存的是导致缺页中断的线性地址,CR1目前没有使用。


有哪些寄存器,硬件没有自动保存呢?

EAX,EBX,ECX,等通用寄存器。


为什么硬件没有自动保存呢?

因为这些是通用寄存器,需要通过这些寄存器,通过软件来模拟某些某些指令。


vmx_vcpu_run中的处理:


        asm(
                /* Store host registers */
                "push %%" _ASM_DX "; push %%" _ASM_BP ";"
                "push %%" _ASM_CX " \n\t"                                      /* 在Host OS的栈中保存一个空间,当vm exit的时候,先保存cx到栈上 */
                "push %%" _ASM_CX " \n\t"                                      //保存hostos当前的寄存器信息到内核栈中


                "cmp %%" _ASM_SP ", %c[host_rsp](%0) \n\t"       //把HostOS的SP的保存在vmx中的rsp
                "je 1f \n\t"
                "mov %%" _ASM_SP ", %c[host_rsp](%0) \n\t"

                __ex(ASM_VMX_VMWRITE_RSP_RDX) "\n\t"       //把sp的值保存在vmcs中


                "1: \n\t"
                /* Reload cr2 if changed */                                          //判断vmx中的CR2和实际的CR2,如果不一致,修改CR2
                "mov %c[cr2](%0), %%" _ASM_AX " \n\t"
                "mov %%cr2, %%" _ASM_DX " \n\t"
                "cmp %%" _ASM_AX ", %%" _ASM_DX " \n\t"
                "je 2f \n\t"
                "mov %%" _ASM_AX", %%cr2 \n\t"
                "2: \n\t"


                /* Check if vmlaunch of vmresume is needed */     //在这里判断是因为这里还可以访问vmx
                "cmpl $0, %c[launched](%0) \n\t"

               /* Load guest registers.  Don't clobber flags. */       //把vmx数据结构中的ax,bx,dx,si,di,bp恢复到寄存器
                "mov %c[rax](%0), %%" _ASM_AX " \n\t"              
                "mov %c[rbx](%0), %%" _ASM_BX " \n\t"
                "mov %c[rdx](%0), %%" _ASM_DX " \n\t"
                "mov %c[rsi](%0), %%" _ASM_SI " \n\t"
                "mov %c[rdi](%0), %%" _ASM_DI " \n\t"
                "mov %c[rbp](%0), %%" _ASM_BP " \n\t"


#ifdef CONFIG_X86_64                                                             //64位增加的寄存器
                "mov %c[r8](%0),  %%r8  \n\t"
                "mov %c[r9](%0),  %%r9  \n\t"
                "mov %c[r10](%0), %%r10 \n\t"
                "mov %c[r11](%0), %%r11 \n\t"
                "mov %c[r12](%0), %%r12 \n\t"
                "mov %c[r13](%0), %%r13 \n\t"
                "mov %c[r14](%0), %%r14 \n\t"
                "mov %c[r15](%0), %%r15 \n\t"
#endif

                "mov %c[rcx](%0), %%" _ASM_CX " \n\t" /* kills %0 (ecx) */    //为什么cx放在后面?因为cx本身存放vmx的指针


                /* Enter guest mode */                                                          //根据前面lanched的判断结果,进入non-root模式
                "jne 1f \n\t"
                __ex(ASM_VMX_VMLAUNCH) "\n\t"
                "jmp 2f \n\t"
                "1: " __ex(ASM_VMX_VMRESUME) "\n\t"
                "2: "



                /* Save guest registers, load host registers, keep flags */       退出了
                "mov %0, %c[wordsize](%%" _ASM_SP ") \n\t"                 //把cx保存在栈中遇留的寄存器
                "pop %0 \n\t"                                                                         //把cx从栈中恢复,这个时候cx指向vmx


                "mov %%" _ASM_AX ", %c[rax](%0) \n\t"                         //把寄存器需要保存在vmx中
                "mov %%" _ASM_BX ", %c[rbx](%0) \n\t"
                __ASM_SIZE(pop) " %c[rcx](%0) \n\t"                              //cx为什么要特殊处理?  cx存放在栈中
                "mov %%" _ASM_DX ", %c[rdx](%0) \n\t"
                "mov %%" _ASM_SI ", %c[rsi](%0) \n\t"
                "mov %%" _ASM_DI ", %c[rdi](%0) \n\t"
                "mov %%" _ASM_BP ", %c[rbp](%0) \n\t"

#ifdef CONFIG_X86_64
                "mov %%r8,  %c[r8](%0) \n\t"
                "mov %%r9,  %c[r9](%0) \n\t"
                "mov %%r10, %c[r10](%0) \n\t"
                "mov %%r11, %c[r11](%0) \n\t"
                "mov %%r12, %c[r12](%0) \n\t"
                "mov %%r13, %c[r13](%0) \n\t"
                "mov %%r14, %c[r14](%0) \n\t"
                "mov %%r15, %c[r15](%0) \n\t"
#endif

                "mov %%cr2, %%" _ASM_AX "   \n\t"
                "mov %%" _ASM_AX ", %c[cr2](%0) \n\t"                 //保存cr2寄存器到vmx中的cr2


                "pop  %%" _ASM_BP "; pop  %%" _ASM_DX " \n\t"        //从内核栈上恢复bp,dx
                "setbe %c[fail](%0) \n\t"
                ".pushsection .rodata \n\t"
                ".global vmx_return \n\t"
                "vmx_return: " _ASM_PTR " 2b \n\t"
                ".popsection"
              : : "c"(vmx), "d"((unsigned long)HOST_RSP),                            输入参数,vmx变量存在在ecx中,HOSTRSP存放在edx中。
                [launched]"i"(offsetof(struct vcpu_vmx, __launched)),
                [fail]"i"(offsetof(struct vcpu_vmx, fail)),
                [host_rsp]"i"(offsetof(struct vcpu_vmx, host_rsp)),
                [rax]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RAX])),
                [rbx]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RBX])),
                [rcx]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RCX])),
                [rdx]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RDX])),
                [rsi]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RSI])),
                [rdi]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RDI])),
                [rbp]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RBP])),


#ifdef CONFIG_X86_64
                [r8]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R8])),
                [r9]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R9])),
                [r10]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R10])),
                [r11]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R11])),
                [r12]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R12])),
                [r13]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R13])),
                [r14]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R14])),
                [r15]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_R15])),
#endif
                [cr2]"i"(offsetof(struct vcpu_vmx, vcpu.arch.cr2)),
                [wordsize]"i"(sizeof(ulong))
              : "cc", "memory"                                                       //被影响的寄存器,cx,dx,bp在栈中保存
#ifdef CONFIG_X86_64
                , "rax", "rbx", "rdi", "rsi"
                , "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
#else
                , "eax", "ebx", "edi", "esi"
#endif
              );


Guest non-register state

PDPTES               EPT页表,指向EPT页表

Guest interrupt status

RVI    VAPCI的支持,正在请求的最高优先级中断

SVI     VAPCI的支持,正在处理的最高优先级中断



Host State

VM Entry的时候,会自动保存的HostOS的状态。

CR0,CR3,CR4

RSP,RIP

CS,SS,DS,ES,FS,GS,TR

GDTR,IDTR


VM execution control


Pin-based VM execution Control,指定什么情况下中断导致虚拟机退出。

外部中断,NMI中断都会导致VM exits

Process posted interrupts,VAPIC的支持,

通过posted-interrupt nodification vector,更新apic页表。


Process-based Vm execution control,控制那些指令会导致VM exit。

Excepion Bitmap,确定哪些异常导致VM exit

IO Bitmap Address,确定哪些IO操作导致VM exit

TSC Offest:TSC偏差

MSR-Bitmap Address:



VM-Entry controls fields

event injection,触发向虚拟机中发中断


VM exit information fields

Exit Reason:

Exit qualification:更详细的推出原因

Guest Liner address

Guest physical address:用于EPT页表失效的情况。


Vm-exit interuption information:中断退出情况下的信息

vm-exit interrupt error code:硬件异常的error code


vm-exit instruction length:  因为执行指令导致的退出


谢谢您的分享!
以后多分享一些这样的有价值的帖子啊
好东西一定要看看!
以后多分享一些这样的有价值的帖子啊
以后多分享一些这样的有价值的帖子啊
大家都不容易!
谢谢您的分享!
谢谢您的分享!
您需要登录后才可以回帖 登录 | 注册会员

本版积分规则  | 请遵守晓木虫管理条例,不得违反国家法律法规

返回顶部