avr32: fix out-of-range jump in large kernels
This patch fixes following error (for big kernels):
---8<---
arch/avr32/boot/u-boot/head.o: In function `no_tag_table':
(.init.text+0x44): relocation truncated to fit: R_AVR32_22H_PCREL against symbol `panic' defined in .text.unlikely section in kernel/built-in.o
arch/avr32/kernel/built-in.o: In function `bad_return':
(.ex.text+0x236): relocation truncated to fit: R_AVR32_22H_PCREL against symbol `panic' defined in .text.unlikely section in kernel/built-in.o
--->8---
It comes up when the kernel increases and 'panic()' is too far away to fit in
the +/- 2MiB range. Which in turn issues from the 21-bit displacement in
'br{cond4}' mnemonic which is one of the two ways to do jumps (rjmp has just
10-bit displacement and therefore a way smaller range). This fact was stated
before in 8d29b7b9f8
.
One solution to solve this is to add a local storage for the symbol address
and just load the $pc with that value.
Signed-off-by: Andreas Bießmann <andreas@biessmann.de>
Acked-by: Hans-Christian Egtvedt <egtvedt@samfundet.no>
Cc: Haavard Skinnemoen <hskinnemoen@gmail.com>
Cc: stable@vger.kernel.org
This commit is contained in:
Родитель
7a2a74f4b8
Коммит
d617b338bb
|
@ -73,8 +73,11 @@ init_sr:
|
|||
.long 0x007f0000 /* Supervisor mode, everything masked */
|
||||
stack_addr:
|
||||
.long init_thread_union
|
||||
panic_addr:
|
||||
.long panic
|
||||
|
||||
no_tag_table:
|
||||
sub r12, pc, (. - 2f)
|
||||
bral panic
|
||||
/* branch to panic() which can be far away with that construct */
|
||||
lddpc pc, panic_addr
|
||||
2: .asciz "Boot loader didn't provide correct magic number\n"
|
||||
|
|
|
@ -401,9 +401,10 @@ handle_critical:
|
|||
/* We should never get here... */
|
||||
bad_return:
|
||||
sub r12, pc, (. - 1f)
|
||||
bral panic
|
||||
lddpc pc, 2f
|
||||
.align 2
|
||||
1: .asciz "Return from critical exception!"
|
||||
2: .long panic
|
||||
|
||||
.align 1
|
||||
do_bus_error_write:
|
||||
|
|
Загрузка…
Ссылка в новой задаче