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>
This commit is contained in:
committed by
Russell King
parent
15e7e5c1eb
commit
2874865c12
@@ -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
|
||||||
|
Reference in New Issue
Block a user