Skip to content

Commit

Permalink
ARM: 7751/1: zImage: don't overwrite ourself with a page table
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Nicolas Pitre authored and Russell King committed Jun 17, 2013
1 parent 15e7e5c commit 2874865
Showing 1 changed file with 30 additions and 5 deletions.
35 changes: 30 additions & 5 deletions arch/arm/boot/compressed/head.S
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 2874865

Please sign in to comment.