jingxin168

qemu/kvm 进程很像一个普通的linux程序。它通过通常的malloc和mmap调用来申请内存。
如果一个客户系统想使用1G物理内存,qemu/kvm将会做一个malloc(1<<30)调用,在主机上申请1G的虚拟地址。然而,就像一个普通的程序做一个malloc,在这个时候没有实际的物理内存被分配。只有当这片内存第一次被访问的时候(触发异常)才会真正的分配物理内存。

      客户系统一旦开始运行,就会把qemu通过malloc申请的内存区域看作它的物理内存(实际上只是在主机上的虚拟内存)。如果客户机的内核访问(以它的角度看到的)0x00处的物理内存,它访问的实际是qemu/kvm进程通过malloc申请的第一页内存。

      通常每一次运行在kvm上的客户机改变它的页表,主机也必须相应的配合。主机需要验证客户机放在
它页表的条目是有效的以及客户机没有访问任何不允许的内存。主机通过2种机制来实现这些。

       一个是虚拟化硬件实际所使用的一套页表与客户机“认为”使用的页表是分开的。客户机首先在它的页表上做一个修改。主机再通知这个变化,验证它,然后创建一个被硬件访问的真实页表。客户机不允许直接操作被硬件访问的页表。这个概念叫做影子页表,这是一种在虚拟化中很常见的一种技术。

      第二个就是VMX/AMD-V扩展机制允许主机在任何时候捕获客户机试图写指向基页表的寄存器(CR3)的操作。

    这项技术工作的很好,但是他也有一些很严重的性能影响。一次单一的访问客户系统页可以使用多达25次的内存访问(xx),这些很消耗资源。见:http://developer.amd.com/assets/NPT-WP-1%201-final-TM.pdf。基本的问题就是每一次对内存的访问必须经过客户机和主机的页表。对于主机来说校验维护影子页表都是很消耗资源的。



Intel和AMD都有针对这些问题的解决方案也提出了相似的解决方案EPT/NPT。他们指定了一组可以被硬件识别的数据结构,用来快速的把客户机的物理地址转化为主机的物理地址,而不用通过主机的页表。这项技术取代了消耗资源的两次页表转换。

     此时,我们使用主机页表来执行一些事情例如进程隔离。如果一个页被从主机上unmap(比如交换进swap)了,我们必须使用新的硬件EPT/NPT数据结构来协调这些改变。


       这个软件上的解决方式linux叫做mmu_notifiers。qemu/kvm使用的内存是普通的linux内存(从主机linux内核的角度)内核可能试着要swap,replace,甚至free它就像使用普通内存一样。


      但是,在这些页表被真正返回给主机内核使用之前,kvm/qemu客户机被通知主机的意图。kvm/qemu客户机可以从NPT/EPT结构体中或者影子页表中移除这个页。当kvm/qemu客户机完成这些之后,主机内核就可以随意使用这些页表。

    

    
A day in the life of a KVM guest physical page:
    Fault-in path 
    1。QEMU调用malloc为页表申请虚拟空间,但是此时还没有相应的物理页。
    2。客户机进程访问它认为的物理地址,但是在相应的物理内存没有分配之前会陷进主机。
    3。主机内核发现一个页错误,对malloc申请的内存调用do_page_fault,如果一切顺利此时就准备物理内存。
    4。主机内核创建一个pte_t来在malloc申请的虚拟地址和主机的物理地址之间建立连接,创建rmap条目放在LRU,
       等等。
    5。mmu_notifier,change_pte  (xx)被调用,允许kvm为新的页创建一个NPT或者EPT条目。
    6。主机从页错误中返回,客户机继续执行。

    Swap-out path 
    现在,让我们看一下主机处在内存压力下的情况。上面提到的页遍历Linux LRU发现自己在没有激活的list上
    (按照某种策略一段时间内没有访问?(xx))。内核决定收回这个页表:
    1。主机内核使用rmap结构体来发现这个页映射在哪个VMA(vm_area_struct)上。
    2。主机内核查找与那个VMA有关的mm_struct,遍历linux页表来为这个页找到pte_t。
    3。主机内核把这个页交换进虚拟内存清除pte_t(这里假设这个物理页之被映射到一个虚拟地址)。但是在释放
          这个页之前:
    4。主机内核调用mmu_notifier invalidate_pate()。在NPT/EPT结构体中查找页的条目并且删除它。

    5。现在任何对这个页的访问将会陷进主机中。(上面提到的Fault-in path 第(2)步)

 

原文链接:
http://www.linux-kvm.org/page/Memory

 

转自 https://blog.csdn.net/gudujianjsk/article/details/7519562

分类:

技术点:

相关文章:

猜你喜欢