Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6
[pandora-kernel.git] / arch / arm / kernel / entry-common.S
index 1b56082..8bfa987 100644 (file)
@@ -48,6 +48,8 @@ work_pending:
        beq     no_work_pending
        mov     r0, sp                          @ 'regs'
        mov     r2, why                         @ 'syscall'
+       tst     r1, #_TIF_SIGPENDING            @ delivering a signal?
+       movne   why, #0                         @ prevent further restarts
        bl      do_notify_resume
        b       ret_slow_syscall                @ Check work again
 
@@ -127,30 +129,58 @@ ENDPROC(ret_from_fork)
  * clobber the ip register.  This is OK because the ARM calling convention
  * allows it to be clobbered in subroutines and doesn't use it to hold
  * parameters.)
+ *
+ * When using dynamic ftrace, we patch out the mcount call by a "mov r0, r0"
+ * for the mcount case, and a "pop {lr}" for the __gnu_mcount_nc case (see
+ * arch/arm/kernel/ftrace.c).
  */
+
+#ifndef CONFIG_OLD_MCOUNT
+#if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4))
+#error Ftrace requires CONFIG_FRAME_POINTER=y with GCC older than 4.4.0.
+#endif
+#endif
+
 #ifdef CONFIG_DYNAMIC_FTRACE
-ENTRY(mcount)
+ENTRY(__gnu_mcount_nc)
+       mov     ip, lr
+       ldmia   sp!, {lr}
+       mov     pc, ip
+ENDPROC(__gnu_mcount_nc)
+
+ENTRY(ftrace_caller)
        stmdb   sp!, {r0-r3, lr}
        mov     r0, lr
        sub     r0, r0, #MCOUNT_INSN_SIZE
+       ldr     r1, [sp, #20]
 
-       .globl mcount_call
-mcount_call:
+       .global ftrace_call
+ftrace_call:
        bl      ftrace_stub
-       ldr     lr, [fp, #-4]                   @ restore lr
-       ldmia   sp!, {r0-r3, pc}
+       ldmia   sp!, {r0-r3, ip, lr}
+       mov     pc, ip
+ENDPROC(ftrace_caller)
 
-ENTRY(ftrace_caller)
+#ifdef CONFIG_OLD_MCOUNT
+ENTRY(mcount)
+       stmdb   sp!, {lr}
+       ldr     lr, [fp, #-4]
+       ldmia   sp!, {pc}
+ENDPROC(mcount)
+
+ENTRY(ftrace_caller_old)
        stmdb   sp!, {r0-r3, lr}
        ldr     r1, [fp, #-4]
        mov     r0, lr
        sub     r0, r0, #MCOUNT_INSN_SIZE
 
-       .globl ftrace_call
-ftrace_call:
+       .globl ftrace_call_old
+ftrace_call_old:
        bl      ftrace_stub
        ldr     lr, [fp, #-4]                   @ restore lr
        ldmia   sp!, {r0-r3, pc}
+ENDPROC(ftrace_caller_old)
+#endif
 
 #else
 
@@ -158,7 +188,7 @@ ENTRY(__gnu_mcount_nc)
        stmdb   sp!, {r0-r3, lr}
        ldr     r0, =ftrace_trace_function
        ldr     r2, [r0]
-       adr     r0, ftrace_stub
+       adr     r0, .Lftrace_stub
        cmp     r0, r2
        bne     gnu_trace
        ldmia   sp!, {r0-r3, ip, lr}
@@ -168,11 +198,19 @@ gnu_trace:
        ldr     r1, [sp, #20]                   @ lr of instrumented routine
        mov     r0, lr
        sub     r0, r0, #MCOUNT_INSN_SIZE
-       mov     lr, pc
+       adr     lr, BSYM(1f)
        mov     pc, r2
+1:
        ldmia   sp!, {r0-r3, ip, lr}
        mov     pc, ip
+ENDPROC(__gnu_mcount_nc)
 
+#ifdef CONFIG_OLD_MCOUNT
+/*
+ * This is under an ifdef in order to force link-time errors for people trying
+ * to build with !FRAME_POINTER with a GCC which doesn't use the new-style
+ * mcount.
+ */
 ENTRY(mcount)
        stmdb   sp!, {r0-r3, lr}
        ldr     r0, =ftrace_trace_function
@@ -191,12 +229,15 @@ trace:
        mov     pc, r2
        ldr     lr, [fp, #-4]                   @ restore lr
        ldmia   sp!, {r0-r3, pc}
+ENDPROC(mcount)
+#endif
 
 #endif /* CONFIG_DYNAMIC_FTRACE */
 
-       .globl ftrace_stub
-ftrace_stub:
+ENTRY(ftrace_stub)
+.Lftrace_stub:
        mov     pc, lr
+ENDPROC(ftrace_stub)
 
 #endif /* CONFIG_FUNCTION_TRACER */
 
@@ -293,7 +334,6 @@ ENTRY(vector_swi)
 
        get_thread_info tsk
        adr     tbl, sys_call_table             @ load syscall table pointer
-       ldr     ip, [tsk, #TI_FLAGS]            @ check for syscall tracing
 
 #if defined(CONFIG_OABI_COMPAT)
        /*
@@ -310,8 +350,20 @@ ENTRY(vector_swi)
        eor     scno, scno, #__NR_SYSCALL_BASE  @ check OS number
 #endif
 
+       ldr     r10, [tsk, #TI_FLAGS]           @ check for syscall tracing
        stmdb   sp!, {r4, r5}                   @ push fifth and sixth args
-       tst     ip, #_TIF_SYSCALL_TRACE         @ are we tracing syscalls?
+
+#ifdef CONFIG_SECCOMP
+       tst     r10, #_TIF_SECCOMP
+       beq     1f
+       mov     r0, scno
+       bl      __secure_computing      
+       add     r0, sp, #S_R0 + S_OFF           @ pointer to regs
+       ldmia   r0, {r0 - r3}                   @ have to reload r0 - r3
+1:
+#endif
+
+       tst     r10, #_TIF_SYSCALL_TRACE                @ are we tracing syscalls?
        bne     __sys_trace
 
        cmp     scno, #NR_syscalls              @ check upper syscall limit