ARM: entry: get rid of multiple macro definitions
authorRussell King <rmk+kernel@arm.linux.org.uk>
Wed, 26 Aug 2015 19:07:25 +0000 (20:07 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Wed, 26 Aug 2015 19:25:48 +0000 (20:25 +0100)
The following structure is just asking for trouble:

 #ifdef CONFIG_symbol
.macro foo
...
.endm
.macro bar
...
.endm
.macro baz
...
.endm
 #else
.macro foo
...
.endm
.macro bar
...
.endm
 #ifdef CONFIG_symbol2
.macro baz
...
.endm
 #else
.macro baz
...
.endm
 #endif
 #endif

such as one defintion being updated, but the other definitions miss out.
Where the contents of a macro needs to be conditional, the hint is in
the first clause of this very sentence.  "contents" "conditional".  Not
multiple separate definitions, especially not when much of the macro
is the same between different configs.

This patch fixes this bad style, which had caused the Thumb2 code to
miss-out on the uaccess updates.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/kernel/entry-header.S

index 1a0045abead7562be1e27163e0aee3c6afbe9b40..d47b5161b029e12070888e63032249c44546c28b 100644 (file)
        msr     cpsr_c, \rtemp                  @ switch back to the SVC mode
        .endm
 
-#ifndef CONFIG_THUMB2_KERNEL
+
        .macro  svc_exit, rpsr, irq = 0
        .if     \irq != 0
        @ IRQs already off
        blne    trace_hardirqs_off
 #endif
        .endif
+
+#ifndef CONFIG_THUMB2_KERNEL
+       @ ARM mode SVC restore
        msr     spsr_cxsf, \rpsr
 #if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_32v6K)
        @ We must avoid clrex due to Cortex-A15 erratum #830321
        strex   r1, r2, [r0]                    @ clear the exclusive monitor
 #endif
        ldmia   sp, {r0 - pc}^                  @ load r0 - pc, cpsr
+#else
+       @ Thumb mode SVC restore
+       ldr     lr, [sp, #S_SP]                 @ top of the stack
+       ldrd    r0, r1, [sp, #S_LR]             @ calling lr and pc
+
+       @ We must avoid clrex due to Cortex-A15 erratum #830321
+       strex   r2, r1, [sp, #S_LR]             @ clear the exclusive monitor
+
+       stmdb   lr!, {r0, r1, \rpsr}            @ calling lr and rfe context
+       ldmia   sp, {r0 - r12}
+       mov     sp, lr
+       ldr     lr, [sp], #4
+       rfeia   sp!
+#endif
        .endm
 
        @
        @ on the stack remains correct).
        @
        .macro  svc_exit_via_fiq
+#ifndef CONFIG_THUMB2_KERNEL
+       @ ARM mode restore
        mov     r0, sp
        ldmib   r0, {r1 - r14}  @ abort is deadly from here onward (it will
                                @ clobber state restored below)
        msr     spsr_cxsf, r9
        ldr     r0, [r0, #S_R0]
        ldmia   r8, {pc}^
+#else
+       @ Thumb mode restore
+       add     r0, sp, #S_R2
+       ldr     lr, [sp, #S_LR]
+       ldr     sp, [sp, #S_SP] @ abort is deadly from here onward (it will
+                               @ clobber state restored below)
+       ldmia   r0, {r2 - r12}
+       mov     r1, #FIQ_MODE | PSR_I_BIT | PSR_F_BIT
+       msr     cpsr_c, r1
+       sub     r0, #S_R2
+       add     r8, r0, #S_PC
+       ldmia   r0, {r0 - r1}
+       rfeia   r8
+#endif
        .endm
 
+
        .macro  restore_user_regs, fast = 0, offset = 0
+#ifndef CONFIG_THUMB2_KERNEL
+       @ ARM mode restore
        mov     r2, sp
        ldr     r1, [r2, #\offset + S_PSR]      @ get calling cpsr
        ldr     lr, [r2, #\offset + S_PC]!      @ get pc
                                                @ after ldm {}^
        add     sp, sp, #\offset + S_FRAME_SIZE
        movs    pc, lr                          @ return & move spsr_svc into cpsr
-       .endm
-
-#else  /* CONFIG_THUMB2_KERNEL */
-       .macro  svc_exit, rpsr, irq = 0
-       .if     \irq != 0
-       @ IRQs already off
-#ifdef CONFIG_TRACE_IRQFLAGS
-       @ The parent context IRQs must have been enabled to get here in
-       @ the first place, so there's no point checking the PSR I bit.
-       bl      trace_hardirqs_on
-#endif
-       .else
-       @ IRQs off again before pulling preserved data off the stack
-       disable_irq_notrace
-#ifdef CONFIG_TRACE_IRQFLAGS
-       tst     \rpsr, #PSR_I_BIT
-       bleq    trace_hardirqs_on
-       tst     \rpsr, #PSR_I_BIT
-       blne    trace_hardirqs_off
-#endif
-       .endif
-       ldr     lr, [sp, #S_SP]                 @ top of the stack
-       ldrd    r0, r1, [sp, #S_LR]             @ calling lr and pc
-
-       @ We must avoid clrex due to Cortex-A15 erratum #830321
-       strex   r2, r1, [sp, #S_LR]             @ clear the exclusive monitor
-
-       stmdb   lr!, {r0, r1, \rpsr}            @ calling lr and rfe context
-       ldmia   sp, {r0 - r12}
-       mov     sp, lr
-       ldr     lr, [sp], #4
-       rfeia   sp!
-       .endm
-
-       @
-       @ svc_exit_via_fiq - like svc_exit but switches to FIQ mode before exit
-       @
-       @ For full details see non-Thumb implementation above.
-       @
-       .macro  svc_exit_via_fiq
-       add     r0, sp, #S_R2
-       ldr     lr, [sp, #S_LR]
-       ldr     sp, [sp, #S_SP] @ abort is deadly from here onward (it will
-                               @ clobber state restored below)
-       ldmia   r0, {r2 - r12}
-       mov     r1, #FIQ_MODE | PSR_I_BIT | PSR_F_BIT
-       msr     cpsr_c, r1
-       sub     r0, #S_R2
-       add     r8, r0, #S_PC
-       ldmia   r0, {r0 - r1}
-       rfeia   r8
-       .endm
-
-#ifdef CONFIG_CPU_V7M
-       /*
-        * Note we don't need to do clrex here as clearing the local monitor is
-        * part of each exception entry and exit sequence.
-        */
-       .macro  restore_user_regs, fast = 0, offset = 0
+#elif defined(CONFIG_CPU_V7M)
+       @ V7M restore.
+       @ Note that we don't need to do clrex here as clearing the local
+       @ monitor is part of the exception entry and exit sequence.
        .if     \offset
        add     sp, #\offset
        .endif
        v7m_exception_slow_exit ret_r0 = \fast
-       .endm
-#else  /* ifdef CONFIG_CPU_V7M */
-       .macro  restore_user_regs, fast = 0, offset = 0
+#else
+       @ Thumb mode restore
        mov     r2, sp
        load_user_sp_lr r2, r3, \offset + S_SP  @ calling sp, lr
        ldr     r1, [sp, #\offset + S_PSR]      @ get calling cpsr
        .endif
        add     sp, sp, #S_FRAME_SIZE - S_SP
        movs    pc, lr                          @ return & move spsr_svc into cpsr
-       .endm
-#endif /* ifdef CONFIG_CPU_V7M / else */
 #endif /* !CONFIG_THUMB2_KERNEL */
+       .endm
 
 /*
  * Context tracking subsystem.  Used to instrument transitions