lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [day] [month] [year] [list]
Date:	Fri, 30 May 2008 21:27:21 -0400
From:	Ulrich Drepper <drepper@...hat.com>
To:	linux-kernel@...r.kernel.org
Cc:	akpm@...ux-foundation.org, mtk.manpages@...il.com,
	torvalds@...ux-foundation.org
Subject: [PATCH 2/3] 64-bit futexes: x86-64 support

This patch adds 64-bit futex support for x86-64.  As can be seen, it consists
almost exclusively of the enablement for the FUTEX_WAKE_OP operation in the
form of new inline assembly code.  The magic to enable the 64-bit support is
the one little type definition in the types.h file.


 include/asm-x86/futex.h |   78 +++++++++++++++++++++++++++++++++++++++++++-----
 include/asm-x86/types.h |    5 +++
 2 files changed, 75 insertions(+), 8 deletions(-)


Signed-off-by: Ulrich Drepper <drepper@...hat.com>

diff -up linux-2.6/include/asm-x86/futex.h.b2 linux-2.6/include/asm-x86/futex.h
--- linux-2.6/include/asm-x86/futex.h.b2	2008-05-28 18:40:52.000000000 -0700
+++ linux-2.6/include/asm-x86/futex.h	2008-05-28 18:50:26.000000000 -0700
@@ -12,16 +12,23 @@
 #include <asm/system.h>
 
 #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg)	\
+  do {								\
+	u32 oldvaltemp;						\
 	asm volatile("1:\t" insn "\n"				\
 		     "2:\t.section .fixup,\"ax\"\n"		\
 		     "3:\tmov\t%3, %1\n"			\
 		     "\tjmp\t2b\n"				\
 		     "\t.previous\n"				\
 		     _ASM_EXTABLE(1b, 3b)			\
-		     : "=r" (oldval), "=r" (ret), "+m" (*uaddr)	\
-		     : "i" (-EFAULT), "0" (oparg), "1" (0))
+		     : "=r" (oldvaltemp), "=r" (ret),		\
+		       "+m" (*(u32 __user *) uaddr)		\
+		     : "i" (-EFAULT), "0" (oparg), "1" (0));	\
+	oldval = oldvaltemp;					\
+  } while (0)
 
 #define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg)	\
+  do {								\
+	u32 oldvaltemp;						\
 	asm volatile("1:\tmovl	%2, %0\n"			\
 		     "\tmovl\t%0, %3\n"				\
 		     "\t" insn "\n"				\
@@ -33,34 +40,67 @@
 		     "\t.previous\n"				\
 		     _ASM_EXTABLE(1b, 4b)			\
 		     _ASM_EXTABLE(2b, 4b)			\
+		     : "=&a" (oldvaltemp), "=&r" (ret),		\
+		       "+m" (*(u32 __user *) uaddr), "=&r" (tem)\
+		     : "r" (oparg), "i" (-EFAULT), "1" (0));	\
+	oldval = oldvaltemp;					\
+  } while (0)
+
+#ifndef CONFIG_X86_32
+#define __futex_atomic64_op1(insn, ret, oldval, uaddr, oparg)	\
+	asm volatile("1:\t" insn "\n"				\
+		     "2:\t.section .fixup,\"ax\"\n"		\
+		     "3:\tmov\t%3, %1\n"			\
+		     "\tjmp\t2b\n"				\
+		     "\t.previous\n"				\
+		     _ASM_EXTABLE(1b, 3b)			\
+		     : "=r" (oldval), "=r" (ret),		\
+		       "+m" (*(u32 __user *) uaddr)		\
+		     : "i" (-EFAULT), "0" (oparg), "1" (0))
+
+#define __futex_atomic64_op2(insn, ret, oldval, uaddr, oparg)	\
+	asm volatile("1:\tmovq	%q2, %q0\n"			\
+		     "\tmovq\t%q0, %q3\n"				\
+		     "\t" insn "\n"				\
+		     "2:\tlock; cmpxchgq %q3, %2\n"		\
+		     "\tjnz\t1b\n"				\
+		     "3:\t.section .fixup,\"ax\"\n"		\
+		     "4:\tmov\t%5, %1\n"			\
+		     "\tjmp\t3b\n"				\
+		     "\t.previous\n"				\
+		     _ASM_EXTABLE(1b, 4b)			\
+		     _ASM_EXTABLE(2b, 4b)			\
 		     : "=&a" (oldval), "=&r" (ret),		\
-		       "+m" (*uaddr), "=&r" (tem)		\
+		       "+m" (*(u64 __user *) uaddr), "=&r" (tem)\
 		     : "r" (oparg), "i" (-EFAULT), "1" (0))
+#endif
 
-static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr,
+static inline int futex_atomic_op_inuser(int encoded_op, void __user *uaddr,
 					 int flags)
 {
 	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, tem;
+	s64 oldval = 0;
+	int ret, tem;
 
 	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
 		oparg = 1 << oparg;
 
-	if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
+	if (!access_ok(VERIFY_WRITE, uaddr,
+		       FUTEX_64_P(flags) ? sizeof(u64) : sizeof(u32)))
 		return -EFAULT;
 
 #if defined(CONFIG_X86_32) && !defined(CONFIG_X86_BSWAP)
-	/* Real i386 machines can only support FUTEX_OP_SET */
+	/* Real i386 machines can only support 32-bit FUTEX_OP_SET */
 	if (op != FUTEX_OP_SET && boot_cpu_data.x86 == 3)
 		return -ENOSYS;
 #endif
 
 	pagefault_disable();
 
-	switch (op) {
+	switch (op | (FUTEX_64_P(flags) ? 8 : 0)) {
 	case FUTEX_OP_SET:
 		__futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
 		break;
@@ -77,6 +117,28 @@ static inline int futex_atomic_op_inuser
 	case FUTEX_OP_XOR:
 		__futex_atomic_op2("xorl %4, %3", ret, oldval, uaddr, oparg);
 		break;
+#ifndef CONFIG_X86_32
+	case FUTEX_OP64_SET:
+		__futex_atomic64_op1("xchgq %q0, %q2",
+				     ret, oldval, uaddr, oparg);
+		break;
+	case FUTEX_OP64_ADD:
+		__futex_atomic64_op1("lock; xaddq %q0, %q2", ret, oldval,
+				     uaddr, oparg);
+		break;
+	case FUTEX_OP64_OR:
+		__futex_atomic64_op2("orq %q4, %q3",
+				     ret, oldval, uaddr, oparg);
+		break;
+	case FUTEX_OP64_ANDN:
+		__futex_atomic64_op2("andq %q4, %q3",
+				     ret, oldval, uaddr, ~oparg);
+		break;
+	case FUTEX_OP64_XOR:
+		__futex_atomic64_op2("xorq %q4, %q3",
+				     ret, oldval, uaddr, oparg);
+		break;		
+#endif
 	default:
 		ret = -ENOSYS;
 	}
diff -up linux-2.6/include/asm-x86/types.h.b2 linux-2.6/include/asm-x86/types.h
--- linux-2.6/include/asm-x86/types.h.b2	2008-05-28 18:29:25.000000000 -0700
+++ linux-2.6/include/asm-x86/types.h	2008-05-28 18:45:20.000000000 -0700
@@ -30,6 +30,11 @@ typedef u64 dma_addr_t;
 typedef u32 dma_addr_t;
 #endif
 
+#ifdef CONFIG_X86_64
+typedef u64 futex_val_t;
+#define __have_futex_val_t
+#endif
+
 #endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