【问题标题】:How does KVM/QEMU and guest OS handles page faultKVM/QEMU 和客户操作系统如何处理页面错误
【发布时间】:2020-06-26 20:57:27
【问题描述】:

例如,我有一个启用了 KVM 的主机操作系统(比如 Ubuntu)。我用 QEMU 启动一个虚拟机来运行一个来宾操作系统(比如 CentOS)。据说对于主机操作系统来说,这个虚拟机只是一个进程。因此,从主机的角度来看,它像往常一样处理页面错误(例如,根据需要分配页框,必要时根据活动/非活动列表交换页面)。

这是问题和我的理解。在来宾操作系统中,由于它仍然是一个成熟的操作系统,我认为它仍然具有处理虚拟内存的所有机制。它看到了一些由 QEMU 提供的虚拟化物理内存。通过虚拟化物理内存,我的意思是客户操作系统不知道它在虚拟机中,并且仍然像在真实物理机器上一样工作,但它确实是 QEMU 给出的抽象。因此,即使为它分配了一个页框,如果它不在客户的页表中,客户操作系统仍然会触发页面错误,然后将一些页面映射到该框架。更糟糕的是,可能会出现双页错误,即客户机在页错误时首先分配一些页帧,这会触发主机操作系统的页错误。

不过,我也听说过浅(或影子)页表之类的东西,它似乎可以优化这种不必要的双页错误和双页表问题。我还查看了其他一些内核实现,特别是 unikernel,例如 OSvIncludeOS 等。我没有找到任何与页面错误和页表机制相关的内容。我确实看到了一些像 page_fault_handler 这样的符号,但没有我在 Linux 内核代码中看到的那么大。在这些 un​​ikernel 实现中,内存管理似乎没什么大不了的。所以我假设 QEMU/KVM 和一些英特尔的虚拟化技术已经处理了这个问题。

对这个主题有什么想法吗?或者,如果您对此问题有一些很好的参考资料/论文/资源,或者一些提示会非常有帮助。

【问题讨论】:

    标签: linux-kernel kernel virtualization qemu kvm


    【解决方案1】:

    QEMU/KVM 有两种方式支持客户物理内存:EPT 和影子页表。 (EPT是Intel定义的机制,其他处理器也支持类似的,这里就不多说了。)

    EPT 代表扩展页表。除了常规处理器页表之外,它是 CPU 支持的第二级分页。在 VM 中运行时,常规页表用于将访客虚拟地址转换为访客物理地址,而 EPT 表用于将访客物理地址转换为主机物理地址。这种双级转换针对来宾中的每个内存访问执行。 (处理器 TLB 隐藏了大部分成本。) EPT 表由 VMM 管理,而常规页表由来宾管理。如果来宾页表中不存在页面,则会导致来宾内部出现页面错误,正如您所描述的那样。如果访客页表中存在页面但 EPT 中不存在,则会导致违反 EPT 的 VM 退出,因此 VMM 可以处理丢失的页面。

    当 EPT 不可用时,使用影子页表。影子页表是客户页表的副本,它在一组页表中合并了 GVA 到 GPA 和 GPA 到 HPA 映射。发生页面错误时,总是会导致 VM 退出。 VMM 检查丢失的页面是否映射到来宾页表中。如果不是,则 VMM 将页面错误注入到客户机中以供其处理。如果页面映射到来宾页面表中,则 VMM 会像处理 EPT 违规一样处理故障。在来宾内跨多个进程有效管理影子页表可能非常复杂。

    EPT 实现起来更简单,并且对于大多数工作负载而言具有更好的性能,因为页面错误是直接生成到客户操作系统的,而这通常是它们需要处理的地方。使用影子页表需要为每个页面错误退出 VM。然而,影子页表对于一些导致很少页面错误的特定工作负载可能具有更好的性能。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-08
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多