也谈Intel的cpu虚拟化

2018-04-13 22:34:04 浏览数 (1)

讲到intel的cpu虚拟化,就不得不提到vt-x。vt-x是intel的CPU硬件虚拟化技术,但是在操作系统内部查看cpu的flag时,是否支持硬件虚拟化的的判断标准是是否有vmx,vmx是什么,它和虚拟化有什么关系,本文将会涉及到。

几个基础概念

1.VMM

虚拟机监视器在宿主机上表现为一个提供虚拟机CPU,内存以及一系列硬件虚拟的实体,这个实体在KVM体系中就是一个进程,如qemu-kvm。VMM负责管理虚拟机的资源,并拥有所有虚拟机资源的控制权,包括切换虚拟机的CPU上下文等。

2.Guest

可能是一个操作系统(OS),也可能就是一个二进制程序。对于VMM来说,他就是一堆指令集,只需要知道入口(rip寄存器值)就可以加载。

Guest运行需要虚拟CPU,当Guest代码运行的时候,处于VMX non-root模式,此模式下,该用什么指令还是用什么指令,该用什么寄存器还用什么寄存器,该用cache还是用cache,但是在执行到特殊指令的时候(比如Demo中的out指令),把CPU控制权交给VMM,由VMM来处理特殊指令,完成硬件操作。

3.CPU运行级别

CPU支持ring0~ring3 4个等级,但是Linux只使用了其中的两个ring0,ring3。当CPU寄存器标示了当前CPU处于ring0级别的时候,表示此时CPU正在运行的是内核的代码。而当CPU处于ring3级别的时候,表示此时CPU正在运行的是用户级别的代码。当发生系统调用或者进程切换的时候,CPU会从ring3级别转到ring0级别。ring3级别是不允许执行硬件操作的,所有硬件操作都需要内核提供的系统调用来完成。

4.VMX

为了从CPU层面支持VT技术,Intel-V 在 ring0~ring3 的基础上, 扩展了传统的x86处理器架构,引入了VMX模式,VMX分为root和non-root。VMM运行在VMX root模式;Guest运行在VMX non-root模式。

CPU虚拟化

有了cpu的运行级别和VMX,就可以看一下CPU虚拟化的基本运行情况了。

Guest OS里的内核运行于VMX non-root下的ring0

Guest OS里的应用程序运行于VMX non-root模式下的ring3

Host OS的内核和VMM运行于VMX root模式下的ring0。

虽然GuestOS的内核也运行于ring0,但是由于是non-root模式,所以不能操作某些资源,不能运行敏感指令。

Guest也分ring0~ring3,不过他并不感知自己处于VMX non-root模式下。

VMM与Guest的切换

1. VM entry 和 VM exit

Guest与VMM之间的切换有两个过程:VM entry 和 VM exit。Guest运行时处于VMX下的non-root模式,当执行了特殊操作的时候(具体哪种操作后面的VM exit原因中会提到),通过VM exit将cpu控制权返回给VMM,从而陷入到root模式下的ring0内的VMM,进行“陷入模拟”。 VMM处理完特殊操作后再通过VM entry把结果和控制权返回给Guest。

2.导致VM exit的原因

导致VM exit的原因有多种,例如Guest执行了硬件IO访问操作,或者Guest调用了VMCALL指令,或者调用了退出指令,或者产生了一个page fault,或者访问了特殊设备的寄存器等。在内核中有关于VM exit原因的列表。

3.VMCS:(虚拟机控制结构)

这是虚拟机的户口本,对虚拟机至关重要。Guest Exit的时候,会将当前Guest的上下文保存到VMCS中,Guest entry的时候把VMCS上下文恢复给VMM。VMCS是一个64位的指针,指向一个真实的内存地址,VMCS是以vCPU为单位的,即Guest有多少个vCPU,就对应多少个VMCS指针。VMCS的操作包括VMREAD,VMWRITE,VMCLEAR。

当Guest发起执行的指令处于VMX模式(包括运行VMM的root和运行Guest代码的non-root)的时候,Guest不能判断当前CPU是否处于VMX模式还是非VMX模式。当产生VM exit的时候,CPU会将exit reason保存到MSRs(VMX模式的特殊寄存器组),对应到KVM就是vCPU->kvm_run->exit_reason。VMM再根据exit_reason做相应的处理。所以MSRs寄存器就成了Guest和VMX交接的中间人。

关于Intel的cpu虚拟化的详细说明可参考:


关注本公众号,了解更多关于云计算虚拟化的知识。

0 人点赞