DevConf.cz 2021 has ended
Back To Schedule
Friday, February 19 • 11:30am - 11:55am
Large Virtual Address support in ARM64 kernel

Sign up or log in to save this to your schedule, view media, leave feedback and see who's attending!

Feedback form is now closed.

With ARMv8.2 architecture extensions becoming available in new / upcoming ARM64 CPUs, two new hardware extensions, namely - LVA (Large Virtual Addressing)
and LPA (Large Physical Addressing) are also being supported in open-source software now.

Starting from Linux kernel version 5.4, the 52-bit (Large) Virtual Address (VA) and Physical Address (PA) support was introduced for the ARM64 kernel. Although the kernel documentation describes these features (see [1] for more details) and how they impact the new kernels running on older CPUs (which don't support 52-bit VA extension in hardware) and the newer CPUs (which support 52-bit VA extension in hardware), it is still at-times complex for a normal user to understand the same and understand how one can "opt-in" for receiving VAs from a 52-bit space.

In this talk, I explain how:
A. the kernel memory layout gets "flipped" for ARM64 after the support for these features were added,
B. user-space applications, especially the ones which provide debugging support (e.g. kexec-tools, makedumpfile and crash-utility) get impacted because of the same, and
C. how user-space applications can "opt-in" to receiving VAs from a 52-bit space by specifying an mmap hint parameter that is larger than 48-bit.
ARMv8.2 architecture extensions - LVA and LPA:

* ARMv8.2 architecture provides two important extensions - Large Virtual Addressing (LVA) and Large Physical Addressing (LPA).
* ARMv8.2-LVA supports a larger VA space for each translation table base register of up to 52 bits when using the 64KB translation granule.
* ARMv8.2-LPA:
- Allows a larger intermediate physical address (IPA) and PA space of up to 52 bits when using the 64KB translation granule.
- Allows a level 1 block size where the block covers a 4TB address range for the 64KB translation granule if the implementation support 52 bits of PA.

52-bit VA support in the kernel:
Since the newer kernels with the LVA support should run well on older CPUs (which don't support LVA extension in hardware) and the newer CPUs (which support LVA extension in hardware), the design approach chosen is to have a single binary which supports 52-bit (which must also be able to fall back to 48-bit at early boot time if the hardware feature is not present).

This design approach requires the kernel to support the following variables for supporting the new virtual address space:
VA_BITSconstantthe *maximum* VA space size
vabits_actualvariablethe *actual* VA space size

So, while VA_BITS denotes the maximum VA space size, the actual VA space supported (depending on the switch made at boot-time) is indicated by vabits_actual.

Flipping the kernel memory layout:
The design approach of keeping a single kernel binary necessitates the kernel .text to be in the higher addresses such that they are invariant to 48/52-bit VAs.

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.

Impact on user-space applications which are used to debug kernel:
A number of user-space applications are used to debug running / live kernels or to analyze the vmcore dump obtained from a crashing system - to determine
the root-cause of the kernel crash, for example: kexec-tools, makedumpfile and crash-utility.

When these are used to debug the ARM64 kernel, we see an impact on these as well because of the ARM64 kernel memory map getting "flipped". These applications also need to perform a translation table walk for determining a physical address corresponding to a virtual address (pretty much similar to how it is done in the kernel).
Accordingly, user-space applications need to be modified as they are broken upstream after the "flip" was introduced in the kernel memory map.

I have proposed fixes in the three affected user-space applications accordingly and while some of these have been accepted upstream, others are still pending (see [2], [3]).

52-bit userspace VAs:
To maintain compatibility with user-space applications 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. User-space applications can "opt-in" to receiving VAs from a 52-bit space by specifying an mmap hint parameter that is larger than 48-bit:
maybe_high_address = mmap(~0UL, size, prot, flags,...);

[1]. https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/arm64/memory.rst [Kernel documentation describing the memory map]
[2]. http://lists.infradead.org/pipermail/kexec/2020-September/021372.html [Proposed Makedumpfile upstream fix]
[3]. http://lists.infradead.org/pipermail/kexec/2020-September/021333.html [kexec fix]

avatar for Bhupesh Sharma

Bhupesh Sharma

I work with Linaro as a part of the Landing team. I have been hacking on bootloaders and kernel used on arm architecture since past 14 years. I contribute to Linux, EFI/u-boot bootloader code base and also to user-space utilities like kexec-tools and crash-utility. Bringing up a Silicon... Read More →

Friday February 19, 2021 11:30am - 11:55am CET
Session Room 2