KVM实现机制[2]

时间 : 14-06-14 栏目 : 虚拟化 作者 : 老薛 评论 : 0 点击 : 1,772 次

2.2.KVM实现
作为VMM,KVM分为两部分,分别是运行于Kernel模式的KVM内核模块和运行于User模式的Qemu模块。这里的Kernel模式和User模 式,实际上指的是VMX根模式下的特权级0和特权级3。另外,KVM将虚拟机所在的运行模式称为Guest模式。所谓Guest模式,实际上指的是VMX 的非根模式。

010

利用VT-x技术的支持,KVM中的每个虚拟机可具有多个虚拟处理器VCPU,每个VCPU对应一个Qemu线程,VCPU的创建初始化运行以及退出处理都在Qemu线程上下文中进行,需要Kernel、User和Guest三种模式相互配合,其工作模型如图2.1所示。Qemu线程与KVM内核模块间以ioctl的方式进行交互,而KVM内核模块与客户软件之间通过VM Exit和VM entry操作进行切换。
Qemu线程以ioctl的方式指示KVM内核模块进行VCPU的创建和初始化等操作,主要指VMM创建VCPU运行所需的各种数据结构并初始化。其中很重要的一个数据结构就是VMCS,其初始化配置见附2。
初始化工作完成之后,Qemu线程以ioctl的方式向KVM内核模块发出运行VCPU的指示,后者执行VM entry操作,将处理器由kernel模式切换到Guest模式,中止宿主机软件,转而运行客户软件。注意,宿主机软件被中止时,正处于Qemu线程上 下文,且正在执行ioctl系统调用的kernel模式处理程序。客户软件在运行过程中,如发生异常或外部中断等事件,或执行I/O操作,可能导致VM exit,将处理器状态由Guest模式切换回Kernel模式。KVM内核模块检查发生VM exit的原因,如果VM exit由于I/O操作导致,则执行系统调用返回操作,将I/O操作交给处于User模式的Qemu线程来处理,Qemu线程在处理完I/O操作后再次执 行ioctl,指示KVM切换处理器到Guest模式,恢复客户软件的运行;如果VM exit由于其它原因导致,则由KVM内核模块负责处理,并在处理后切换处理器到Guest模式,恢复客户机的运行。

