Advertisement

Intel VMCS学习总结

阅读量:

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当前的寄存器信息到内核栈中

Compare asm_sp with host_rsp(%0) in the VMX. //Save the SP from the host OS into the VMX's rsp.
Jump to address 1f. //跳转到地址1f
Move asm_sp into host_rsp(%0). //将asm_sp移动至host_rsp(%0)

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

"1: \n\t"
/* Reload cr2 if changed */ //判断vmx中的CR2和实际的CR2,如果不一致,修改CR2
"mov %ccr2, %%" _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"

Determine whether vmlaunch of vmresume is necessary. //此处判断的原因是由于还可以访问vmx

/* Load the guest registers without disturbing the flags. */ // Revert the ax, bx, dx, si, di and bp fields from the guest VMX structure to the CPU registers
"Move the contents of register (%0) in the guest VMX structure into register AX." _ASM_AX "\n\t"
"Move data from register (%0) in VMX to BX." _ASM_BX "\n\t"
"Transfer value from (%0) in VMX to DX." _ASM_DX "\n\t"
"Retrieve value from (%0) in VMX and store in SI." _ASM_SI "\n\t"
"Fetch data from (%0) in VMX into DI." _ASM_DI "\n\t"
"Multiply content of (%0) in VMX by BP and store result." _ASM_BP "\n\t"

#ifdef CONFIG_X86_64 /为64位扩展了寄存器组/
"执行目标地址值的操作\n完成目标地址值的操作\n完成目标地址值的操作\n完成目标地址值的操作\n完成目标地址值的操作\n完成目标地址值的操作\n完成目标地址值的操作\n完成目标地址值的操作"
#endif

mov %basercx, _ASM_CX " \n\t" // instruction clears src_reg (ecx)
//why cx is after? because cx stores vmx pointer.

/* Enter guest mode */ //基于前面lanched的判定结果, 进入non-root模式
"jne 1f \n"
执行jne指令至内存地址0x01ff并换行
"jmp 2f \n"
执行jmp指令至内存地址0x02ff并换行
"1: "
通过__ex函数执行ASM_VMX_VMLAUNCH指令并换行
"2: "
通过__ex函数执行ASM_VMX_VMRESUME指令并换行

/* 保存Guest寄存器、加载Host寄存器并保持标志位 */ 退出程序
"mov %0, %cwordsize \n\t" //将CX寄存器的数据压入栈中
"pop %0 \n\t" //从栈中弹出CX寄存器的数据,并更新基址使其指向VMX段

将寄存器需保存至vmx段中
将寄存器需保存至bx段中
关于cx寄存器的存放位置,请注意其需被放置于栈中
dx寄存器为何需特别处理?
si寄存器为何特别设计?
di寄存器为何需特别注意?
bp寄存器为何需特别处理?

#ifdef CONFIG_X86_64
将%%r8赋值为%cr8
将%%r9赋值为%cr9
将%%r10赋值为%cr10
将%%r11赋值为%cr11
将%%r12赋值为%cr12
将%%r13赋值为%cr13
将%%r14赋值为%cr14
将%%r15赋值为%cr15
#endif

"mov %%cr2, %%" _ASM_AX " \n\t"
"mov %%" _ASM_AX ", %ccr2 \n\t" //保存cr2寄存器到vmx中的cr2

以下是改写后的文本

#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: 因为执行指令导致的退出

vm-exit instruction information:

全部评论 (0)

还没有任何评论哟~