]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - include/asm-powerpc/futex.h
[NETFILTER]: ipt annotations
[linux-2.6-omap-h63xx.git] / include / asm-powerpc / futex.h
index 37c94e52ab6dd6a5bb0d41bbdfb2a2082479e0b5..936422e54891f0cab44229639f8321e9d47a270e 100644 (file)
@@ -7,13 +7,14 @@
 #include <asm/errno.h>
 #include <asm/synch.h>
 #include <asm/uaccess.h>
-#include <asm/ppc_asm.h>
+#include <asm/asm-compat.h>
 
 #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
   __asm__ __volatile ( \
-       SYNC_ON_SMP \
+       LWSYNC_ON_SMP \
 "1:    lwarx   %0,0,%2\n" \
        insn \
+       PPC405_ERR77(0, %2) \
 "2:    stwcx.  %1,0,%2\n" \
        "bne-   1b\n" \
        "li     %1,0\n" \
@@ -23,7 +24,7 @@
        ".previous\n" \
        ".section __ex_table,\"a\"\n" \
        ".align 3\n" \
-       DATAL " 1b,4b,2b,4b\n" \
+       PPC_LONG "1b,4b,2b,4b\n" \
        ".previous" \
        : "=&r" (oldval), "=&r" (ret) \
        : "b" (uaddr), "i" (-EFAULT), "1" (oparg) \
@@ -80,5 +81,37 @@ static inline int futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
        return ret;
 }
 
+static inline int
+futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
+{
+       int prev;
+
+       if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
+               return -EFAULT;
+
+        __asm__ __volatile__ (
+        LWSYNC_ON_SMP
+"1:     lwarx   %0,0,%2         # futex_atomic_cmpxchg_inatomic\n\
+        cmpw    0,%0,%3\n\
+        bne-    3f\n"
+        PPC405_ERR77(0,%2)
+"2:     stwcx.  %4,0,%2\n\
+        bne-    1b\n"
+        ISYNC_ON_SMP
+"3:    .section .fixup,\"ax\"\n\
+4:     li      %0,%5\n\
+       b       3b\n\
+       .previous\n\
+       .section __ex_table,\"a\"\n\
+       .align 3\n\
+       " PPC_LONG "1b,4b,2b,4b\n\
+       .previous" \
+        : "=&r" (prev), "+m" (*uaddr)
+        : "r" (uaddr), "r" (oldval), "r" (newval), "i" (-EFAULT)
+        : "cc", "memory");
+
+        return prev;
+}
+
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_FUTEX_H */