<!DOCTYPE html>
<html lang="en" data-content_root="../../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Memory Layout on AArch64 Linux — The Linux Kernel documentation</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css?v=fa44fd50" />
<link rel="stylesheet" type="text/css" href="../../_static/alabaster.css?v=3918102e" />
<script src="../../_static/documentation_options.js?v=5929fcd5"></script>
<script src="../../_static/doctools.js?v=9bcbadda"></script>
<script src="../../_static/sphinx_highlight.js?v=dc90522c"></script>
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
<link rel="next" title="Memory Tagging Extension (MTE) in AArch64 Linux" href="memory-tagging-extension.html" />
<link rel="prev" title="Legacy instructions" href="legacy_instructions.html" />
<link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../../index.html">
<img class="logo" src="../../_static/logo.svg" alt="Logo of The Linux Kernel"/>
</a></p>
<h1 class="logo"><a href="../../index.html">The Linux Kernel</a></h1>
<p class="blurb">6.18.50</p>
<search id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script>
<p>
<h3 class="kernel-toc-contents">Contents</h3>
<input type="checkbox" class="kernel-toc-toggle" id = "kernel-toc-toggle" checked>
<label class="kernel-toc-title" for="kernel-toc-toggle"></label>
<div class="kerneltoc" id="kerneltoc">
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../process/development-process.html">Development process</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../process/submitting-patches.html">Submitting patches</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../process/code-of-conduct.html">Code of conduct</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../maintainer/index.html">Maintainer handbook</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../process/index.html">All development-process docs</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../core-api/index.html">Core API</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../driver-api/index.html">Driver APIs</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../subsystem-apis.html">Subsystems</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../locking/index.html">Locking</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../process/license-rules.html">Licensing rules</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../doc-guide/index.html">Writing documentation</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../dev-tools/index.html">Development tools</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../dev-tools/testing-overview.html">Testing guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../kernel-hacking/index.html">Hacking guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../trace/index.html">Tracing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../fault-injection/index.html">Fault injection</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../livepatch/index.html">Livepatching</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../rust/index.html">Rust</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../admin-guide/index.html">Administration</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../kbuild/index.html">Build system</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../admin-guide/reporting-issues.html">Reporting issues</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../tools/index.html">Userspace tools</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../userspace-api/index.html">Userspace API</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../firmware-guide/index.html">Firmware</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../devicetree/index.html">Firmware and Devicetree</a></li>
</ul>
<ul class="current">
<li class="toctree-l1 current"><a class="reference internal" href="../index.html">CPU architectures</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../arc/index.html">ARC architecture</a></li>
<li class="toctree-l2"><a class="reference internal" href="../arm/index.html">ARM Architecture</a></li>
<li class="toctree-l2 current"><a class="reference internal" href="index.html">ARM64 Architecture</a><ul class="current">
<li class="toctree-l3"><a class="reference internal" href="acpi_object_usage.html">ACPI Tables</a></li>
<li class="toctree-l3"><a class="reference internal" href="amu.html">Activity Monitors Unit (AMU) extension in AArch64 Linux</a></li>
<li class="toctree-l3"><a class="reference internal" href="arm-acpi.html">ACPI on Arm systems</a></li>
<li class="toctree-l3"><a class="reference internal" href="arm-cca.html">Arm Confidential Compute Architecture</a></li>
<li class="toctree-l3"><a class="reference internal" href="asymmetric-32bit.html">Asymmetric 32-bit SoCs</a></li>
<li class="toctree-l3"><a class="reference internal" href="booting.html">Booting AArch64 Linux</a></li>
<li class="toctree-l3"><a class="reference internal" href="cpu-feature-registers.html">ARM64 CPU Feature Registers</a></li>
<li class="toctree-l3"><a class="reference internal" href="cpu-hotplug.html">CPU Hotplug and ACPI</a></li>
<li class="toctree-l3"><a class="reference internal" href="elf_hwcaps.html">ARM64 ELF hwcaps</a></li>
<li class="toctree-l3"><a class="reference internal" href="gcs.html">Guarded Control Stack support for AArch64 Linux</a></li>
<li class="toctree-l3"><a class="reference internal" href="hugetlbpage.html">HugeTLBpage on ARM64</a></li>
<li class="toctree-l3"><a class="reference internal" href="kdump.html">crashkernel memory reservation on arm64</a></li>
<li class="toctree-l3"><a class="reference internal" href="legacy_instructions.html">Legacy instructions</a></li>
<li class="toctree-l3 current"><a class="current reference internal" href="#">Memory Layout on AArch64 Linux</a></li>
<li class="toctree-l3"><a class="reference internal" href="memory-tagging-extension.html">Memory Tagging Extension (MTE) in AArch64 Linux</a></li>
<li class="toctree-l3"><a class="reference internal" href="mops.html">Memory copy/set instructions (MOPS)</a></li>
<li class="toctree-l3"><a class="reference internal" href="perf.html">Perf</a></li>
<li class="toctree-l3"><a class="reference internal" href="pointer-authentication.html">Pointer authentication in AArch64 Linux</a></li>
<li class="toctree-l3"><a class="reference internal" href="ptdump.html">Kernel page table dump</a></li>
<li class="toctree-l3"><a class="reference internal" href="silicon-errata.html">Silicon Errata and Software Workarounds</a></li>
<li class="toctree-l3"><a class="reference internal" href="sme.html">Scalable Matrix Extension support for AArch64 Linux</a></li>
<li class="toctree-l3"><a class="reference internal" href="sve.html">Scalable Vector Extension support for AArch64 Linux</a></li>
<li class="toctree-l3"><a class="reference internal" href="tagged-address-abi.html">AArch64 TAGGED ADDRESS ABI</a></li>
<li class="toctree-l3"><a class="reference internal" href="tagged-pointers.html">Tagged virtual addresses in AArch64 Linux</a></li>
<li class="toctree-l3"><a class="reference internal" href="features.html">Feature status on arm64 architecture</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../loongarch/index.html">LoongArch Architecture</a></li>
<li class="toctree-l2"><a class="reference internal" href="../m68k/index.html">m68k Architecture</a></li>
<li class="toctree-l2"><a class="reference internal" href="../mips/index.html">MIPS-specific Documentation</a></li>
<li class="toctree-l2"><a class="reference internal" href="../nios2/index.html">Nios II Specific Documentation</a></li>
<li class="toctree-l2"><a class="reference internal" href="../openrisc/index.html">OpenRISC Architecture</a></li>
<li class="toctree-l2"><a class="reference internal" href="../parisc/index.html">PA-RISC Architecture</a></li>
<li class="toctree-l2"><a class="reference internal" href="../powerpc/index.html">powerpc</a></li>
<li class="toctree-l2"><a class="reference internal" href="../riscv/index.html">RISC-V architecture</a></li>
<li class="toctree-l2"><a class="reference internal" href="../s390/index.html">s390 Architecture</a></li>
<li class="toctree-l2"><a class="reference internal" href="../sh/index.html">SuperH Interfaces Guide</a></li>
<li class="toctree-l2"><a class="reference internal" href="../sparc/index.html">Sparc Architecture</a></li>
<li class="toctree-l2"><a class="reference internal" href="../x86/index.html">x86-specific Documentation</a></li>
<li class="toctree-l2"><a class="reference internal" href="../xtensa/index.html">Xtensa Architecture</a></li>
</ul>
</li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../staging/index.html">Unsorted documentation</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../translations/index.html">Translations</a></li>
</ul>
</div>
<script type="text/javascript"> <!--
var sbar = document.getElementsByClassName("sphinxsidebar")[0];
let currents = document.getElementsByClassName("current")
if (currents.length) {
sbar.scrollTop = currents[currents.length - 1].offsetTop;
}
--> </script>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../../_sources/arch/arm64/memory.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
</div>
</div>
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="memory-layout-on-aarch64-linux">
<h1>Memory Layout on AArch64 Linux<a class="headerlink" href="#memory-layout-on-aarch64-linux" title="Link to this heading">¶</a></h1>
<p>Author: Catalin Marinas <<a class="reference external" href="mailto:catalin.marinas%40arm.com">catalin<span>.</span>marinas<span>@</span>arm<span>.</span>com</a>></p>
<p>This document describes the virtual memory layout used by the AArch64
Linux kernel. The architecture allows up to 4 levels of translation
tables with a 4KB page size and up to 3 levels with a 64KB page size.</p>
<p>AArch64 Linux uses either 3 levels or 4 levels of translation tables
with the 4KB page configuration, allowing 39-bit (512GB) or 48-bit
(256TB) virtual addresses, respectively, for both user and kernel. With
64KB pages, only 2 levels of translation tables, allowing 42-bit (4TB)
virtual address, are used but the memory layout is the same.</p>
<p>ARMv8.2 adds optional support for Large Virtual Address space. This is
only available when running with a 64KB page size and expands the
number of descriptors in the first level of translation.</p>
<p>TTBRx selection is given by bit 55 of the virtual address. The
swapper_pg_dir contains only kernel (global) mappings while the user pgd
contains only user (non-global) mappings. The swapper_pg_dir address is
written to TTBR1 and never written to TTBR0.</p>
<p>When using KVM without the Virtualization Host Extensions, the
hypervisor maps kernel pages in EL2 at a fixed (and potentially
random) offset from the linear mapping. See the kern_hyp_va macro and
kvm_update_va_mask function for more details. MMIO devices such as
GICv2 gets mapped next to the HYP idmap page, as do vectors when
ARM64_SPECTRE_V3A is enabled for particular CPUs.</p>
<p>When using KVM with the Virtualization Host Extensions, no additional
mappings are created, since the host kernel runs directly in EL2.</p>
<section id="bit-va-support-in-the-kernel">
<h2>52-bit VA support in the kernel<a class="headerlink" href="#bit-va-support-in-the-kernel" title="Link to this heading">¶</a></h2>
<p>If the ARMv8.2-LVA optional feature is present, and we are running
with a 64KB page size; then it is possible to use 52-bits of address
space for both userspace and kernel addresses. However, any kernel
binary that supports 52-bit must also be able to fall back to 48-bit
at early boot time if the hardware feature is not present.</p>
<p>This fallback mechanism necessitates the kernel .text to be in the
higher addresses such that they are invariant to 48/52-bit VAs. Due
to the kasan shadow being a fraction of the entire kernel VA space,
the end of the kasan shadow must also be in the higher half of the
kernel VA space for both 48/52-bit. (Switching from 48-bit to 52-bit,
the end of the kasan shadow is invariant and dependent on ~0UL,
whilst the start address will “grow” towards the lower addresses).</p>
<p>In order to optimise phys_to_virt and virt_to_phys, the PAGE_OFFSET
is kept constant at 0xFFF0000000000000 (corresponding to 52-bit),
this obviates the need for an extra variable read. The physvirt
offset and vmemmap offsets are computed at early boot to enable
this logic.</p>
<p>As a single binary will need to support both 48-bit and 52-bit VA
spaces, the VMEMMAP must be sized large enough for 52-bit VAs and
also must be sized large enough to accommodate a fixed PAGE_OFFSET.</p>
<p>Most code in the kernel should not need to consider the VA_BITS, for
code that does need to know the VA size the variables are
defined as follows:</p>
<p>VA_BITS constant the <em>maximum</em> VA space size</p>
<p>VA_BITS_MIN constant the <em>minimum</em> VA space size</p>
<p>vabits_actual variable the <em>actual</em> VA space size</p>
<p>Maximum and minimum sizes can be useful to ensure that buffers are
sized large enough or that addresses are positioned close enough for
the “worst” case.</p>
</section>
<section id="bit-userspace-vas">
<h2>52-bit userspace VAs<a class="headerlink" href="#bit-userspace-vas" title="Link to this heading">¶</a></h2>
<p>To maintain compatibility with software that relies on the ARMv8.0
VA space maximum size of 48-bits, the kernel will, by default,
return virtual addresses to userspace from a 48-bit range.</p>
<p>Software can “opt-in” to receiving VAs from a 52-bit space by
specifying an mmap hint parameter that is larger than 48-bit.</p>
<p>For example:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">maybe_high_address</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">mmap</span><span class="p">(</span><span class="o">~</span><span class="mi">0UL</span><span class="p">,</span><span class="w"> </span><span class="n">size</span><span class="p">,</span><span class="w"> </span><span class="n">prot</span><span class="p">,</span><span class="w"> </span><span class="n">flags</span><span class="p">,...);</span>
</pre></div>
</div>
<p>It is also possible to build a debug kernel that returns addresses
from a 52-bit space by enabling the following kernel config options:</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre><span></span><span class="nv">CONFIG_EXPERT</span><span class="o">=</span>y<span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="nv">CONFIG_ARM64_FORCE_52BIT</span><span class="o">=</span>y
</pre></div>
</div>
<p>Note that this option is only intended for debugging applications
and should not be used in production.</p>
</section>
</section>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
©The kernel development community.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 8.1.3</a>
& <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a>
|
<a href="../../_sources/arch/arm64/memory.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>