[PATCH] powerpc: Merge futex.h
authorDavid Gibson <david@gibson.dropbear.id.au>
Wed, 2 Nov 2005 02:58:22 +0000 (13:58 +1100)
committerPaul Mackerras <paulus@samba.org>
Wed, 2 Nov 2005 03:48:18 +0000 (14:48 +1100)
This patch merges the ppc32 and ppc64 versions of futex.h, essentially
by taking the ppc64 version as the powerpc version.  The old ppc32
version did not implement the futex_atomic_op_inuser() callback (it
always returned -ENOSYS), so FUTEX_WAKE_OP would not work on ppc32.
In fact the ppc64 version of this function is almost suitable for
ppc32 as well - the only change needed is to extend ppc_asm.h with a
macro expanding to to the right pseudo-op to store a pointer (either
".long" or ".llong").

Built and booted on pSeries.  Built for 32-bit powermac.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Paul Mackerras <paulus@samba.org>
include/asm-powerpc/futex.h [new file with mode: 0644]
include/asm-powerpc/ppc_asm.h
include/asm-ppc/futex.h [deleted file]
include/asm-ppc64/futex.h [deleted file]

diff --git a/include/asm-powerpc/futex.h b/include/asm-powerpc/futex.h
new file mode 100644 (file)
index 0000000..37c94e5
--- /dev/null
@@ -0,0 +1,84 @@
+#ifndef _ASM_POWERPC_FUTEX_H
+#define _ASM_POWERPC_FUTEX_H
+
+#ifdef __KERNEL__
+
+#include <linux/futex.h>
+#include <asm/errno.h>
+#include <asm/synch.h>
+#include <asm/uaccess.h>
+#include <asm/ppc_asm.h>
+
+#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
+  __asm__ __volatile ( \
+       SYNC_ON_SMP \
+"1:    lwarx   %0,0,%2\n" \
+       insn \
+"2:    stwcx.  %1,0,%2\n" \
+       "bne-   1b\n" \
+       "li     %1,0\n" \
+"3:    .section .fixup,\"ax\"\n" \
+"4:    li      %1,%3\n" \
+       "b      3b\n" \
+       ".previous\n" \
+       ".section __ex_table,\"a\"\n" \
+       ".align 3\n" \
+       DATAL " 1b,4b,2b,4b\n" \
+       ".previous" \
+       : "=&r" (oldval), "=&r" (ret) \
+       : "b" (uaddr), "i" (-EFAULT), "1" (oparg) \
+       : "cr0", "memory")
+
+static inline int futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
+{
+       int op = (encoded_op >> 28) & 7;
+       int cmp = (encoded_op >> 24) & 15;
+       int oparg = (encoded_op << 8) >> 20;
+       int cmparg = (encoded_op << 20) >> 20;
+       int oldval = 0, ret;
+       if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
+               oparg = 1 << oparg;
+
+       if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
+               return -EFAULT;
+
+       inc_preempt_count();
+
+       switch (op) {
+       case FUTEX_OP_SET:
+               __futex_atomic_op("", ret, oldval, uaddr, oparg);
+               break;
+       case FUTEX_OP_ADD:
+               __futex_atomic_op("add %1,%0,%1\n", ret, oldval, uaddr, oparg);
+               break;
+       case FUTEX_OP_OR:
+               __futex_atomic_op("or %1,%0,%1\n", ret, oldval, uaddr, oparg);
+               break;
+       case FUTEX_OP_ANDN:
+               __futex_atomic_op("andc %1,%0,%1\n", ret, oldval, uaddr, oparg);
+               break;
+       case FUTEX_OP_XOR:
+               __futex_atomic_op("xor %1,%0,%1\n", ret, oldval, uaddr, oparg);
+               break;
+       default:
+               ret = -ENOSYS;
+       }
+
+       dec_preempt_count();
+
+       if (!ret) {
+               switch (cmp) {
+               case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
+               case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
+               case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
+               case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
+               case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
+               case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
+               default: ret = -ENOSYS;
+               }
+       }
+       return ret;
+}
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_FUTEX_H */
index f99f2af82ca564fb9377d5cd5cdb70be70d12887..c534ca41224b6cea93d31fd29fdba6445da5dcbc 100644 (file)
@@ -506,6 +506,13 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
 #else
   #define __ASM_CONST(x) x##UL
   #define ASM_CONST(x) __ASM_CONST(x)
