]> err.no Git - linux-2.6/blobdiff - arch/arm/kernel/entry-armv.S
Merge /spare/repo/linux-2.6/
[linux-2.6] / arch / arm / kernel / entry-armv.S
index 78cf84cdc2ae84de914a17f078402fc91b18ceeb..7152bfbee581ea4fa83769bd323564a6249782f7 100644 (file)
@@ -308,7 +308,7 @@ __pabt_svc:
        str     r1, [sp]                @ save the "real" r0 copied
                                        @ from the exception stack
 
-#if __LINUX_ARM_ARCH__ < 6
+#if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
        @ make sure our user space atomic helper is aborted
        cmp     r2, #VIRT_OFFSET
        bichs   r3, r3, #PSR_Z_BIT
@@ -533,6 +533,13 @@ ENTRY(__switch_to)
        ldr     r3, [r2, #TI_TP_VALUE]
        stmia   ip!, {r4 - sl, fp, sp, lr}      @ Store most regs on stack
        ldr     r6, [r2, #TI_CPU_DOMAIN]!
+#if __LINUX_ARM_ARCH__ >= 6
+#ifdef CONFIG_CPU_MPCORE
+       clrex
+#else
+       strex   r3, r4, [ip]                    @ Clear exclusive monitor
+#endif
+#endif
 #if defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_IWMMXT)
        mra     r4, r5, acc0
        stmia   ip, {r4, r5}
@@ -648,11 +655,17 @@ __kuser_helper_start:
 
 __kuser_cmpxchg:                               @ 0xffff0fc0
 
-#if __LINUX_ARM_ARCH__ < 6
+#if defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
 
-#ifdef CONFIG_SMP  /* sanity check */
-#error "CONFIG_SMP on a machine supporting pre-ARMv6 processors?"
-#endif
+       /*
+        * Poor you.  No fast solution possible...
+        * The kernel itself must perform the operation.
+        * A special ghost syscall is used for that (see traps.c).
+        */
+       swi     #0x9ffff0
+       mov     pc, lr
+
+#elif __LINUX_ARM_ARCH__ < 6
 
        /*
         * Theory of operation: