Intel VMCS学习总结
来源:互联网 发布:淘宝怎么上传质检报告 编辑:程序博客网 时间:2024/05/17 03:08
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, GSCR1,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: 因为执行指令导致的退出
vm-exit instruction information:
- Intel VMCS学习总结
- VMCS研究总结
- VMCS研究总结
- VMX学习-VMCS
- Intel Pin 学习总结
- Intel 保护模式学习总结
- 操作系统虚拟化原理总结篇——VMCS详解
- 2.3 VMCS
- 看操作系统虚拟化原理总结篇——VMCS详解
- 看操作系统虚拟化原理总结篇——VMCS详解
- Intel杯竞赛总结
- Intel面试总结20100104
- 今天intel面试总结
- intel笔试总结
- ffmpeg Intel硬件加速总结
- VMX和VMCS
- VT VMCS结构信息
- Intel Thread Checker学习
- 4-h-Median of Two Sorted Arrays
- Ubuntu下更改网卡名称
- 数字滤波技术
- LeetCode Valid Parentheses
- 详解APNS苹果消息推送通知
- Intel VMCS学习总结
- python多线程与线程同步
- 145.Binary Tree Postorder Traversal
- NVIDIA 的深度学习工具箱NVIDIA DIGITS:可视化训练
- 在JAVA中目录列表器file的应用及Matcher对象与Pattern对象的使用
- VMware11安装OS X10.10和xcode整理
- Leetcode Valid Palindrome
- [转]学JS必看
- 查验身份证(15)