您的位置:首页 > 其它

qemu-kvm内存虚拟化原理

2017-03-20 11:59 316 查看
Guest Physical Address, GPA  客户机物理地址

Guest Virtual  Address, GVA  客户机虚拟地址

Host  Physical Address, HPA  宿主机物理地址

Host  Virtual  Address, HVA  宿主机虚拟地址

kvm 内存虚拟化结构:(有点类似 vmalloc 原理)客户机里面使用的物理地址(从0开始连续的一段地址),在宿主机里面看来却不是连续的,而是有各个地址空间映射为连续的;

客户机物理地址(pb 表示 物理地址区间)

pb0 | pb1 | pb2 | .... | pbn

vb0 | vb1 | vb2 | .... | vbn

宿主机虚拟机地址(vb 表示 虚拟机地址区间)

上面的映射一定不是 pb0 == vb0 , pb1 == vb1 ..... pbn == vbn;他们之间有些是错开映射的;

kvm 内存虚拟化的重点就是:GVA->HPA,客户机虚拟机地址到宿主机物理地址的转换;

由于在访问内存地址时,要进过MMU的映射,物理地址映射为总线上的地址(可以理解为内存卡上地址);客户机里的物理地址不能直接进行MMU映射使用,所以就必须把客户机的物理地址映射为宿主机的物理地址,然后MMU访问总线内存地址;

KVM 用一个 kvm_memory_slot 数据结构来记录每一个地址区间的映射关系,此数据结构包含了对应此映射区间的起始客户机页帧号 (Guest Frame Number, GFN),映射的内存页数目以及起始宿主机虚拟地址。

首先根据客户机物理地址找到对应的映射区间,然后根据此客户机物理地址在此映射区间的偏移量就可以得到其对应的宿主机虚拟地址。进而再通过宿主机的页表也可实现客户机物理地址到宿主机物理地址之间的转换,也即 GPA 到 HPA 的转换。

根据上述客户机物理地址到宿主机物理地址之间的转换以及客户机页表,即可实现客户机虚拟地址空间到客户机物理地址空间之间的映射,也即 GVA 到 HPA 的转换。显然通过这种映射方式,客户机的每次内存访问都需要 KVM 介入,并由软件进行多次地址转换,其效率是非常低的。

提供两种方法来简化这种低效的映射:

影子页表:

首先根据客户机页表把客户机虚拟地址转传成客户机物理地址,然后再通过客户机物理地址到宿主机虚拟地址之间的映射转换成宿主机虚拟地址,最后再根据宿主机页表把宿主机虚拟地址转换成宿主机物理地址。而通过影子页表,则可以实现客户机虚拟地址到宿主机物理地址的直接转换。

影子页表简化了地址转换过程,实现了客户机虚拟地址空间到宿主机物理地址空间的直接映射。但是由于客户机中每个进程都有自己的虚拟地址空间,

所以 KVM 需要为客户机中的每个进程页表都要维护一套相应的影子页表。在客户机访问内存时,真正被装入宿主机 MMU 的是客户机当前页表所对应的影子页表,从而实现了从客户机虚拟地址到宿主机物理地址的直接转换。而且,在 TLB 和CPU缓存上缓存的是来自影子页表中客户机虚拟地址和宿主机物理地址之间的映射,也因此提高了缓存的效率。

为了快速检索客户机页表所对应的的影子页表,KVM 为每个客户机都维护了一个哈希表,影子页表和客户机页表通过此哈希表进行映射。对于每一个客户机来说,客户机的页目录和页表都有唯一的客户机物理地址,通过页目录 / 页表的客户机物理地址就可以在哈希链表中快速地找到对应的影子页目录 / 页表。在检索哈希表时,KVM 把客户机页目录 / 页表的客户机物理地址低 10 位作为键值进行索引,根据其键值定位到对应的链表,然后遍历此链表找到对应的影子页目录 / 页表。当然,如果不能发现对应的影子页目录 / 页表,说明 KVM 还没有为其建立,于是
KVM 就为其分配新的物理页并加入此链表,从而建立起客户机页目录 / 页表和对应的影子页目录 / 页表之间的映射。当客户机切换进程时,客户机操作系统会把待切换进程的页表基址载入 CR3而 KVM 将会截获这一特权指令,进行新的处理,也即在哈希表中找到与此页表基址对应的影子页表基址,载入客户机 CR3,使客户机在恢复运行时 CR3 实际指向的是新切换进程对应的影子页表。

重点: 

1、kvm 内存虚拟化的重点就是:GVA->HPA,客户机虚拟机地址到宿主机物理地址的转换;kvm_memory_slot 数据结构来记录每一个地址区间的映射关系

    GVA->GPA->kvm_memory_slot->HVA->HPA

2、影子页表:客户机虚拟地址空间到宿主机物理地址空间的直接映;KVM 需要为客户机中的每个进程页表都要维护一套相应的影子页表;在客户机访问内存时,真正被装入宿主机 MMU 的是客户机当前页表所对应的影子页表;

 

3、哈希表:KVM 为每个客户机都维护了一个哈希表,影子页表和客户机页表通过此哈希表进行映射。通过页目录/页表的客户机物理地址就可以在哈希链表中快速地找到对应的影子页目录/页表

   

   KVM 把客户机页目录/页表的客户机物理地址低 10 位作为键值进行索引,根据其键值定位到对应的链表,然后遍历此链表找到对应的影子页目录/页表。

   

4、异常

   如果该异常是由客户机本身引起的,KVM 则直接把该异常交由客户机的缺页异常处理机制来进行处理。

   如果该异常是由客户机页表和影子页表不一致引起的,KVM 则根据客户机页表同步影子页表。

   

关系:客户机虚拟地址---> 哈希表 ---> 影子页表 ---> 虚拟地址--->宿主物理地址;

   哈希表之所以用物理地址映射(到影子页表是用虚拟机地址的)是因为每个客户机只有一个哈希表,而虚拟地址每个客户机有多个进程对应的虚拟机地址,也有多个影子表。而物理地址只有一个;以通过物理地址唯一来对应哈希表唯一,并且影子页表也是通过cr3来确定唯一;

知识点:

TLB表,TLB:
Translation Lookaside Buffer:里面存放的是一些页表文件(虚拟地址到物理地址的转换表)

转载地址:https://www.ibm.com/developerworks/cn/linux/l-cn-kvm-mem/index.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  虚拟化 影子页表