ARM: 8518/1: Use correct symbols for XIP_KERNEL
authorChris Brandt <chris.brandt@renesas.com>
Tue, 9 Feb 2016 18:34:43 +0000 (19:34 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Thu, 11 Feb 2016 15:43:14 +0000 (15:43 +0000)
For an XIP build, _etext does not represent the end of the
binary image that needs to stay mapped into the MODULES_VADDR area.
Years ago, data came before text in the memory map. However,
now that the order is text/init/data, an XIP_KERNEL needs to map
up to the data location in order to keep from cutting off
parts of the kernel that are needed.
We only map up to the beginning of data because data has already been
copied, so there's no reason to keep it around anymore.
A new symbol is created to make it clear what it is we are referring
to.

This fixes the bug where you might lose the end of your kernel area
after page table setup is complete.

Signed-off-by: Chris Brandt <chris.brandt@renesas.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/include/asm/Kbuild
arch/arm/include/asm/sections.h [new file with mode: 0644]
arch/arm/kernel/module.c
arch/arm/kernel/vmlinux-xip.lds.S
arch/arm/mm/mmu.c

index 16da6380eb8505a9f9b87db77ac4b56c1febd8d9..3f6616b472af6919f4308870b66228cfc0b884fd 100644 (file)
@@ -23,7 +23,6 @@ generic-y += preempt.h
 generic-y += resource.h
 generic-y += rwsem.h
 generic-y += seccomp.h
-generic-y += sections.h
 generic-y += segment.h
 generic-y += sembuf.h
 generic-y += serial.h
diff --git a/arch/arm/include/asm/sections.h b/arch/arm/include/asm/sections.h
new file mode 100644 (file)
index 0000000..803bbf2
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _ASM_ARM_SECTIONS_H
+#define _ASM_ARM_SECTIONS_H
+
+#include <asm-generic/sections.h>
+
+extern char _exiprom[];
+
+#endif /* _ASM_ARM_SECTIONS_H */
index efdddcb97dd14df54b0f7307acb6a57367793f6b..4f14b5ce6535f7a19215660ebb4b3e62bd6ea5ed 100644 (file)
@@ -34,7 +34,7 @@
  * recompiling the whole kernel when CONFIG_XIP_KERNEL is turned on/off.
  */
 #undef MODULES_VADDR
-#define MODULES_VADDR  (((unsigned long)_etext + ~PMD_MASK) & PMD_MASK)
+#define MODULES_VADDR  (((unsigned long)_exiprom + ~PMD_MASK) & PMD_MASK)
 #endif
 
 #ifdef CONFIG_MMU
index 7b1ded6fb628712e0a002559a40b5cf97441b40d..40bc4cadb959b2604c706a6080ccda5295c28bb0 100644 (file)
@@ -85,6 +85,7 @@ SECTIONS
        }
 
        . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR);
+       _xiprom = .;                    /* XIP ROM area to be mapped */
 
        .head.text : {
                _text = .;
@@ -210,6 +211,7 @@ SECTIONS
        PERCPU_SECTION(L1_CACHE_BYTES)
 #endif
 
+       _exiprom = .;                   /* End of XIP ROM area */
        __data_loc = ALIGN(4);          /* location in binary */
        . = PAGE_OFFSET + TEXT_OFFSET;
 
index 434d76f0b36314e3731fe74376b7db5bc92483a6..e4b681aafd6db5f501ac4b75afbfa2ff8341c4c9 100644 (file)
@@ -1253,7 +1253,7 @@ static inline void prepare_page_table(void)
 
 #ifdef CONFIG_XIP_KERNEL
        /* The XIP kernel is mapped in the module area -- skip over it */
-       addr = ((unsigned long)_etext + PMD_SIZE - 1) & PMD_MASK;
+       addr = ((unsigned long)_exiprom + PMD_SIZE - 1) & PMD_MASK;
 #endif
        for ( ; addr < PAGE_OFFSET; addr += PMD_SIZE)
                pmd_clear(pmd_off_k(addr));
@@ -1335,7 +1335,7 @@ static void __init devicemaps_init(const struct machine_desc *mdesc)
 #ifdef CONFIG_XIP_KERNEL
        map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK);
        map.virtual = MODULES_VADDR;
-       map.length = ((unsigned long)_etext - map.virtual + ~SECTION_MASK) & SECTION_MASK;
+       map.length = ((unsigned long)_exiprom - map.virtual + ~SECTION_MASK) & SECTION_MASK;
        map.type = MT_ROM;
        create_mapping(&map);
 #endif
@@ -1426,7 +1426,11 @@ static void __init kmap_init(void)
 static void __init map_lowmem(void)
 {
        struct memblock_region *reg;
+#ifdef CONFIG_XIP_KERNEL
+       phys_addr_t kernel_x_start = round_down(__pa(_sdata), SECTION_SIZE);
+#else
        phys_addr_t kernel_x_start = round_down(__pa(_stext), SECTION_SIZE);
+#endif
        phys_addr_t kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE);
 
        /* Map all the lowmem memory banks. */