The following image shows how a 32-bit process virtual address space is divided:
But how a 64-bit process virtual address space is divided?
The following image shows how a 32-bit process virtual address space is divided:
But how a 64-bit process virtual address space is divided?
The 64-bit x86 virtual memory map splits the address space into two: the lower section (with the top bit set to 0) is user-space, the upper section (with the top bit set to 1) is kernel-space. (Note that x86-64 defines “canonical” “lower half” and “higher half” addresses, with a number of bits effectively limited to 48 or 57; see Wikipedia or the Intel SDM, volume 3 section 4.5, for details.)
The complete map is documented in detail in the kernel; currently it looks like
Start addr | Offset | End addr | Size | VM area description |
---|---|---|---|---|
0000_0000_0000_0000 |
0 | 0000_7fff_ffff_ffff |
128 TiB | user-space virtual memory |
0000_8000_0000_0000 |
+128 TiB | ffff_7fff_ffff_ffff |
~16M TiB | non-canonical |
ffff_8000_0000_0000 |
-128 TiB | ffff_ffff_ffff_ffff |
128 TiB | kernel-space virtual memory |
with 48-bit virtual addresses. The 57-bit variant has the same structure, with 64 PiB of usable address space on either side of a 16K PiB hole:
Start addr | Offset | End addr | Size | VM area description |
---|---|---|---|---|
0000_0000_0000_0000 |
0 | 00ff_ffff_ffff_ffff |
64 PiB | user-space virtual memory |
0100_0000_0000_0000 |
+64 PiB | feff_ffff_ffff_ffff |
~16K PiB | non-canonical |
ff00_0000_0000_0000 |
-64 PiB | ffff_ffff_ffff_ffff |
64 PiB | kernel-space virtual memory |
(Note that 16K PiB = 16M TiB = 264 bytes. The vast majority of the available address space is non-canonical.)
Both of these layouts provide access to the same physical address space, using 52 address lines (4 PiB). 4-level paging only provides access to a 256 TiB subset at any given time; 5-level paging provides access to the full physical address space. Current x86 CPUs can handle far less than this; as far as I’m aware, the most a single socket CPU can handle is 6TiB.
Unlike the 32-bit case, the “64-bit” memory map is a direct reflection of hardware constraints.
64-bit ARM has a similar address distinction in hardware: the top twelve or sixteen bits are 0 for user-space, 1 for kernel-space. Linux uses 39, 42 or 48 bits for virtual addresses, depending on the number of page table levels and the page size. With ARMv8.2-LVA, another four bits are added, resulting in 52-bit virtual addresses.
This is also documented in detail in the kernel.
CONFIG_VMSPLIT_
options; and since 2007 you can also select fractional splits like 5/16ths and 15/32ths. If you modify some#define
s you can even have arbitrary splits. Nowadays systems affected by Meltdown typically use 4/4 split, i.e. completely separate kernel and user address spaces – phuclv Sep 15 '21 at 11:20