Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2874865c authored by Nicolas Pitre's avatar Nicolas Pitre Committed by Russell King
Browse files

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: default avatarNicolas Pitre <nico@linaro.org>
Reported-by: default avatarStephen Boyd <sboyd@codeurora.org>
Tested-by: default avatarStephen Boyd <sboyd@codeurora.org>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 15e7e5c1
Loading
Loading
Loading
Loading
+30 −5
Original line number Diff line number Diff line
@@ -182,7 +182,19 @@ not_angel:
		ldr	r4, =zreladdr
#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
		ldmia	r0, {r1, r2, r3, r6, r10, r11, r12}
@@ -228,7 +240,7 @@ restart: adr r0, LC0
 *   r0  = delta
 *   r2  = BSS start
 *   r3  = BSS end
 *   r4  = final kernel address
 *   r4  = final kernel address (possibly with LSB set)
 *   r5  = appended dtb size (still unknown)
 *   r6  = _edata
 *   r7  = architecture ID
@@ -276,6 +288,7 @@ restart: adr r0, LC0
		 */
		cmp	r0, #1
		sub	r0, r4, #TEXT_OFFSET
		bic	r0, r0, #1
		add	r0, r0, #0x100
		mov	r1, r6
		sub	r2, sp, r6
@@ -322,12 +335,13 @@ dtb_check_done:

/*
 * 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
 *   r10 = end of this image, including  bss/stack/malloc space if non XIP
 * We basically want:
 *   r4 - 16k page directory >= r10 -> OK
 *   r4 + image length <= address of wont_overwrite -> OK
 * Note: the possible LSB in r4 is harmless here.
 */
		add	r10, r10, #16384
		cmp	r4, r10
@@ -389,7 +403,8 @@ dtb_check_done:
		add	sp, sp, r6
#endif

		bl	cache_clean_flush
		tst	r4, #1
		bleq	cache_clean_flush

		adr	r0, BSYM(restart)
		add	r0, r0, r6
@@ -401,7 +416,7 @@ wont_overwrite:
 *   r0  = delta
 *   r2  = BSS start
 *   r3  = BSS end
 *   r4  = kernel execution address
 *   r4  = kernel execution address (possibly with LSB set)
 *   r5  = appended dtb size (0 if not present)
 *   r7  = architecture ID
 *   r8  = atags pointer
@@ -464,6 +479,15 @@ not_relocated: mov r0, #0
		cmp	r2, r3
		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.
 * Set up some pointers, and start decompressing.
@@ -512,6 +536,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