29.4. 5 级分页

29.4.1. 概述

原始的 x86-64 受限于 4 级分页,虚拟地址空间为 256 TiB,物理地址空间为 64 TiB。我们已经触碰到了这个限制:一些供应商现在提供具有 64 TiB 内存的服务器。

为了克服这个限制,即将到来的硬件将引入对 5 级分页的支持。它是当前页表结构的直接扩展,增加了一层转换。

它将限制提升到 128 PiB 的虚拟地址空间和 4 PiB 的物理地址空间。这“应该足够任何人使用”©。

QEMU 2.9 及更高版本支持 5 级分页。

5 级分页的虚拟内存布局在 内存管理 中描述。

29.4.2. 启用 5 级分页

CONFIG_X86_5LEVEL=y 启用此功能。

配置了 CONFIG_X86_5LEVEL=y 的内核仍然能够在 4 级硬件上启动。在这种情况下,额外的页表级别 -- p4d -- 将在运行时被折叠。

29.4.3. 用户空间和大型虚拟地址空间

在 x86 上,5 级分页启用 56 位用户空间虚拟地址空间。并非所有用户空间都准备好处理宽地址。众所周知,至少某些 JIT 编译器在指针中使用高位来编码其信息。这与 5 级分页的有效指针冲突,并导致崩溃。

为了缓解这种情况,我们默认不会分配高于 47 位的虚拟地址空间。

但是,用户空间可以通过指定高于 47 位的提示地址(带有或不带有 MAP_FIXED)来请求从完整地址空间分配。

如果提示地址设置在 47 位以上,但未指定 MAP_FIXED,我们会尝试按指定地址查找未映射的区域。如果它已被占用,我们会在完整的地址空间中查找未映射的区域,而不是从 47 位窗口查找。

高提示地址只会影响正在进行的分配,而不会影响任何未来的 mmap()。

在较旧的内核上或在没有 5 级分页支持的机器上指定高提示地址是安全的。该提示将被忽略,内核将回退到从 47 位地址空间进行分配。

这种方法有助于轻松地使应用程序的内存分配器了解大型地址空间,而无需手动跟踪已分配的虚拟地址空间。

我们需要在此处处理的一个重要情况是与 MPX 的交互。MPX(没有 MAWA 扩展)无法处理高于 47 位的地址,因此我们需要确保在已经有高于边界的 VMA 时无法启用 MPX,并禁止在启用 MPX 后创建此类 VMA。