]>
Commit | Line | Data |
---|---|---|
caab277b | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
87d1587b SP |
2 | /* |
3 | * Kernel page table mapping | |
4 | * | |
5 | * Copyright (C) 2015 ARM Ltd. | |
87d1587b SP |
6 | */ |
7 | ||
8 | #ifndef __ASM_KERNEL_PGTABLE_H | |
9 | #define __ASM_KERNEL_PGTABLE_H | |
10 | ||
5f1f7f6c | 11 | #include <asm/pgtable-hwdef.h> |
06e9bf2f | 12 | #include <asm/sparsemem.h> |
b433dce0 SP |
13 | |
14 | /* | |
15 | * The linear mapping and the start of memory are both 2M aligned (per | |
16 | * the arm64 booting.txt requirements). Hence we can use section mapping | |
17 | * with 4K (section size = 2M) but not with 16K (section size = 32M) or | |
18 | * 64K (section size = 512M). | |
19 | */ | |
20 | #ifdef CONFIG_ARM64_4K_PAGES | |
2062d44d | 21 | #define ARM64_KERNEL_USES_PMD_MAPS 1 |
b433dce0 | 22 | #else |
2062d44d | 23 | #define ARM64_KERNEL_USES_PMD_MAPS 0 |
b433dce0 SP |
24 | #endif |
25 | ||
87d1587b SP |
26 | /* |
27 | * The idmap and swapper page tables need some space reserved in the kernel | |
28 | * image. Both require pgd, pud (4 levels only) and pmd tables to (section) | |
29 | * map the kernel. With the 64K page configuration, swapper and idmap need to | |
30 | * map to pte level. The swapper also maps the FDT (see __create_page_tables | |
31 | * for more information). Note that the number of ID map translation levels | |
32 | * could be increased on the fly if system RAM is out of reach for the default | |
c265af51 SP |
33 | * VA range, so pages required to map highest possible PA are reserved in all |
34 | * cases. | |
87d1587b | 35 | */ |
2062d44d | 36 | #if ARM64_KERNEL_USES_PMD_MAPS |
87d1587b | 37 | #define SWAPPER_PGTABLE_LEVELS (CONFIG_PGTABLE_LEVELS - 1) |
c265af51 | 38 | #define IDMAP_PGTABLE_LEVELS (ARM64_HW_PGTABLE_LEVELS(PHYS_MASK_SHIFT) - 1) |
b433dce0 SP |
39 | #else |
40 | #define SWAPPER_PGTABLE_LEVELS (CONFIG_PGTABLE_LEVELS) | |
c265af51 | 41 | #define IDMAP_PGTABLE_LEVELS (ARM64_HW_PGTABLE_LEVELS(PHYS_MASK_SHIFT)) |
87d1587b SP |
42 | #endif |
43 | ||
0370b31e SC |
44 | |
45 | /* | |
46 | * If KASLR is enabled, then an offset K is added to the kernel address | |
47 | * space. The bottom 21 bits of this offset are zero to guarantee 2MB | |
48 | * alignment for PA and VA. | |
49 | * | |
50 | * For each pagetable level of the swapper, we know that the shift will | |
51 | * be larger than 21 (for the 4KB granule case we use section maps thus | |
52 | * the smallest shift is actually 30) thus there is the possibility that | |
53 | * KASLR can increase the number of pagetable entries by 1, so we make | |
54 | * room for this extra entry. | |
55 | * | |
56 | * Note KASLR cannot increase the number of required entries for a level | |
57 | * by more than one because it increments both the virtual start and end | |
58 | * addresses equally (the extra entry comes from the case where the end | |
59 | * address is just pushed over a boundary and the start address isn't). | |
60 | */ | |
61 | ||
62 | #ifdef CONFIG_RANDOMIZE_BASE | |
63 | #define EARLY_KASLR (1) | |
64 | #else | |
65 | #define EARLY_KASLR (0) | |
66 | #endif | |
67 | ||
90268574 MR |
68 | #define EARLY_ENTRIES(vstart, vend, shift) \ |
69 | ((((vend) - 1) >> (shift)) - ((vstart) >> (shift)) + 1 + EARLY_KASLR) | |
0370b31e SC |
70 | |
71 | #define EARLY_PGDS(vstart, vend) (EARLY_ENTRIES(vstart, vend, PGDIR_SHIFT)) | |
72 | ||
73 | #if SWAPPER_PGTABLE_LEVELS > 3 | |
74 | #define EARLY_PUDS(vstart, vend) (EARLY_ENTRIES(vstart, vend, PUD_SHIFT)) | |
75 | #else | |
76 | #define EARLY_PUDS(vstart, vend) (0) | |
77 | #endif | |
78 | ||
79 | #if SWAPPER_PGTABLE_LEVELS > 2 | |
80 | #define EARLY_PMDS(vstart, vend) (EARLY_ENTRIES(vstart, vend, SWAPPER_TABLE_SHIFT)) | |
81 | #else | |
82 | #define EARLY_PMDS(vstart, vend) (0) | |
83 | #endif | |
84 | ||
85 | #define EARLY_PAGES(vstart, vend) ( 1 /* PGDIR page */ \ | |
86 | + EARLY_PGDS((vstart), (vend)) /* each PGDIR needs a next level page table */ \ | |
87 | + EARLY_PUDS((vstart), (vend)) /* each PUD needs a next level page table */ \ | |
88 | + EARLY_PMDS((vstart), (vend))) /* each PMD needs a next level page table */ | |
120dc60d | 89 | #define INIT_DIR_SIZE (PAGE_SIZE * EARLY_PAGES(KIMAGE_VADDR, _end)) |
c265af51 | 90 | #define IDMAP_DIR_SIZE (IDMAP_PGTABLE_LEVELS * PAGE_SIZE) |
87d1587b SP |
91 | |
92 | /* Initial memory map size */ | |
2062d44d | 93 | #if ARM64_KERNEL_USES_PMD_MAPS |
4aaa87ab AK |
94 | #define SWAPPER_BLOCK_SHIFT PMD_SHIFT |
95 | #define SWAPPER_BLOCK_SIZE PMD_SIZE | |
87d1587b | 96 | #define SWAPPER_TABLE_SHIFT PUD_SHIFT |
b433dce0 SP |
97 | #else |
98 | #define SWAPPER_BLOCK_SHIFT PAGE_SHIFT | |
99 | #define SWAPPER_BLOCK_SIZE PAGE_SIZE | |
100 | #define SWAPPER_TABLE_SHIFT PMD_SHIFT | |
87d1587b SP |
101 | #endif |
102 | ||
87d1587b SP |
103 | /* |
104 | * Initial memory map attributes. | |
105 | */ | |
41acec62 WD |
106 | #define SWAPPER_PTE_FLAGS (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED) |
107 | #define SWAPPER_PMD_FLAGS (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S) | |
87d1587b | 108 | |
2062d44d | 109 | #if ARM64_KERNEL_USES_PMD_MAPS |
87d1587b | 110 | #define SWAPPER_MM_MMUFLAGS (PMD_ATTRINDX(MT_NORMAL) | SWAPPER_PMD_FLAGS) |
b433dce0 SP |
111 | #else |
112 | #define SWAPPER_MM_MMUFLAGS (PTE_ATTRINDX(MT_NORMAL) | SWAPPER_PTE_FLAGS) | |
87d1587b SP |
113 | #endif |
114 | ||
a7f8de16 AB |
115 | /* |
116 | * To make optimal use of block mappings when laying out the linear | |
117 | * mapping, round down the base of physical memory to a size that can | |
118 | * be mapped efficiently, i.e., either PUD_SIZE (4k granule) or PMD_SIZE | |
119 | * (64k granule), or a multiple that can be mapped using contiguous bits | |
120 | * in the page tables: 32 * PMD_SIZE (16k granule) | |
121 | */ | |
06e9bf2f AB |
122 | #if defined(CONFIG_ARM64_4K_PAGES) |
123 | #define ARM64_MEMSTART_SHIFT PUD_SHIFT | |
124 | #elif defined(CONFIG_ARM64_16K_PAGES) | |
ca6ece6a | 125 | #define ARM64_MEMSTART_SHIFT CONT_PMD_SHIFT |
a7f8de16 | 126 | #else |
06e9bf2f AB |
127 | #define ARM64_MEMSTART_SHIFT PMD_SHIFT |
128 | #endif | |
129 | ||
130 | /* | |
131 | * sparsemem vmemmap imposes an additional requirement on the alignment of | |
132 | * memstart_addr, due to the fact that the base of the vmemmap region | |
133 | * has a direct correspondence, and needs to appear sufficiently aligned | |
134 | * in the virtual address space. | |
135 | */ | |
782276b4 | 136 | #if ARM64_MEMSTART_SHIFT < SECTION_SIZE_BITS |
06e9bf2f AB |
137 | #define ARM64_MEMSTART_ALIGN (1UL << SECTION_SIZE_BITS) |
138 | #else | |
139 | #define ARM64_MEMSTART_ALIGN (1UL << ARM64_MEMSTART_SHIFT) | |
a7f8de16 | 140 | #endif |
87d1587b SP |
141 | |
142 | #endif /* __ASM_KERNEL_PGTABLE_H */ |