3.内存虚拟化
3.1.VT-x内存虚拟化介绍
3.1.1.基于VTLB的内存虚拟化
对于x86平台来说,处理器在加电或复位后处于实模式,此后在操作系统的操纵下一般会先切换到非分页保护模式,最后在切换到分页保护模式。VMM必须能够 满足以上各种模式下的内存虚拟化要求,完全控制客户机对物理地址的访问,实现虚拟机间物理内存的隔离,并对客户机保持透明。客户机绝大多数情况下将工作在 分页保护模式下,因此我们首先介绍客户机工作在分页保护模式时的内存虚拟化。
我们知道,当处理器未启动VMX模式时,页表机制确定了线性地址到物理地址的对应关系。为了加快地址转换的效率,减少地址转换过程中的页表访问次数,处理 器使用TLB(Translation Lookaside Buffer)来缓存线性地址到物理地址的映射关系。实际的地址转换过程中,处理器首先根据线性地址查找TLB,如果未发现该线性地址到物理地址的映射关 系(TLB miss),将根据页表中的映射关系填充TLB(TLB fill),然后再进行地址转换。因此,页表虽然确定了线性地址到物理地址的对应关系,但它并不直接控制线性地址到物理地址的转换,这种转换是由TLB控 制的。在不会导致地址转换错误的前提下,处理器不要求TLB的内容一定与页表保持一致,例如一次进程切换后,TLB的内容可能都是无效的,但进程的页表却 是有效的,此时页表和TLB是不一致的,以后访问内存时会引发TLB miss,并通过TLB fill令某个页表项与某个TLB项保持一致。
VT-x中可采用一种称为Virtual TLB(VTLB)的技术来实现内存虚拟化,其思想就源于上述多级页表与TLB间的交互机制,其工作机制如图3.1所示。VM的页表并不直接控制线性地址 到物理地址的转换,即CR3寄存器并不指向VM的页目录,而是指向VMM维护的影子页表(Shadow Page Table),因此线性地址到物理地址的转换是由影子页表和TLB来控制的,影子页表和TLB共同构成了所谓的Virtual TLB。VM可以任意修改其页表,而不会导致VM exit,由此可能产生两种VM页表与VTLB之间的不一致情况。
第一种不一致是指VM的页表拥有比影子页表更多的访问能力,可以利用页面故障来修补这种不一致性。例如VM页表有某个线性地址到物理的对应关系而影子页表中却没有,那么VM对该线性地址的访问将导致页面故障。VMM可以捕获该异常,进而根据VM的页表来修改影子页表。
第二种不一致是指VM的页表的访问能力不及影子页表,那么一定是由于VM修改了自己的页表,并且把页表的访问权限降低了,例如页面交换将页表项的P位置 0,但该操作并不会马上反映到TLB中。此时,VM需要执行INVLPG指令或重装CR3寄存器来刷新TLB,VM在执行INVLPG指令或重装CR3寄 存器时将导致VM exit,使VMM有机会根据VM的页表来修改影子页表,从而修补这种不一致性。
另外,处理器在进行内存访问时会自动修改页表项的A位或D位。A位在所有级别的页表项中都存在,但在TLB entry中并不缓存A位,原因是本次访存操作涉及的各个级别的页表项都允许本次访问,才会在TLB中生成一个entry,因此只要TLB中存在一个 entry,那么一定已经将entry相关的各级页表项都访问过了,各级页表项的A位都是1。处理器在初次访问一个页表项时,将其A位置1,但由软件负责 将A位清0。如果软件将A位由1变成0,它应该使用INVLPG指令使对应的TLB entry失效。如果不这样做,那么在访存时,总是使用TLB中缓存的entry,处理器认为页表项中的A位已经是1了,从而不会将A位由0改为1。在软 件看来,好象该页自将A位置0以来未曾被访问过,而实际情况并不是这样。
D位仅在最后一级页表中存在,而且在TLB entry中也缓存D位。当首次写一个页时,如果TLB entry不存在或其D位为0,则将页表项中的D位置1,同A位相同,由软件负责将D位置1。如果软件将PTE的D位由1变成0,应该使用INVLPG指 令使对应的TLB entry失效。如果不这样做,那么再次写该页时,总是优先使用缓存的TLB entry,并且TLB entry的D位为1,这时处理器认为PTE的D位已经是1了,它不会再将其置1。在软件看来,好象该页自将D位置0以来未曾被写过,而实际情况并不是这 样。
由于VM进行内存访问实际使用的是影子页表,因此这种修改不能自动反映到客户页表中,从而导致客户页表和影子页表的不一致。应该有某种机制使VMM得以捕获处理器对影子页表的A位和D位的初次修改,并更新VM页表,从而解决这种不一致性。
对于A位,只要VMM不先于VM建立线性地址到物理地址的映射关系,就可以确保捕获客户对内存的访问,进而有机会确保影子页表项和客户页表项在A位上的一 致。因为,当客户首次访问某个线性地址时,由于影子页表中没有该线性地址到物理地址的对应关系,将导致一次页面故障,VMM可以捕获该故障,在影子页表中 建立线性地址到物理地址的对应关系,并将客户页表中相应项的A位置1。
对于D位,VMM在影子页表中建立线性地址到物理地址间的映射之初,可以将页置为只读,这样当VM对该页进行写操作时,将导致页面故障,使VMM获得控制,进而有机会确保影子页表项和VM页表项在D位上的一致。

k1

上面提到,VMM必须能够满足以上各种处理器模式下的内存虚拟化要求,但由于VMX模式要求处理器必须工作在分页保护模式下,因此VMM不可能允许客户软 件将处理器切换到实模式或非分页保护模式,而只能在分页保护模式下为客户软件模拟出类似实模式或非分页保护模式的环境。
可采用一个v86任务来模拟客户机所需的实模式环境。我们知道,v86软件在执行时,其逻辑地址经16位分段机制转换为20位线性地址,其后再经过分页机 制转换为物理地址。因此,在客户机引导之初,VMM可以另客户操作系统的实模式代码执行于一个v86任务中,并为其构造执行所需的页表结构,从而接管客户 软件对物理内存访问。
客户的非分页保护模式代码实际上是执行在分页保护模式之下,只不过通过影子CR0等机制使客户察觉不到而已。客户逻辑地址经32位分段机制转换后为32位线性地址,而后经VMM构造的页表转换为物理地址,从而避免了客户软件对物理内存的直接控制。
3.1.2.基于EPT的内存虚拟化
基于VTLB进行内存虚拟化时,因为客户在读写CR3、执行INVLPG指令或客户页表不完整等情况下均会导致VM exit,这导致了内存虚拟化效率很低。较新的Intel处理器中引入了EPT(Extended Page Table)技术,用于提高内存虚拟化的效率。
EPT引入了额外的一套页表结构,后者定义了客户物理地址到主机物理地址之间的映射关系,所有的客户物理地址(如CR3给出的页目录基址、PDE给出的页表基址、PTE给出的页基址等)须经由EPT页表结构转换后用于访存,其原理如图3.2所示。

k2

EPT由VMM控制,并且仅在处理器工作于非根模式时才参与地址转换。采用EPT后,客户在读写CR3和执行INVLPG指令时不会导致VM exit,并且由于客户页表结构自身导致的页故障也不会导致VM exit,因此极大地提高了内存虚拟化的效率,简化了内存虚拟化的实现。

除非注明,文章均为( 老薛 )原创,转载请保留链接: http://www.bdkyr.com/uncategorized/122.html

随便看看

0