]>
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 | ||
4b65a5db | 11 | #include <asm/pgtable.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 | |
21 | #define ARM64_SWAPPER_USES_SECTION_MAPS 1 | |
22 | #else | |
23 | #define ARM64_SWAPPER_USES_SECTION_MAPS 0 | |
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 | */ |
b433dce0 | 36 | #if ARM64_SWAPPER_USES_SECTION_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 | ||
68 | #define EARLY_ENTRIES(vstart, vend, shift) (((vend) >> (shift)) \ | |
69 | - ((vstart) >> (shift)) + 1 + EARLY_KASLR) | |
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 */ | |
2b5548b6 | 89 | #define INIT_DIR_SIZE (PAGE_SIZE * EARLY_PAGES(KIMAGE_VADDR + TEXT_OFFSET, _end)) |
c265af51 | 90 | #define IDMAP_DIR_SIZE (IDMAP_PGTABLE_LEVELS * PAGE_SIZE) |
87d1587b | 91 | |
4b65a5db CM |
92 | #ifdef CONFIG_ARM64_SW_TTBR0_PAN |
93 | #define RESERVED_TTBR0_SIZE (PAGE_SIZE) | |
94 | #else | |
95 | #define RESERVED_TTBR0_SIZE (0) | |
96 | #endif | |
97 | ||
87d1587b | 98 | /* Initial memory map size */ |
b433dce0 | 99 | #if ARM64_SWAPPER_USES_SECTION_MAPS |
87d1587b SP |
100 | #define SWAPPER_BLOCK_SHIFT SECTION_SHIFT |
101 | #define SWAPPER_BLOCK_SIZE SECTION_SIZE | |
102 | #define SWAPPER_TABLE_SHIFT PUD_SHIFT | |
b433dce0 SP |
103 | #else |
104 | #define SWAPPER_BLOCK_SHIFT PAGE_SHIFT | |
105 | #define SWAPPER_BLOCK_SIZE PAGE_SIZE | |
106 | #define SWAPPER_TABLE_SHIFT PMD_SHIFT | |
87d1587b SP |
107 | #endif |
108 | ||
b433dce0 SP |
109 | /* The size of the initial kernel direct mapping */ |
110 | #define SWAPPER_INIT_MAP_SIZE (_AC(1, UL) << SWAPPER_TABLE_SHIFT) | |
87d1587b SP |
111 | |
112 | /* | |
113 | * Initial memory map attributes. | |
114 | */ | |
41acec62 WD |
115 | #define SWAPPER_PTE_FLAGS (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED) |
116 | #define SWAPPER_PMD_FLAGS (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S) | |
87d1587b | 117 | |
b433dce0 | 118 | #if ARM64_SWAPPER_USES_SECTION_MAPS |
87d1587b | 119 | #define SWAPPER_MM_MMUFLAGS (PMD_ATTRINDX(MT_NORMAL) | SWAPPER_PMD_FLAGS) |
b433dce0 SP |
120 | #else |
121 | #define SWAPPER_MM_MMUFLAGS (PTE_ATTRINDX(MT_NORMAL) | SWAPPER_PTE_FLAGS) | |
87d1587b SP |
122 | #endif |
123 | ||
a7f8de16 AB |
124 | /* |
125 | * To make optimal use of block mappings when laying out the linear | |
126 | * mapping, round down the base of physical memory to a size that can | |
127 | * be mapped efficiently, i.e., either PUD_SIZE (4k granule) or PMD_SIZE | |
128 | * (64k granule), or a multiple that can be mapped using contiguous bits | |
129 | * in the page tables: 32 * PMD_SIZE (16k granule) | |
130 | */ | |
06e9bf2f AB |
131 | #if defined(CONFIG_ARM64_4K_PAGES) |
132 | #define ARM64_MEMSTART_SHIFT PUD_SHIFT | |
133 | #elif defined(CONFIG_ARM64_16K_PAGES) | |
134 | #define ARM64_MEMSTART_SHIFT (PMD_SHIFT + 5) | |
a7f8de16 | 135 | #else |
06e9bf2f AB |
136 | #define ARM64_MEMSTART_SHIFT PMD_SHIFT |
137 | #endif | |
138 | ||
139 | /* | |
140 | * sparsemem vmemmap imposes an additional requirement on the alignment of | |
141 | * memstart_addr, due to the fact that the base of the vmemmap region | |
142 | * has a direct correspondence, and needs to appear sufficiently aligned | |
143 | * in the virtual address space. | |
144 | */ | |
145 | #if defined(CONFIG_SPARSEMEM_VMEMMAP) && ARM64_MEMSTART_SHIFT < SECTION_SIZE_BITS | |
146 | #define ARM64_MEMSTART_ALIGN (1UL << SECTION_SIZE_BITS) | |
147 | #else | |
148 | #define ARM64_MEMSTART_ALIGN (1UL << ARM64_MEMSTART_SHIFT) | |
a7f8de16 | 149 | #endif |
87d1587b SP |
150 | |
151 | #endif /* __ASM_KERNEL_PGTABLE_H */ |