假设有这样的代码。
MOV [0x1234], EAX (intel assembly)
假设CPU想要处理此指令。 我们假设没有管理程序。 我们只是在linux环境中使用普通的x86 CPU(保护模式)。
现在,我理解的是 由于0x1234是虚拟地址,因此需要进行转换 到物理地址。(让我们跳过分段部分)
CPU只是将此地址(0x1234)传递给MMU硬件。 MMU遍历页表并使用物理地址访问内存内容。
我是对的吗?现在让我们假设有管理程序和此代码 从客户操作系统运行。
究竟发生了什么?
我知道虚拟机管理程序提供了另一层页面表。 但我不明白这是如何运作的。
如果执行了访客代码“MOV [0x1234],EAX” 在真正的CPU中。虚拟地址0x1234将被翻译 真正的硬件MMU。所以我认为这个指令必须如此 重写(0x1234应该替换为另一个地址 在代码执行之前),或被困在管理程序...
我错了吗? 如果我错了,请修正我的理解......提前谢谢。
答案 0 :(得分:5)
回答你的第一个问题:是的,你是。这基本上就是虚拟内存的工作原理。
现在,让我们看看当MMU和客户操作系统之间运行虚拟机管理程序时会发生什么。出于性能考虑,虚拟机管理程序(它们是类型1 或类型2 )将尝试避免在每个来宾操作系统内存访问时捕获。我们的想法是让管理MMU的客户操作系统。我将详细介绍可能的实现,一个用于x86,另一个用于PowerPC。
在x86上,来自Intel's manual 3B:
27.3.2嘉宾&主机物理地址空间
内存虚拟化为访客软件提供连续的客户物理 地址空间从零开始并扩展到支持的最大地址 来宾虚拟处理器的物理地址宽度。 VMM利用客户物理 托管物理地址映射以定位客户物理的全部或部分 主机内存中的地址空间。 VMM负责策略和算法 对于这种可能考虑到主机系统物理的映射 内存映射和由客户端公开的虚拟化物理内存映射 VMM。
VMM知道VM的当前PDBR
基地址(PDBR
保留在CR3
寄存器中),因为访问CR3
将导致VM_EXIT 。 VMM将能够代表来宾操作系统维护真实页面目录。我的意思是当客户操作系统修改其页面目录以将逻辑地址A映射到物理地址B时,VMM对此进行陷阱,而不是将A映射到B,它将A映射到C.因此,对A的任何进一步访问都不会导致#PF,它将通过MMU完美地路由到C。这种方法的悲哀之处在于客户认为它已将A映射到B,但实际上A映射到C,因此VMM必须维护虚拟页面目录,以防客户端读取它先前映射到A的位置。 VMM捕获此读取访问权限,而不是将A映射到B,而是返回到A映射到C的guest虚拟机。
27.3.3通过暴力虚拟化虚拟内存
这样做的简单方法是确保所有访客都尝试访问 地址转换硬件陷阱到VMM,这些操作可以正常进行 效仿。它必须确保访问页面目录和页表 被困。这可以通过用常规方法保护这些内存中结构来完成 基于页面的保护。 VMM可以执行此操作,因为它可以找到页面 目录,因为它的基地址在CR3中,VMM接收任何控制 改为CR3;它可以找到页表,因为它们的基地址在 页面目录。
在PowerPC上,您没有像英特尔那样的页面目录的硬件表。 TLB的每次修改都是由一条指令引起的,通常来自内核内存管理器。同样,一个直截了当的想法是捕获每个访客对TLB的访问权限(例如,当访客执行tlbwe
指令时设置导致VM退出的事项;注意:tlbwe
将一个条目写入TLB)。一旦进入VMM,管理程序就会对捕获指令进行解码,并模拟其行为,但不是将A映射到B,而是将A映射到C,直接映射到TLB。同样,VMM必须维护虚拟TLB ,以防客户操作系统想要检查TLB中的内容,并返回它认为早先放入TLB的内容。
总而言之,虽然某些硬件功能有助于虚拟化客户物理内存,但通常由VMM来管理有效的客户 - 物理到主机 - 物理内存映射。