arm64: Determine the vmalloc/vmemmap space at build time based on VA_BITS

Rather than guessing what the maximum vmmemap space should be, this
patch allows the calculation based on the VA_BITS and sizeof(struct
page). The vmalloc space extends to the beginning of the vmemmap space.

Since the virtual kernel memory layout now depends on the build
configuration, this patch removes the detailed description in
Documentation/arm64/memory.txt in favour of information printed during
kernel booting.

Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Tested-by: Jungseok Lee <jungseoklee85@gmail.com>
This commit is contained in:
Catalin Marinas 2014-07-16 17:42:43 +01:00
parent b4a0d8b377
commit 08375198b0
3 changed files with 38 additions and 95 deletions

View File

@ -2,19 +2,18 @@
============================== ==============================
Author: Catalin Marinas <catalin.marinas@arm.com> Author: Catalin Marinas <catalin.marinas@arm.com>
Date : 20 February 2012
This document describes the virtual memory layout used by the AArch64 This document describes the virtual memory layout used by the AArch64
Linux kernel. The architecture allows up to 4 levels of translation 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. tables with a 4KB page size and up to 3 levels with a 64KB page size.
AArch64 Linux uses either 3 levels or 4 levels of translation tables with AArch64 Linux uses either 3 levels or 4 levels of translation tables
the 4KB page configuration, allowing 39-bit (512GB) or 48-bit (256TB) with the 4KB page configuration, allowing 39-bit (512GB) or 48-bit
virtual addresses, respectively, for both user and kernel. With 64KB (256TB) virtual addresses, respectively, for both user and kernel. With
pages, only 2 levels of translation tables, allowing 42-bit (4TB) 64KB pages, only 2 levels of translation tables, allowing 42-bit (4TB)
virtual address, are used but the memory layout is the same. virtual address, are used but the memory layout is the same.
User addresses have bits 63:39 set to 0 while the kernel addresses have User addresses have bits 63:48 set to 0 while the kernel addresses have
the same bits set to 1. TTBRx selection is given by bit 63 of the the same bits set to 1. TTBRx selection is given by bit 63 of the
virtual address. The swapper_pg_dir contains only kernel (global) virtual address. The swapper_pg_dir contains only kernel (global)
mappings while the user pgd contains only user (non-global) mappings. mappings while the user pgd contains only user (non-global) mappings.
@ -27,26 +26,7 @@ AArch64 Linux memory layout with 4KB pages + 3 levels:
Start End Size Use Start End Size Use
----------------------------------------------------------------------- -----------------------------------------------------------------------
0000000000000000 0000007fffffffff 512GB user 0000000000000000 0000007fffffffff 512GB user
ffffff8000000000 ffffffffffffffff 512GB kernel
ffffff8000000000 ffffffbbfffeffff ~240GB vmalloc
ffffffbbffff0000 ffffffbbffffffff 64KB [guard page]
ffffffbc00000000 ffffffbdffffffff 8GB vmemmap
ffffffbe00000000 ffffffbffbbfffff ~8GB [guard, future vmmemap]
ffffffbffa000000 ffffffbffaffffff 16MB PCI I/O space
ffffffbffb000000 ffffffbffbbfffff 12MB [guard]
ffffffbffbc00000 ffffffbffbdfffff 2MB fixed mappings
ffffffbffbe00000 ffffffbffbffffff 2MB [guard]
ffffffbffc000000 ffffffbfffffffff 64MB modules
ffffffc000000000 ffffffffffffffff 256GB kernel logical memory map
AArch64 Linux memory layout with 4KB pages + 4 levels: AArch64 Linux memory layout with 4KB pages + 4 levels:
@ -54,26 +34,7 @@ AArch64 Linux memory layout with 4KB pages + 4 levels:
Start End Size Use Start End Size Use
----------------------------------------------------------------------- -----------------------------------------------------------------------
0000000000000000 0000ffffffffffff 256TB user 0000000000000000 0000ffffffffffff 256TB user
ffff000000000000 ffffffffffffffff 256TB kernel
ffff000000000000 ffff7bfffffeffff ~124TB vmalloc
ffff7bffffff0000 ffff7bffffffffff 64KB [guard page]
ffff7c0000000000 ffff7dffffffffff 2TB vmemmap
ffff7e0000000000 ffff7ffffbbfffff ~2TB [guard, future vmmemap]
ffff7ffffa000000 ffff7ffffaffffff 16MB PCI I/O space
ffff7ffffb000000 ffff7ffffbbfffff 12MB [guard]
ffff7ffffbc00000 ffff7ffffbdfffff 2MB fixed mappings
ffff7ffffbe00000 ffff7ffffbffffff 2MB [guard]
ffff7ffffc000000 ffff7fffffffffff 64MB modules
ffff800000000000 ffffffffffffffff 128TB kernel logical memory map
AArch64 Linux memory layout with 64KB pages + 2 levels: AArch64 Linux memory layout with 64KB pages + 2 levels:
@ -81,44 +42,14 @@ AArch64 Linux memory layout with 64KB pages + 2 levels:
Start End Size Use Start End Size Use
----------------------------------------------------------------------- -----------------------------------------------------------------------
0000000000000000 000003ffffffffff 4TB user 0000000000000000 000003ffffffffff 4TB user
fffffc0000000000 ffffffffffffffff 4TB kernel
fffffc0000000000 fffffdfbfffeffff ~2TB vmalloc
fffffdfbffff0000 fffffdfbffffffff 64KB [guard page]
fffffdfc00000000 fffffdfdffffffff 8GB vmemmap
fffffdfe00000000 fffffdfffbbfffff ~8GB [guard, future vmmemap]
fffffdfffa000000 fffffdfffaffffff 16MB PCI I/O space
fffffdfffb000000 fffffdfffbbfffff 12MB [guard]
fffffdfffbc00000 fffffdfffbdfffff 2MB fixed mappings
fffffdfffbe00000 fffffdfffbffffff 2MB [guard]
fffffdfffc000000 fffffdffffffffff 64MB modules
fffffe0000000000 ffffffffffffffff 2TB kernel logical memory map
Translation table lookup with 4KB pages + 3 levels: For details of the virtual kernel memory layout please see the kernel
booting log.
+--------+--------+--------+--------+--------+--------+--------+--------+
|63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0|
+--------+--------+--------+--------+--------+--------+--------+--------+
| | | | | |
| | | | | v
| | | | | [11:0] in-page offset
| | | | +-> [20:12] L3 index
| | | +-----------> [29:21] L2 index
| | +---------------------> [38:30] L1 index
| +-------------------------------> [47:39] L0 index (not used)
+-------------------------------------------------> [63] TTBR0/1
Translation table lookup with 4KB pages + 4 levels: Translation table lookup with 4KB pages:
+--------+--------+--------+--------+--------+--------+--------+--------+ +--------+--------+--------+--------+--------+--------+--------+--------+
|63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0| |63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0|
@ -133,7 +64,7 @@ Translation table lookup with 4KB pages + 4 levels:
+-------------------------------------------------> [63] TTBR0/1 +-------------------------------------------------> [63] TTBR0/1
Translation table lookup with 64KB pages + 2 levels: Translation table lookup with 64KB pages:
+--------+--------+--------+--------+--------+--------+--------+--------+ +--------+--------+--------+--------+--------+--------+--------+--------+
|63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0| |63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0|
@ -142,10 +73,11 @@ Translation table lookup with 64KB pages + 2 levels:
| | | | v | | | | v
| | | | [15:0] in-page offset | | | | [15:0] in-page offset
| | | +----------> [28:16] L3 index | | | +----------> [28:16] L3 index
| | +--------------------------> [41:29] L2 index (only 38:29 used) | | +--------------------------> [41:29] L2 index
| +-------------------------------> [47:42] L1 index (not used) | +-------------------------------> [47:42] L1 index
+-------------------------------------------------> [63] TTBR0/1 +-------------------------------------------------> [63] TTBR0/1
When using KVM, the hypervisor maps kernel pages in EL2, at a fixed When using KVM, the hypervisor maps kernel pages in EL2, at a fixed
offset from the kernel VA (top 24bits of the kernel VA set to zero): offset from the kernel VA (top 24bits of the kernel VA set to zero):

