瀏覽代碼

ARM: 7751/1: zImage: don't overwrite ourself with a page table

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@linaro.org>
Reported-by: Stephen Boyd <sboyd@codeurora.org>
Tested-by: Stephen Boyd <sboyd@codeurora.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Nicolas Pitre 12 年之前
父節點
當前提交
2874865c12
共有 1 個文件被更改,包括 30 次插入5 次删除
  1. 30 5
      arch/arm/boot/compressed/head.S

+ 30 - 5
arch/arm/boot/compressed/head.S

@@ -182,7 +182,19 @@ not_angel:
 		ldr	r4, =zreladdr
 		ldr	r4, =zreladdr
 #endif
 #endif
 
 
-		bl	cache_on
+		/*
+		 * Set up a page table only if it won't overwrite ourself.
+		 * That means r4 < pc && r4 - 16k page directory > &_end.
+		 * Given that r4 > &_end 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
+		orrcc	r4, r4, #1		@ remember we skipped cache_on
+		blcs	cache_on
 
 
 restart:	adr	r0, LC0
 restart:	adr	r0, LC0
 		ldmia	r0, {r1, r2, r3, r6, r10, r11, r12}
 		ldmia	r0, {r1, r2, r3, r6, r10, r11, r12}
@@ -228,7 +240,7 @@ restart:	adr	r0, LC0
  *   r0  = delta
  *   r0  = delta
  *   r2  = BSS start
  *   r2  = BSS start
  *   r3  = BSS end
  *   r3  = BSS end
- *   r4  = final kernel address
+ *   r4  = final kernel address (possibly with LSB set)
  *   r5  = appended dtb size (still unknown)
  *   r5  = appended dtb size (still unknown)
  *   r6  = _edata
  *   r6  = _edata
  *   r7  = architecture ID
  *   r7  = architecture ID
@@ -276,6 +288,7 @@ restart:	adr	r0, LC0
 		 */
 		 */
 		cmp	r0, #1
 		cmp	r0, #1
 		sub	r0, r4, #TEXT_OFFSET
 		sub	r0, r4, #TEXT_OFFSET
+		bic	r0, r0, #1
 		add	r0, r0, #0x100
 		add	r0, r0, #0x100
 		mov	r1, r6
 		mov	r1, r6
 		sub	r2, sp, r6
 		sub	r2, sp, r6
@@ -322,12 +335,13 @@ dtb_check_done:
 
 
 /*
 /*
  * Check to see if we will overwrite ourselves.
  * Check to see if we will overwrite ourselves.
- *   r4  = final kernel address
+ *   r4  = final kernel address (possibly with LSB set)
  *   r9  = size of decompressed image
  *   r9  = size of decompressed image
  *   r10 = end of this image, including  bss/stack/malloc space if non XIP
  *   r10 = end of this image, including  bss/stack/malloc space if non XIP
  * We basically want:
  * We basically want:
  *   r4 - 16k page directory >= r10 -> OK
  *   r4 - 16k page directory >= r10 -> OK
  *   r4 + image length <= address of wont_overwrite -> OK
  *   r4 + image length <= address of wont_overwrite -> OK
+ * Note: the possible LSB in r4 is harmless here.
  */
  */
 		add	r10, r10, #16384
 		add	r10, r10, #16384
 		cmp	r4, r10
 		cmp	r4, r10
@@ -389,7 +403,8 @@ dtb_check_done:
 		add	sp, sp, r6
 		add	sp, sp, r6
 #endif
 #endif
 
 
-		bl	cache_clean_flush
+		tst	r4, #1
+		bleq	cache_clean_flush
 
 
 		adr	r0, BSYM(restart)
 		adr	r0, BSYM(restart)
 		add	r0, r0, r6
 		add	r0, r0, r6
@@ -401,7 +416,7 @@ wont_overwrite:
  *   r0  = delta
  *   r0  = delta
  *   r2  = BSS start
  *   r2  = BSS start
  *   r3  = BSS end
  *   r3  = BSS end
- *   r4  = kernel execution address
+ *   r4  = kernel execution address (possibly with LSB set)
  *   r5  = appended dtb size (0 if not present)
  *   r5  = appended dtb size (0 if not present)
  *   r7  = architecture ID
  *   r7  = architecture ID
  *   r8  = atags pointer
  *   r8  = atags pointer
@@ -464,6 +479,15 @@ not_relocated:	mov	r0, #0
 		cmp	r2, r3
 		cmp	r2, r3
 		blo	1b
 		blo	1b
 
 
+		/*
+		 * Did we skip the cache setup earlier?
+		 * That is indicated by the LSB in r4.
+		 * Do it now if so.
+		 */
+		tst	r4, #1
+		bic	r4, r4, #1
+		blne	cache_on
+
 /*
 /*
  * The C runtime environment should now be setup sufficiently.
  * The C runtime environment should now be setup sufficiently.
  * Set up some pointers, and start decompressing.
  * Set up some pointers, and start decompressing.
@@ -512,6 +536,7 @@ LC0:		.word	LC0			@ r1
 		.word	_got_start		@ r11
 		.word	_got_start		@ r11
 		.word	_got_end		@ ip
 		.word	_got_end		@ ip
 		.word	.L_user_stack_end	@ sp
 		.word	.L_user_stack_end	@ sp
+		.word	_end - restart + 16384 + 1024*1024
 		.size	LC0, . - LC0
 		.size	LC0, . - LC0
 
 
 #ifdef CONFIG_ARCH_RPC
 #ifdef CONFIG_ARCH_RPC