diff options
author | Mark Rutland <mark.rutland@arm.com> | 2014-06-24 11:51:35 -0400 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2014-07-10 07:36:12 -0400 |
commit | bd00cd5f8c8c3c282bb1e1eac6a6679a4f808091 (patch) | |
tree | f146d737e7fdd6b107e23f51cd912402ef7f0bcd /arch/arm64/kernel/head.S | |
parent | 909a4069da65a5cfca8c968edf9f0d99f694d2f3 (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.S | 28 |
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 |