+
+#ifdef CONFIG_PPC64
+#define DATAL  ".llong"
+#else
+#define DATAL  ".long"
+#endif
+
 #endif /*  __ASSEMBLY__ */
 
 #endif /* _ASM_POWERPC_PPC_ASM_H */
diff --git a/include/asm-ppc/futex.h b/include/asm-ppc/futex.h
deleted file mode 100644 (file)
index 9feff4c..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef _ASM_FUTEX_H
-#define _ASM_FUTEX_H
-
-#ifdef __KERNEL__
-
-#include <linux/futex.h>
-#include <asm/errno.h>
-#include <asm/uaccess.h>
-
-static inline int
-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
-{
-       int op = (encoded_op >> 28) & 7;
-       int cmp = (encoded_op >> 24) & 15;
-       int oparg = (encoded_op << 8) >> 20;
-       int cmparg = (encoded_op << 20) >> 20;
-       int oldval = 0, ret;
-       if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
-               oparg = 1 << oparg;
-
-       if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
-               return -EFAULT;
-
-       inc_preempt_count();
-
-       switch (op) {
-       case FUTEX_OP_SET:
-       case FUTEX_OP_ADD:
-       case FUTEX_OP_OR:
-       case FUTEX_OP_ANDN:
-       case FUTEX_OP_XOR:
-       default:
-               ret = -ENOSYS;
-       }
-
-       dec_preempt_count();
-
-       if (!ret) {
-               switch (cmp) {
-               case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
-               case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
-               case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
-               case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
-               case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
-               case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
-               default: ret = -ENOSYS;
-               }
-       }
-       return ret;
-}
-
-#endif
-#endif
diff --git a/include/asm-ppc64/futex.h b/include/asm-ppc64/futex.h
deleted file mode 100644 (file)
index 266b460..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-#ifndef _ASM_FUTEX_H
-#define _ASM_FUTEX_H
-
-#ifdef __KERNEL__
-
-#include <linux/futex.h>
-#include <asm/errno.h>
-#include <asm/synch.h>
-#include <asm/uaccess.h>
-
-#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
-  __asm__ __volatile (SYNC_ON_SMP                              \
-"1:    lwarx   %0,0,%2\n"                                      \
-       insn                                                    \
-"2:    stwcx.  %1,0,%2\n\
-       bne-    1b\n\
-       li      %1,0\n\
-3:     .section .fixup,\"ax\"\n\
-4:     li      %1,%3\n\
-       b       3b\n\
-       .previous\n\
-       .section __ex_table,\"a\"\n\
-       .align 3\n\
-       .llong  1b,4b,2b,4b\n\
-       .previous"                                              \
-       : "=&r" (oldval), "=&r" (ret)                           \
-       : "b" (uaddr), "i" (-EFAULT), "1" (oparg)               \
-       : "cr0", "memory")
-
-static inline int
-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
-{
-       int op = (encoded_op >> 28) & 7;
-       int cmp = (encoded_op >> 24) & 15;
-       int oparg = (encoded_op << 8) >> 20;
-       int cmparg = (encoded_op << 20) >> 20;
-       int oldval = 0, ret;
-       if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
-               oparg = 1 << oparg;
-
-       if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
-               return -EFAULT;
-
-       inc_preempt_count();
-
-       switch (op) {
-       case FUTEX_OP_SET:
-               __futex_atomic_op("", ret, oldval, uaddr, oparg);
-               break;
-       case FUTEX_OP_ADD:
-               __futex_atomic_op("add %1,%0,%1\n", ret, oldval, uaddr, oparg);
-               break;
-       case FUTEX_OP_OR:
-               __futex_atomic_op("or %1,%0,%1\n", ret, oldval, uaddr, oparg);
-               break;
-       case FUTEX_OP_ANDN:
-               __futex_atomic_op("andc %1,%0,%1\n", ret, oldval, uaddr, oparg);
-               break;
-       case FUTEX_OP_XOR:
-               __futex_atomic_op("xor %1,%0,%1\n", ret, oldval, uaddr, oparg);
-               break;
-       default:
-               ret = -ENOSYS;
-       }
-
-       dec_preempt_count();
-
-       if (!ret) {
-               switch (cmp) {
-               case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
-               case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
-               case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
-               case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
-               case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
-               case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
-               default: ret = -ENOSYS;
-               }
-       }
-       return ret;
-}
-
-#endif
-#endif