View File

@ -33,13 +33,16 @@
/* /*
* VMALLOC and SPARSEMEM_VMEMMAP ranges. * VMALLOC and SPARSEMEM_VMEMMAP ranges.
*
* VMEMAP_SIZE: allows the whole VA space to be covered by a struct page array
* (rounded up to PUD_SIZE).
* VMALLOC_START: beginning of the kernel VA space
* VMALLOC_END: extends to the available space below vmmemmap, PCI I/O space,
* fixed mappings and modules
*/ */
#define VMEMMAP_SIZE ALIGN((1UL << (VA_BITS - PAGE_SHIFT)) * sizeof(struct page), PUD_SIZE)
#define VMALLOC_START (UL(0xffffffffffffffff) << VA_BITS) #define VMALLOC_START (UL(0xffffffffffffffff) << VA_BITS)
#if CONFIG_ARM64_PGTABLE_LEVELS != 4 #define VMALLOC_END (PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K)
#define VMALLOC_END (PAGE_OFFSET - UL(0x400000000) - SZ_64K)
#else
#define VMALLOC_END (PAGE_OFFSET - UL(0x40000000000) - SZ_64K)
#endif
#define vmemmap ((struct page *)(VMALLOC_END + SZ_64K)) #define vmemmap ((struct page *)(VMALLOC_END + SZ_64K))

