powerpc: Merge futex.h

David Gibson david at gibson.dropbear.id.au
Wed Nov 2 13:58:22 EST 2005


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 at gibson.dropbear.id.au>

Index: working-2.6/include/asm-powerpc/futex.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ working-2.6/include/asm-powerpc/futex.h	2005-11-02 13:43:08.000000000 +1100
@@ -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: working-2.6/include/asm-ppc/futex.h
===================================================================
--- working-2.6.orig/include/asm-ppc/futex.h	2005-10-25 11:59:59.000000000 +1000
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -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
Index: working-2.6/include/asm-ppc64/futex.h
===================================================================
--- working-2.6.orig/include/asm-ppc64/futex.h	2005-10-31 15:20:22.000000000 +1100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -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
Index: working-2.6/include/asm-powerpc/ppc_asm.h
===================================================================
--- working-2.6.orig/include/asm-powerpc/ppc_asm.h	2005-10-31 15:20:57.000000000 +1100
+++ working-2.6/include/asm-powerpc/ppc_asm.h	2005-11-02 13:48:08.000000000 +1100
@@ -506,6 +506,13 @@
 #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 */

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/people/dgibson



More information about the Linuxppc64-dev mailing list