aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/kernel/head.S
diff options
context:
space:
mode:
authorMark Rutland <mark.rutland@arm.com>2014-06-24 11:51:35 -0400
committerCatalin Marinas <catalin.marinas@arm.com>2014-07-10 07:36:12 -0400
commitbd00cd5f8c8c3c282bb1e1eac6a6679a4f808091 (patch)
treef146d737e7fdd6b107e23f51cd912402ef7f0bcd /arch/arm64/kernel/head.S
parent909a4069da65a5cfca8c968edf9f0d99f694d2f3 (diff)
arm64: place initial page tables above the kernel
Currently we place swapper_pg_dir and idmap_pg_dir below the kernel image, between PHYS_OFFSET and (PHYS_OFFSET + TEXT_OFFSET). However, bootloaders may use portions of this memory below the kernel and we do not parse the memory reservation list until after the MMU has been enabled. As such we may clobber some memory a bootloader wishes to have preserved. To enable the use of all of this memory by bootloaders (when the required memory reservations are communicated to the kernel) it is necessary to move our initial page tables elsewhere. As we currently have an effectively unbound requirement for memory at the end of the kernel image for .bss, we can place the page tables here. This patch moves the initial page table to the end of the kernel image, after the BSS. As they do not consist of any initialised data they will be stripped from the kernel Image as with the BSS. The BSS clearing routine is updated to stop at __bss_stop rather than _end so as to not clobber the page tables, and memory reservations made redundant by the new organisation are removed. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Tested-by: Laura Abbott <lauraa@codeaurora.org> Acked-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm64/kernel/head.S')
-rw-r--r--arch/arm64/kernel/head.S28
1 files changed, 8 insertions, 20 deletions
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 6dfb21e6e105..15d3c02a38d0 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -35,29 +35,17 @@
35#include <asm/page.h> 35#include <asm/page.h>
36#include <asm/virt.h> 36#include <asm/virt.h>
37 37
38/*
39 * swapper_pg_dir is the virtual address of the initial page table. We place
40 * the page tables 3 * PAGE_SIZE below KERNEL_RAM_VADDR. The idmap_pg_dir has
41 * 2 pages and is placed below swapper_pg_dir.
42 */
43#define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET) 38#define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET)
44 39
45#if (KERNEL_RAM_VADDR & 0xfffff) != 0x80000 40#if (KERNEL_RAM_VADDR & 0xfffff) != 0x80000
46#error KERNEL_RAM_VADDR must start at 0xXXX80000 41#error KERNEL_RAM_VADDR must start at 0xXXX80000
47#endif 42#endif
48 43
49#define SWAPPER_DIR_SIZE (3 * PAGE_SIZE) 44 .macro pgtbl, ttb0, ttb1, virt_to_phys
50#define IDMAP_DIR_SIZE (2 * PAGE_SIZE) 45 ldr \ttb1, =swapper_pg_dir
51 46 ldr \ttb0, =idmap_pg_dir
52 .globl swapper_pg_dir 47 add \ttb1, \ttb1, \virt_to_phys
53 .equ swapper_pg_dir, KERNEL_RAM_VADDR - SWAPPER_DIR_SIZE 48 add \ttb0, \ttb0, \virt_to_phys
54
55 .globl idmap_pg_dir
56 .equ idmap_pg_dir, swapper_pg_dir - IDMAP_DIR_SIZE
57
58 .macro pgtbl, ttb0, ttb1, phys
59 add \ttb1, \phys, #TEXT_OFFSET - SWAPPER_DIR_SIZE
60 sub \ttb0, \ttb1, #IDMAP_DIR_SIZE
61 .endm 49 .endm
62 50
63#ifdef CONFIG_ARM64_64K_PAGES 51#ifdef CONFIG_ARM64_64K_PAGES
@@ -413,7 +401,7 @@ ENTRY(secondary_startup)
413 mov x23, x0 // x23=current cpu_table 401 mov x23, x0 // x23=current cpu_table
414 cbz x23, __error_p // invalid processor (x23=0)? 402 cbz x23, __error_p // invalid processor (x23=0)?
415 403
416 pgtbl x25, x26, x24 // x25=TTBR0, x26=TTBR1 404 pgtbl x25, x26, x28 // x25=TTBR0, x26=TTBR1
417 ldr x12, [x23, #CPU_INFO_SETUP] 405 ldr x12, [x23, #CPU_INFO_SETUP]
418 add x12, x12, x28 // __virt_to_phys 406 add x12, x12, x28 // __virt_to_phys
419 blr x12 // initialise processor 407 blr x12 // initialise processor
@@ -527,7 +515,7 @@ ENDPROC(__calc_phys_offset)
527 * - pgd entry for fixed mappings (TTBR1) 515 * - pgd entry for fixed mappings (TTBR1)
528 */ 516 */
529__create_page_tables: 517__create_page_tables:
530 pgtbl x25, x26, x24 // idmap_pg_dir and swapper_pg_dir addresses 518 pgtbl x25, x26, x28 // idmap_pg_dir and swapper_pg_dir addresses
531 mov x27, lr 519 mov x27, lr
532 520
533 /* 521 /*
@@ -616,7 +604,7 @@ ENDPROC(__create_page_tables)
616__switch_data: 604__switch_data:
617 .quad __mmap_switched 605 .quad __mmap_switched
618 .quad __bss_start // x6 606 .quad __bss_start // x6
619 .quad _end // x7 607 .quad __bss_stop // x7
620 .quad processor_id // x4 608 .quad processor_id // x4
621 .quad __fdt_pointer // x5 609 .quad __fdt_pointer // x5
622 .quad memstart_addr // x6 610 .quad memstart_addr // x6