diff options
Diffstat (limited to 'mm/kasan/kasan_init.c')
-rw-r--r-- | mm/kasan/kasan_init.c | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/mm/kasan/kasan_init.c b/mm/kasan/kasan_init.c index 31238dad85fb..b96a5f773d88 100644 --- a/mm/kasan/kasan_init.c +++ b/mm/kasan/kasan_init.c | |||
@@ -30,6 +30,9 @@ | |||
30 | */ | 30 | */ |
31 | unsigned char kasan_zero_page[PAGE_SIZE] __page_aligned_bss; | 31 | unsigned char kasan_zero_page[PAGE_SIZE] __page_aligned_bss; |
32 | 32 | ||
33 | #if CONFIG_PGTABLE_LEVELS > 4 | ||
34 | p4d_t kasan_zero_p4d[PTRS_PER_P4D] __page_aligned_bss; | ||
35 | #endif | ||
33 | #if CONFIG_PGTABLE_LEVELS > 3 | 36 | #if CONFIG_PGTABLE_LEVELS > 3 |
34 | pud_t kasan_zero_pud[PTRS_PER_PUD] __page_aligned_bss; | 37 | pud_t kasan_zero_pud[PTRS_PER_PUD] __page_aligned_bss; |
35 | #endif | 38 | #endif |
@@ -82,10 +85,10 @@ static void __init zero_pmd_populate(pud_t *pud, unsigned long addr, | |||
82 | } while (pmd++, addr = next, addr != end); | 85 | } while (pmd++, addr = next, addr != end); |
83 | } | 86 | } |
84 | 87 | ||
85 | static void __init zero_pud_populate(pgd_t *pgd, unsigned long addr, | 88 | static void __init zero_pud_populate(p4d_t *p4d, unsigned long addr, |
86 | unsigned long end) | 89 | unsigned long end) |
87 | { | 90 | { |
88 | pud_t *pud = pud_offset(pgd, addr); | 91 | pud_t *pud = pud_offset(p4d, addr); |
89 | unsigned long next; | 92 | unsigned long next; |
90 | 93 | ||
91 | do { | 94 | do { |
@@ -107,6 +110,23 @@ static void __init zero_pud_populate(pgd_t *pgd, unsigned long addr, | |||
107 | } while (pud++, addr = next, addr != end); | 110 | } while (pud++, addr = next, addr != end); |
108 | } | 111 | } |
109 | 112 | ||
113 | static void __init zero_p4d_populate(pgd_t *pgd, unsigned long addr, | ||
114 | unsigned long end) | ||
115 | { | ||
116 | p4d_t *p4d = p4d_offset(pgd, addr); | ||
117 | unsigned long next; | ||
118 | |||
119 | do { | ||
120 | next = p4d_addr_end(addr, end); | ||
121 | |||
122 | if (p4d_none(*p4d)) { | ||
123 | p4d_populate(&init_mm, p4d, | ||
124 | early_alloc(PAGE_SIZE, NUMA_NO_NODE)); | ||
125 | } | ||
126 | zero_pud_populate(p4d, addr, next); | ||
127 | } while (p4d++, addr = next, addr != end); | ||
128 | } | ||
129 | |||
110 | /** | 130 | /** |
111 | * kasan_populate_zero_shadow - populate shadow memory region with | 131 | * kasan_populate_zero_shadow - populate shadow memory region with |
112 | * kasan_zero_page | 132 | * kasan_zero_page |
@@ -125,6 +145,7 @@ void __init kasan_populate_zero_shadow(const void *shadow_start, | |||
125 | next = pgd_addr_end(addr, end); | 145 | next = pgd_addr_end(addr, end); |
126 | 146 | ||
127 | if (IS_ALIGNED(addr, PGDIR_SIZE) && end - addr >= PGDIR_SIZE) { | 147 | if (IS_ALIGNED(addr, PGDIR_SIZE) && end - addr >= PGDIR_SIZE) { |
148 | p4d_t *p4d; | ||
128 | pud_t *pud; | 149 | pud_t *pud; |
129 | pmd_t *pmd; | 150 | pmd_t *pmd; |
130 | 151 | ||
@@ -135,9 +156,22 @@ void __init kasan_populate_zero_shadow(const void *shadow_start, | |||
135 | * 3,2 - level page tables where we don't have | 156 | * 3,2 - level page tables where we don't have |
136 | * puds,pmds, so pgd_populate(), pud_populate() | 157 | * puds,pmds, so pgd_populate(), pud_populate() |
137 | * is noops. | 158 | * is noops. |
159 | * | ||
160 | * The ifndef is required to avoid build breakage. | ||
161 | * | ||
162 | * With 5level-fixup.h, pgd_populate() is not nop and | ||
163 | * we reference kasan_zero_p4d. It's not defined | ||
164 | * unless 5-level paging enabled. | ||
165 | * | ||
166 | * The ifndef can be dropped once all KASAN-enabled | ||
167 | * architectures will switch to pgtable-nop4d.h. | ||
138 | */ | 168 | */ |
139 | pgd_populate(&init_mm, pgd, lm_alias(kasan_zero_pud)); | 169 | #ifndef __ARCH_HAS_5LEVEL_HACK |
140 | pud = pud_offset(pgd, addr); | 170 | pgd_populate(&init_mm, pgd, lm_alias(kasan_zero_p4d)); |
171 | #endif | ||
172 | p4d = p4d_offset(pgd, addr); | ||
173 | p4d_populate(&init_mm, p4d, lm_alias(kasan_zero_pud)); | ||
174 | pud = pud_offset(p4d, addr); | ||
141 | pud_populate(&init_mm, pud, lm_alias(kasan_zero_pmd)); | 175 | pud_populate(&init_mm, pud, lm_alias(kasan_zero_pmd)); |
142 | pmd = pmd_offset(pud, addr); | 176 | pmd = pmd_offset(pud, addr); |
143 | pmd_populate_kernel(&init_mm, pmd, lm_alias(kasan_zero_pte)); | 177 | pmd_populate_kernel(&init_mm, pmd, lm_alias(kasan_zero_pte)); |
@@ -148,6 +182,6 @@ void __init kasan_populate_zero_shadow(const void *shadow_start, | |||
148 | pgd_populate(&init_mm, pgd, | 182 | pgd_populate(&init_mm, pgd, |
149 | early_alloc(PAGE_SIZE, NUMA_NO_NODE)); | 183 | early_alloc(PAGE_SIZE, NUMA_NO_NODE)); |
150 | } | 184 | } |
151 | zero_pud_populate(pgd, addr, next); | 185 | zero_p4d_populate(pgd, addr, next); |
152 | } while (pgd++, addr = next, addr != end); | 186 | } while (pgd++, addr = next, addr != end); |
153 | } | 187 | } |