Merge branch 'mv-merge'
[powerpc.git] / arch / arm / kernel / entry-armv.S
index fb8e7f4..355914f 100644 (file)
@@ -105,14 +105,24 @@ common_invalid:
 /*
  * SVC mode handlers
  */
+
+#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5)
+#define SPFIX(code...) code
+#else
+#define SPFIX(code...)
+#endif
+
        .macro  svc_entry
        sub     sp, sp, #S_FRAME_SIZE
+ SPFIX(        tst     sp, #4          )
+ SPFIX(        bicne   sp, sp, #4      )
        stmib   sp, {r1 - r12}
 
        ldmia   r0, {r1 - r3}
        add     r5, sp, #S_SP           @ here for interlock avoidance
        mov     r4, #-1                 @  ""  ""      ""       ""
        add     r0, sp, #S_FRAME_SIZE   @  ""  ""      ""       ""
+ SPFIX(        addne   r0, r0, #4      )
        str     r1, [sp]                @ save the "real" r0 copied
                                        @ from the exception stack
 
@@ -303,7 +313,14 @@ __pabt_svc:
 
 /*
  * User mode handlers
+ *
+ * EABI note: sp_svc is always 64-bit aligned here, so should S_FRAME_SIZE
  */
+
+#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5) && (S_FRAME_SIZE & 7)
+#error "sizeof(struct pt_regs) must be a multiple of 8"
+#endif
+
        .macro  usr_entry
        sub     sp, sp, #S_FRAME_SIZE
        stmib   sp, {r1 - r12}
@@ -316,9 +333,13 @@ __pabt_svc:
                                        @ from the exception stack
 
 #if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
+#ifndef CONFIG_MMU
+#warning "NPTL on non MMU needs fixing"
+#else
        @ make sure our user space atomic helper is aborted
        cmp     r2, #TASK_SIZE
        bichs   r3, r3, #PSR_Z_BIT
+#endif
 #endif
 
        @
@@ -463,7 +484,6 @@ call_fpe:
        movcss  r7, r5, lsr #(TIF_USING_IWMMXT + 1)
        bcs     iwmmxt_task_enable
 #endif
-       enable_irq
        add     pc, pc, r8, lsr #6
        mov     r0, r0
 
@@ -490,6 +510,7 @@ call_fpe:
        mov     pc, lr                          @ CP#15 (Control)
 
 do_fpe:
+       enable_irq
        ldr     r4, .LCfp
        add     r10, r10, #TI_FPSTATE           @ r10 = workspace
        ldr     pc, [r4]                        @ Call FP module USR entry point
@@ -545,7 +566,7 @@ ENTRY(__switch_to)
        ldr     r6, [r2, #TI_CPU_DOMAIN]!
 #endif
 #if __LINUX_ARM_ARCH__ >= 6
-#ifdef CONFIG_CPU_MPCORE
+#ifdef CONFIG_CPU_32v6K
        clrex
 #else
        strex   r5, r4, [ip]                    @ Clear exclusive monitor
@@ -688,7 +709,12 @@ __kuser_memory_barrier:                            @ 0xffff0fa0
  * The C flag is also set if *ptr was changed to allow for assembly
  * optimization in the calling code.
  *
- * Note: this routine already includes memory barriers as needed.
+ * Notes:
+ *
+ *    - This routine already includes memory barriers as needed.
+ *
+ *    - A failure might be transient, i.e. it is possible, although unlikely,
+ *      that "failure" be returned even if *ptr == oldval.
  *
  * For example, a user space atomic_add implementation could look like this:
  *
@@ -718,8 +744,11 @@ __kuser_cmpxchg:                           @ 0xffff0fc0
         * The kernel itself must perform the operation.
         * A special ghost syscall is used for that (see traps.c).
         */
+       stmfd   sp!, {r7, lr}
+       mov     r7, #0xff00             @ 0xfff0 into r7 for EABI
+       orr     r7, r7, #0xf0
        swi     #0x9ffff0
-       mov     pc, lr
+       ldmfd   sp!, {r7, pc}
 
 #elif __LINUX_ARM_ARCH__ < 6
 
@@ -736,12 +765,18 @@ __kuser_cmpxchg:                          @ 0xffff0fc0
         * exception happening just after the str instruction which would
         * clear the Z flag although the exchange was done.
         */
+#ifdef CONFIG_MMU
        teq     ip, ip                  @ set Z flag
        ldr     ip, [r2]                @ load current val
        add     r3, r2, #1              @ prepare store ptr
        teqeq   ip, r0                  @ compare with oldval if still allowed
        streq   r1, [r3, #-1]!          @ store newval if still allowed
        subs    r0, r2, r3              @ if r2 == r3 the str occured
+#else
+#warning "NPTL on non MMU needs fixing"
+       mov     r0, #-1
+       adds    r0, r0, #0
+#endif
        mov     pc, lr
 
 #else