View File

@ -33,6 +33,7 @@
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/dma-contiguous.h> #include <linux/dma-contiguous.h>
#include <asm/fixmap.h>
#include <asm/sections.h> #include <asm/sections.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/sizes.h> #include <asm/sizes.h>
@ -256,26 +257,33 @@ void __init mem_init(void)
#define MLK(b, t) b, t, ((t) - (b)) >> 10 #define MLK(b, t) b, t, ((t) - (b)) >> 10
#define MLM(b, t) b, t, ((t) - (b)) >> 20 #define MLM(b, t) b, t, ((t) - (b)) >> 20
#define MLG(b, t) b, t, ((t) - (b)) >> 30
#define MLK_ROUNDUP(b, t) b, t, DIV_ROUND_UP(((t) - (b)), SZ_1K) #define MLK_ROUNDUP(b, t) b, t, DIV_ROUND_UP(((t) - (b)), SZ_1K)
pr_notice("Virtual kernel memory layout:\n" pr_notice("Virtual kernel memory layout:\n"
" vmalloc : 0x%16lx - 0x%16lx (%6ld MB)\n" " vmalloc : 0x%16lx - 0x%16lx (%6ld GB)\n"
#ifdef CONFIG_SPARSEMEM_VMEMMAP #ifdef CONFIG_SPARSEMEM_VMEMMAP
" vmemmap : 0x%16lx - 0x%16lx (%6ld MB)\n" " vmemmap : 0x%16lx - 0x%16lx (%6ld GB maximum)\n"
" 0x%16lx - 0x%16lx (%6ld MB actual)\n"
#endif #endif
" PCI I/O : 0x%16lx - 0x%16lx (%6ld MB)\n"
" fixed : 0x%16lx - 0x%16lx (%6ld KB)\n"
" modules : 0x%16lx - 0x%16lx (%6ld MB)\n" " modules : 0x%16lx - 0x%16lx (%6ld MB)\n"
" memory : 0x%16lx - 0x%16lx (%6ld MB)\n" " memory : 0x%16lx - 0x%16lx (%6ld MB)\n"
" .init : 0x%p" " - 0x%p" " (%6ld kB)\n" " .init : 0x%p" " - 0x%p" " (%6ld KB)\n"
" .text : 0x%p" " - 0x%p" " (%6ld kB)\n" " .text : 0x%p" " - 0x%p" " (%6ld KB)\n"
" .data : 0x%p" " - 0x%p" " (%6ld kB)\n", " .data : 0x%p" " - 0x%p" " (%6ld KB)\n",
MLM(VMALLOC_START, VMALLOC_END), MLG(VMALLOC_START, VMALLOC_END),
#ifdef CONFIG_SPARSEMEM_VMEMMAP #ifdef CONFIG_SPARSEMEM_VMEMMAP
MLG((unsigned long)vmemmap,
(unsigned long)vmemmap + VMEMMAP_SIZE),
MLM((unsigned long)virt_to_page(PAGE_OFFSET), MLM((unsigned long)virt_to_page(PAGE_OFFSET),
(unsigned long)virt_to_page(high_memory)), (unsigned long)virt_to_page(high_memory)),
#endif #endif
MLM((unsigned long)PCI_IOBASE, (unsigned long)PCI_IOBASE + SZ_16M),
MLK(FIXADDR_START, FIXADDR_TOP),
MLM(MODULES_VADDR, MODULES_END), MLM(MODULES_VADDR, MODULES_END),
MLM(PAGE_OFFSET, (unsigned long)high_memory), MLM(PAGE_OFFSET, (unsigned long)high_memory),
MLK_ROUNDUP(__init_begin, __init_end), MLK_ROUNDUP(__init_begin, __init_end),
MLK_ROUNDUP(_text, _etext), MLK_ROUNDUP(_text, _etext),
MLK_ROUNDUP(_sdata, _edata)); MLK_ROUNDUP(_sdata, _edata));