Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARM: 7171/1: unwind: add unwind directives to bitops assembly macros

The bitops functions (e.g. _test_and_set_bit) on ARM do not have unwind
annotations and therefore the kernel cannot backtrace out of them on a
fatal error (for example, NULL pointer dereference).

This patch annotates the bitops assembly macros with UNWIND annotations
so that we can produce a meaningful backtrace on error. Callers of the
macros are modified to pass their function name as a macro parameter,
enforcing that the macros are used as standalone function implementations.

Acked-by: Dave Martin <dave.martin@linaro.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

authored by

Will Deacon and committed by
Russell King
c36ef4b1 c89cefed

+28 -22
+22 -4
arch/arm/lib/bitops.h
··· 1 + #include <asm/unwind.h> 2 + 1 3 #if __LINUX_ARM_ARCH__ >= 6 2 - .macro bitop, instr 4 + .macro bitop, name, instr 5 + ENTRY( \name ) 6 + UNWIND( .fnstart ) 3 7 ands ip, r1, #3 4 8 strneb r1, [ip] @ assert word-aligned 5 9 mov r2, #1 ··· 17 13 cmp r0, #0 18 14 bne 1b 19 15 bx lr 16 + UNWIND( .fnend ) 17 + ENDPROC(\name ) 20 18 .endm 21 19 22 - .macro testop, instr, store 20 + .macro testop, name, instr, store 21 + ENTRY( \name ) 22 + UNWIND( .fnstart ) 23 23 ands ip, r1, #3 24 24 strneb r1, [ip] @ assert word-aligned 25 25 mov r2, #1 ··· 42 34 cmp r0, #0 43 35 movne r0, #1 44 36 2: bx lr 37 + UNWIND( .fnend ) 38 + ENDPROC(\name ) 45 39 .endm 46 40 #else 47 - .macro bitop, instr 41 + .macro bitop, name, instr 42 + ENTRY( \name ) 43 + UNWIND( .fnstart ) 48 44 ands ip, r1, #3 49 45 strneb r1, [ip] @ assert word-aligned 50 46 and r2, r0, #31 ··· 61 49 str r2, [r1, r0, lsl #2] 62 50 restore_irqs ip 63 51 mov pc, lr 52 + UNWIND( .fnend ) 53 + ENDPROC(\name ) 64 54 .endm 65 55 66 56 /** ··· 73 59 * Note: we can trivially conditionalise the store instruction 74 60 * to avoid dirtying the data cache. 75 61 */ 76 - .macro testop, instr, store 62 + .macro testop, name, instr, store 63 + ENTRY( \name ) 64 + UNWIND( .fnstart ) 77 65 ands ip, r1, #3 78 66 strneb r1, [ip] @ assert word-aligned 79 67 and r3, r0, #31 ··· 89 73 moveq r0, #0 90 74 restore_irqs ip 91 75 mov pc, lr 76 + UNWIND( .fnend ) 77 + ENDPROC(\name ) 92 78 .endm 93 79 #endif
+1 -3
arch/arm/lib/changebit.S
··· 12 12 #include "bitops.h" 13 13 .text 14 14 15 - ENTRY(_change_bit) 16 - bitop eor 17 - ENDPROC(_change_bit) 15 + bitop _change_bit, eor
+1 -3
arch/arm/lib/clearbit.S
··· 12 12 #include "bitops.h" 13 13 .text 14 14 15 - ENTRY(_clear_bit) 16 - bitop bic 17 - ENDPROC(_clear_bit) 15 + bitop _clear_bit, bic
+1 -3
arch/arm/lib/setbit.S
··· 12 12 #include "bitops.h" 13 13 .text 14 14 15 - ENTRY(_set_bit) 16 - bitop orr 17 - ENDPROC(_set_bit) 15 + bitop _set_bit, orr
+1 -3
arch/arm/lib/testchangebit.S
··· 12 12 #include "bitops.h" 13 13 .text 14 14 15 - ENTRY(_test_and_change_bit) 16 - testop eor, str 17 - ENDPROC(_test_and_change_bit) 15 + testop _test_and_change_bit, eor, str
+1 -3
arch/arm/lib/testclearbit.S
··· 12 12 #include "bitops.h" 13 13 .text 14 14 15 - ENTRY(_test_and_clear_bit) 16 - testop bicne, strne 17 - ENDPROC(_test_and_clear_bit) 15 + testop _test_and_clear_bit, bicne, strne
+1 -3
arch/arm/lib/testsetbit.S
··· 12 12 #include "bitops.h" 13 13 .text 14 14 15 - ENTRY(_test_and_set_bit) 16 - testop orreq, streq 17 - ENDPROC(_test_and_set_bit) 15 + testop _test_and_set_bit, orreq, streq