aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Whitchurch <vincent.whitchurch@axis.com>2018-07-13 06:12:22 -0400
committerRussell King <rmk+kernel@armlinux.org.uk>2018-07-30 06:45:19 -0400
commitafc9f65e01cd114cb2cedf544d22239116ce0cc6 (patch)
treec9639cc1dfb67ee0d1d8c504bc2ae52bf35b1ac2
parentb4c7e2bd2eb4764afe3af9409ff3b1b87116fa30 (diff)
ARM: 8781/1: Fix Thumb-2 syscall return for binutils 2.29+
When building the kernel as Thumb-2 with binutils 2.29 or newer, if the assembler has seen the .type directive (via ENDPROC()) for a symbol, it automatically handles the setting of the lowest bit when the symbol is used with ADR. The badr macro on the other hand handles this lowest bit manually. This leads to a jump to a wrong address in the wrong state in the syscall return path: Internal error: Oops - undefined instruction: 0 [#2] SMP THUMB2 Modules linked in: CPU: 0 PID: 652 Comm: modprobe Tainted: G D 4.18.0-rc3+ #8 PC is at ret_fast_syscall+0x4/0x62 LR is at sys_brk+0x109/0x128 pc : [<80101004>] lr : [<801c8a35>] psr: 60000013 Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none Control: 50c5387d Table: 9e82006a DAC: 00000051 Process modprobe (pid: 652, stack limit = 0x(ptrval)) 80101000 <ret_fast_syscall>: 80101000: b672 cpsid i 80101002: f8d9 2008 ldr.w r2, [r9, #8] 80101006: f1b2 4ffe cmp.w r2, #2130706432 ; 0x7f000000 80101184 <local_restart>: 80101184: f8d9 a000 ldr.w sl, [r9] 80101188: e92d 0030 stmdb sp!, {r4, r5} 8010118c: f01a 0ff0 tst.w sl, #240 ; 0xf0 80101190: d117 bne.n 801011c2 <__sys_trace> 80101192: 46ba mov sl, r7 80101194: f5ba 7fc8 cmp.w sl, #400 ; 0x190 80101198: bf28 it cs 8010119a: f04f 0a00 movcs.w sl, #0 8010119e: f3af 8014 nop.w {20} 801011a2: f2af 1ea2 subw lr, pc, #418 ; 0x1a2 To fix this, add a new symbol name which doesn't have ENDPROC used on it and use that with badr. We can't remove the badr usage since that would would cause breakage with older binutils. Signed-off-by: Vincent Whitchurch <vincent.whitchurch@axis.com> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
-rw-r--r--arch/arm/kernel/entry-common.S4
1 files changed, 3 insertions, 1 deletions
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 106a1466518d..746565a876dc 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -48,6 +48,7 @@ saved_pc .req lr
48 * from those features make this path too inefficient. 48 * from those features make this path too inefficient.
49 */ 49 */
50ret_fast_syscall: 50ret_fast_syscall:
51__ret_fast_syscall:
51 UNWIND(.fnstart ) 52 UNWIND(.fnstart )
52 UNWIND(.cantunwind ) 53 UNWIND(.cantunwind )
53 disable_irq_notrace @ disable interrupts 54 disable_irq_notrace @ disable interrupts
@@ -78,6 +79,7 @@ fast_work_pending:
78 * call. 79 * call.
79 */ 80 */
80ret_fast_syscall: 81ret_fast_syscall:
82__ret_fast_syscall:
81 UNWIND(.fnstart ) 83 UNWIND(.fnstart )
82 UNWIND(.cantunwind ) 84 UNWIND(.cantunwind )
83 str r0, [sp, #S_R0 + S_OFF]! @ save returned r0 85 str r0, [sp, #S_R0 + S_OFF]! @ save returned r0
@@ -255,7 +257,7 @@ local_restart:
255 tst r10, #_TIF_SYSCALL_WORK @ are we tracing syscalls? 257 tst r10, #_TIF_SYSCALL_WORK @ are we tracing syscalls?
256 bne __sys_trace 258 bne __sys_trace
257 259
258 invoke_syscall tbl, scno, r10, ret_fast_syscall 260 invoke_syscall tbl, scno, r10, __ret_fast_syscall
259 261
260 add r1, sp, #S_OFF 262 add r1, sp, #S_OFF
2612: cmp scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE) 2632: cmp scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE)