Linux在x86-64中如何支持超过512GB的虚拟地址范围?

用于Linux的x86-64的用户虚拟地址空间是47位长。 这基本上意味着Linux可以映射具有大约128 TB的虚拟地址范围的进程。

然而,我认为x86-64体系结构支持ISA为每个进程定义了4级分层页表(排列为基数树)。 页表的根目录最多只能映射512 GB的连续虚拟地址空间。 那么Linux如何能够支持超过512GB的虚拟地址范围呢? 它是否为每个进程使用多个页表? 如果是的话,那么对于一个进程来说,CR3(x86-64的寄存器包含页表的基地址)应该包含什么给定的进程? 我错过了什么吗?

Solutions Collecting From Web of "Linux在x86-64中如何支持超过512GB的虚拟地址范围?"

页表的根目录最多只能映射512 GB的连续虚拟地址空间。 那么Linux如何能够支持超过512GB的虚拟地址范围呢? 它是否为每个进程使用多个页表? 如果是的话,那么对于一个进程来说,CR3(x86-64的寄存器包含页表的基地址)应该包含哪个进程? 我错过了什么吗?

我不知道“页表的根目录”是什么意思,但是在x86-64上的分页看起来像这样:

  • 页表 – 分页结构的最低级别。 每个都有512个8字节的条目(PTE),描述一个4 KiB的页面,所以PT描述了512 * 4 KiB = 2 MiB的内存(它也可以作为2 MiB页面,但现在我们暂且离开)。
  • 页面目录 – 与PT类似,包含512个指向PT的8字节条目(PDE); 因此,PD描述512 * 2 MiB = 1 GiB (它也可以作为1 GiB页面,与PT类似)。
  • 页目录页面表 – 类似于PD,但包含指向PD的512个8字节条目(PDPTE); 所以,PDPTE描述了512 * 1 Gib = 512 GiB的内存。
  • 最高级别的分页结构PML4是包含指向PDPT的512个8字节条目(PML4E)的表; 所以,PML4描述512 * 512 GiB = 256 TiB的内存。

我不知道Linux的确切的内存映射,但可能更高的一半(从-128 TiB到0 – 从0xFFFF8000000000000xFFFFFFFFFFFFFFFF )被保留给内核,下半部分(从0到128 TiB – 从0x00000000000000000x00007FFFFFFFFFFF )用户空间应用程序 所以,Linux支持您要求的512个512B的虚拟地址范围; 即使Torvalds也不会说“我们不会支持PML4”。 我不知道是什么让你感到困惑 – 是不是因为你错过了那个页面表格地图2 MiB,而是因为它映射了一个页面 – 4 KiB – 但是如果有什么我可以澄清的话,它。

通常,进程地址空间不共享,也就是说,涉及的页表不在不同的进程之间共享。 这意味着所有4个桌子级别。

当然,常见的(内核)部分总是存在于所有的地址空间中,所以实际上有一些共享,但是内存本身只能被内核访问。

除此之外的确,每个进程都有自己的页表,并且在其中任何一个地址都使用全部2 地址没有任何问题。 至少,CPU的部分没有特别的限制,尽管可以在操作系统的一部分。