diff options
author | Michel Lespinasse <walken@google.com> | 2011-03-10 21:48:51 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2011-03-11 06:23:08 -0500 |
commit | 37a9d912b24f96a0591773e6e6c3642991ae5a70 (patch) | |
tree | 5c4d5b9a52e2c533269e589115afbd25b6c8534b /arch/sparc | |
parent | 522d7decc0370070448a8c28982c8dfd8970489e (diff) |
futex: Sanitize cmpxchg_futex_value_locked API
The cmpxchg_futex_value_locked API was funny in that it returned either
the original, user-exposed futex value OR an error code such as -EFAULT.
This was confusing at best, and could be a source of livelocks in places
that retry the cmpxchg_futex_value_locked after trying to fix the issue
by running fault_in_user_writeable().
This change makes the cmpxchg_futex_value_locked API more similar to the
get_futex_value_locked one, returning an error code and updating the
original value through a reference argument.
Signed-off-by: Michel Lespinasse <walken@google.com>
Acked-by: Chris Metcalf <cmetcalf@tilera.com> [tile]
Acked-by: Tony Luck <tony.luck@intel.com> [ia64]
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Michal Simek <monstr@monstr.eu> [microblaze]
Acked-by: David Howells <dhowells@redhat.com> [frv]
Cc: Darren Hart <darren@dvhart.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Matt Turner <mattst88@gmail.com>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: "James E.J. Bottomley" <jejb@parisc-linux.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
LKML-Reference: <20110311024851.GC26122@google.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/sparc')
-rw-r--r-- | arch/sparc/include/asm/futex_64.h | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/arch/sparc/include/asm/futex_64.h b/arch/sparc/include/asm/futex_64.h index 47f95839dc69..e0862200d6a1 100644 --- a/arch/sparc/include/asm/futex_64.h +++ b/arch/sparc/include/asm/futex_64.h | |||
@@ -85,26 +85,30 @@ static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr) | |||
85 | } | 85 | } |
86 | 86 | ||
87 | static inline int | 87 | static inline int |
88 | futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) | 88 | futex_atomic_cmpxchg_inatomic(int *uval, int __user *uaddr, |
89 | int oldval, int newval) | ||
89 | { | 90 | { |
91 | int ret = 0; | ||
92 | |||
90 | __asm__ __volatile__( | 93 | __asm__ __volatile__( |
91 | "\n1: casa [%3] %%asi, %2, %0\n" | 94 | "\n1: casa [%4] %%asi, %3, %1\n" |
92 | "2:\n" | 95 | "2:\n" |
93 | " .section .fixup,#alloc,#execinstr\n" | 96 | " .section .fixup,#alloc,#execinstr\n" |
94 | " .align 4\n" | 97 | " .align 4\n" |
95 | "3: sethi %%hi(2b), %0\n" | 98 | "3: sethi %%hi(2b), %0\n" |
96 | " jmpl %0 + %%lo(2b), %%g0\n" | 99 | " jmpl %0 + %%lo(2b), %%g0\n" |
97 | " mov %4, %0\n" | 100 | " mov %5, %0\n" |
98 | " .previous\n" | 101 | " .previous\n" |
99 | " .section __ex_table,\"a\"\n" | 102 | " .section __ex_table,\"a\"\n" |
100 | " .align 4\n" | 103 | " .align 4\n" |
101 | " .word 1b, 3b\n" | 104 | " .word 1b, 3b\n" |
102 | " .previous\n" | 105 | " .previous\n" |
103 | : "=r" (newval) | 106 | : "+r" (ret), "=r" (newval) |
104 | : "0" (newval), "r" (oldval), "r" (uaddr), "i" (-EFAULT) | 107 | : "1" (newval), "r" (oldval), "r" (uaddr), "i" (-EFAULT) |
105 | : "memory"); | 108 | : "memory"); |
106 | 109 | ||
107 | return newval; | 110 | *uval = newval; |
111 | return ret; | ||
108 | } | 112 | } |
109 | 113 | ||
110 | #endif /* !(_SPARC64_FUTEX_H) */ | 114 | #endif /* !(_SPARC64_FUTEX_H) */ |