diff options
Diffstat (limited to 'arch/arm64/mm/mmu.c')
-rw-r--r-- | arch/arm64/mm/mmu.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index a8d1059b91b2..f557ebbe7013 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c | |||
@@ -296,6 +296,7 @@ void __iomem * __init early_io_map(phys_addr_t phys, unsigned long virt) | |||
296 | static void __init map_mem(void) | 296 | static void __init map_mem(void) |
297 | { | 297 | { |
298 | struct memblock_region *reg; | 298 | struct memblock_region *reg; |
299 | phys_addr_t limit; | ||
299 | 300 | ||
300 | /* | 301 | /* |
301 | * Temporarily limit the memblock range. We need to do this as | 302 | * Temporarily limit the memblock range. We need to do this as |
@@ -303,9 +304,11 @@ static void __init map_mem(void) | |||
303 | * memory addressable from the initial direct kernel mapping. | 304 | * memory addressable from the initial direct kernel mapping. |
304 | * | 305 | * |
305 | * The initial direct kernel mapping, located at swapper_pg_dir, | 306 | * The initial direct kernel mapping, located at swapper_pg_dir, |
306 | * gives us PGDIR_SIZE memory starting from PHYS_OFFSET (aligned). | 307 | * gives us PGDIR_SIZE memory starting from PHYS_OFFSET (which must be |
308 | * aligned to 2MB as per Documentation/arm64/booting.txt). | ||
307 | */ | 309 | */ |
308 | memblock_set_current_limit((PHYS_OFFSET & PGDIR_MASK) + PGDIR_SIZE); | 310 | limit = PHYS_OFFSET + PGDIR_SIZE; |
311 | memblock_set_current_limit(limit); | ||
309 | 312 | ||
310 | /* map all the memory banks */ | 313 | /* map all the memory banks */ |
311 | for_each_memblock(memory, reg) { | 314 | for_each_memblock(memory, reg) { |
@@ -315,6 +318,22 @@ static void __init map_mem(void) | |||
315 | if (start >= end) | 318 | if (start >= end) |
316 | break; | 319 | break; |
317 | 320 | ||
321 | #ifndef CONFIG_ARM64_64K_PAGES | ||
322 | /* | ||
323 | * For the first memory bank align the start address and | ||
324 | * current memblock limit to prevent create_mapping() from | ||
325 | * allocating pte page tables from unmapped memory. | ||
326 | * When 64K pages are enabled, the pte page table for the | ||
327 | * first PGDIR_SIZE is already present in swapper_pg_dir. | ||
328 | */ | ||
329 | if (start < limit) | ||
330 | start = ALIGN(start, PMD_SIZE); | ||
331 | if (end < limit) { | ||
332 | limit = end & PMD_MASK; | ||
333 | memblock_set_current_limit(limit); | ||
334 | } | ||
335 | #endif | ||
336 | |||
318 | create_mapping(start, __phys_to_virt(start), end - start); | 337 | create_mapping(start, __phys_to_virt(start), end - start); |
319 | } | 338 | } |
320 | 339 | ||