1 .. SPDX-License-Identifier: GPL-2.0
3 =====================================
4 Virtual Memory Layout on RISC-V Linux
5 =====================================
7 :Author: Alexandre Ghiti <alex@ghiti.fr>
8 :Date: 12 February 2021
10 This document describes the virtual memory layout used by the RISC-V Linux
13 RISC-V Linux Kernel 32bit
14 =========================
16 RISC-V Linux Kernel SV32
17 ------------------------
21 RISC-V Linux Kernel 64bit
22 =========================
24 The RISC-V privileged architecture document states that the 64bit addresses
25 "must have bits 63–48 all equal to bit 47, or else a page-fault exception will
26 occur.": that splits the virtual address space into 2 halves separated by a very
27 big hole, the lower half is where the userspace resides, the upper half is where
28 the RISC-V Linux Kernel resides.
30 RISC-V Linux Kernel SV39
31 ------------------------
35 ========================================================================================================================
36 Start addr | Offset | End addr | Size | VM area description
37 ========================================================================================================================
39 0000000000000000 | 0 | 0000003fffffffff | 256 GB | user-space virtual memory, different per mm
40 __________________|____________|__________________|_________|___________________________________________________________
42 0000004000000000 | +256 GB | ffffffbfffffffff | ~16M TB | ... huge, almost 64 bits wide hole of non-canonical
43 | | | | virtual memory addresses up to the -256 GB
44 | | | | starting offset of kernel mappings.
45 __________________|____________|__________________|_________|___________________________________________________________
47 | Kernel-space virtual memory, shared between all processes:
48 ____________________________________________________________|___________________________________________________________
50 ffffffc6fea00000 | -228 GB | ffffffc6feffffff | 6 MB | fixmap
51 ffffffc6ff000000 | -228 GB | ffffffc6ffffffff | 16 MB | PCI io
52 ffffffc700000000 | -228 GB | ffffffc7ffffffff | 4 GB | vmemmap
53 ffffffc800000000 | -224 GB | ffffffd7ffffffff | 64 GB | vmalloc/ioremap space
54 ffffffd800000000 | -160 GB | fffffff6ffffffff | 124 GB | direct mapping of all physical memory
55 fffffff700000000 | -36 GB | fffffffeffffffff | 32 GB | kasan
56 __________________|____________|__________________|_________|____________________________________________________________
59 ____________________________________________________________|____________________________________________________________
61 ffffffff00000000 | -4 GB | ffffffff7fffffff | 2 GB | modules, BPF
62 ffffffff80000000 | -2 GB | ffffffffffffffff | 2 GB | kernel
63 __________________|____________|__________________|_________|____________________________________________________________
66 RISC-V Linux Kernel SV48
67 ------------------------
71 ========================================================================================================================
72 Start addr | Offset | End addr | Size | VM area description
73 ========================================================================================================================
75 0000000000000000 | 0 | 00007fffffffffff | 128 TB | user-space virtual memory, different per mm
76 __________________|____________|__________________|_________|___________________________________________________________
78 0000800000000000 | +128 TB | ffff7fffffffffff | ~16M TB | ... huge, almost 64 bits wide hole of non-canonical
79 | | | | virtual memory addresses up to the -128 TB
80 | | | | starting offset of kernel mappings.
81 __________________|____________|__________________|_________|___________________________________________________________
83 | Kernel-space virtual memory, shared between all processes:
84 ____________________________________________________________|___________________________________________________________
86 ffff8d7ffea00000 | -114.5 TB | ffff8d7ffeffffff | 6 MB | fixmap
87 ffff8d7fff000000 | -114.5 TB | ffff8d7fffffffff | 16 MB | PCI io
88 ffff8d8000000000 | -114.5 TB | ffff8f7fffffffff | 2 TB | vmemmap
89 ffff8f8000000000 | -112.5 TB | ffffaf7fffffffff | 32 TB | vmalloc/ioremap space
90 ffffaf8000000000 | -80.5 TB | ffffef7fffffffff | 64 TB | direct mapping of all physical memory
91 ffffef8000000000 | -16.5 TB | fffffffeffffffff | 16.5 TB | kasan
92 __________________|____________|__________________|_________|____________________________________________________________
94 | Identical layout to the 39-bit one from here on:
95 ____________________________________________________________|____________________________________________________________
97 ffffffff00000000 | -4 GB | ffffffff7fffffff | 2 GB | modules, BPF
98 ffffffff80000000 | -2 GB | ffffffffffffffff | 2 GB | kernel
99 __________________|____________|__________________|_________|____________________________________________________________
102 RISC-V Linux Kernel SV57
103 ------------------------
107 ========================================================================================================================
108 Start addr | Offset | End addr | Size | VM area description
109 ========================================================================================================================
111 0000000000000000 | 0 | 00ffffffffffffff | 64 PB | user-space virtual memory, different per mm
112 __________________|____________|__________________|_________|___________________________________________________________
114 0100000000000000 | +64 PB | feffffffffffffff | ~16K PB | ... huge, almost 64 bits wide hole of non-canonical
115 | | | | virtual memory addresses up to the -64 PB
116 | | | | starting offset of kernel mappings.
117 __________________|____________|__________________|_________|___________________________________________________________
119 | Kernel-space virtual memory, shared between all processes:
120 ____________________________________________________________|___________________________________________________________
122 ff1bfffffea00000 | -57 PB | ff1bfffffeffffff | 6 MB | fixmap
123 ff1bffffff000000 | -57 PB | ff1bffffffffffff | 16 MB | PCI io
124 ff1c000000000000 | -57 PB | ff1fffffffffffff | 1 PB | vmemmap
125 ff20000000000000 | -56 PB | ff5fffffffffffff | 16 PB | vmalloc/ioremap space
126 ff60000000000000 | -40 PB | ffdeffffffffffff | 32 PB | direct mapping of all physical memory
127 ffdf000000000000 | -8 PB | fffffffeffffffff | 8 PB | kasan
128 __________________|____________|__________________|_________|____________________________________________________________
130 | Identical layout to the 39-bit one from here on:
131 ____________________________________________________________|____________________________________________________________
133 ffffffff00000000 | -4 GB | ffffffff7fffffff | 2 GB | modules, BPF
134 ffffffff80000000 | -2 GB | ffffffffffffffff | 2 GB | kernel
135 __________________|____________|__________________|_________|____________________________________________________________
140 To maintain compatibility with software that relies on the VA space with a
141 maximum of 48 bits the kernel will, by default, return virtual addresses to
142 userspace from a 48-bit range (sv48). This default behavior is achieved by
143 passing 0 into the hint address parameter of mmap. On CPUs with an address space
144 smaller than sv48, the CPU maximum supported address space will be the default.
146 Software can "opt-in" to receiving VAs from another VA space by providing
147 a hint address to mmap. A hint address passed to mmap will cause the largest
148 address space that fits entirely into the hint to be used, unless there is no
149 space left in the address space. If there is no space available in the requested
150 address space, an address in the next smallest available address space will be
153 For example, in order to obtain 48-bit VA space, a hint address greater than
154 :code:`1 << 47` must be provided. Note that this is 47 due to sv48 userspace
155 ending at :code:`1 << 47` and the addresses beyond this are reserved for the
156 kernel. Similarly, to obtain 57-bit VA space addresses, a hint address greater
157 than or equal to :code:`1 << 56` must be provided.