[PATCH] ARM: zImage: don't overwrite ourself with a page table

From: Nicolas Pitre
Date: Tue Jun 04 2013 - 17:01:30 EST


When zImage is loaded into RAM at a low address but TEXT_OFFSET
is set higher, we risk overwriting ourself with the page table
needed to turn on the cache as it is located relative to the relocation
address. Let's defer the cache setup after relocation in that case.

Signed-off-by: Nicolas Pitre <nico@xxxxxxxxxx>

diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 9a94f344df..773bc35f92 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -178,11 +178,23 @@ not_angel:
mov r4, pc
and r4, r4, #0xf8000000
add r4, r4, #TEXT_OFFSET
+ bl cache_on
#else
ldr r4, =zreladdr
-#endif

- bl cache_on
+ /*
+ * Set up a page table only if we don't overwrite ourself.
+ * That means r4 < pc && r4 - 4K > &_end.
+ * Given that r4 > &_en is most unfrequent, we add a rough
+ * additional 1MB of room for a possible appended DTB.
+ */
+ mov r0, pc
+ cmp r0, r4
+ ldrcc r0, LC0+32
+ addcc r0, r0, pc
+ cmpcc r4, r0
+ blcs cache_on
+#endif

restart: adr r0, LC0
ldmia r0, {r1, r2, r3, r6, r10, r11, r12}
@@ -464,6 +476,16 @@ not_relocated: mov r0, #0
cmp r2, r3
blo 1b

+#if defined(CONFIG_AUTO_ZRELADDR) && defined(CONFIG_CPU_CP15)
+ /*
+ * Did we skip the cache setup earlier?
+ * Do it now if so.
+ */
+ mrc p15, 0, r0, c1, c0, 0 @ read control register
+ tst r0, #1 @ MMU bit set?
+ bleq cache_on @ no: set it up
+#endif
+
/*
* The C runtime environment should now be setup sufficiently.
* Set up some pointers, and start decompressing.
@@ -512,6 +534,7 @@ LC0: .word LC0 @ r1
.word _got_start @ r11
.word _got_end @ ip
.word .L_user_stack_end @ sp
+ .word _end - restart + 16384 + 1024*1024
.size LC0, . - LC0

#ifdef CONFIG_ARCH_RPC
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/