mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 11:41:38 -04:00
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 <[email protected]>
Acked-by: Chris Metcalf <[email protected]> [tile]
Acked-by: Tony Luck <[email protected]> [ia64]
Acked-by: Thomas Gleixner <[email protected]>
Tested-by: Michal Simek <[email protected]> [microblaze]
Acked-by: David Howells <[email protected]> [frv]
Cc: Darren Hart <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Matt Turner <[email protected]>
Cc: Russell King <[email protected]>
Cc: Ralf Baechle <[email protected]>
Cc: "James E.J. Bottomley" <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Martin Schwidefsky <[email protected]>
Cc: Paul Mundt <[email protected]>
Cc: "David S. Miller" <[email protected]>
Cc: Linus Torvalds <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
This commit is contained in:
parent
522d7decc0
commit
37a9d912b2
20 changed files with 144 additions and 132 deletions
|
|
@ -81,21 +81,22 @@ static inline int futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
|
|||
}
|
||||
|
||||
static inline int
|
||||
futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
|
||||
futex_atomic_cmpxchg_inatomic(int *uval, int __user *uaddr,
|
||||
int oldval, int newval)
|
||||
{
|
||||
int prev, cmp;
|
||||
int ret = 0, prev, cmp;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
|
||||
return -EFAULT;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
__ASM_SMP_MB
|
||||
"1: ldl_l %0,0(%2)\n"
|
||||
" cmpeq %0,%3,%1\n"
|
||||
" beq %1,3f\n"
|
||||
" mov %4,%1\n"
|
||||
"2: stl_c %1,0(%2)\n"
|
||||
" beq %1,4f\n"
|
||||
"1: ldl_l %1,0(%3)\n"
|
||||
" cmpeq %1,%4,%2\n"
|
||||
" beq %2,3f\n"
|
||||
" mov %5,%2\n"
|
||||
"2: stl_c %2,0(%3)\n"
|
||||
" beq %2,4f\n"
|
||||
"3: .subsection 2\n"
|
||||
"4: br 1b\n"
|
||||
" .previous\n"
|
||||
|
|
@ -105,11 +106,12 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
|
|||
" .long 2b-.\n"
|
||||
" lda $31,3b-2b(%0)\n"
|
||||
" .previous\n"
|
||||
: "=&r"(prev), "=&r"(cmp)
|
||||
: "+r"(ret), "=&r"(prev), "=&r"(cmp)
|
||||
: "r"(uaddr), "r"((long)oldval), "r"(newval)
|
||||
: "memory");
|
||||
|
||||
return prev;
|
||||
*uval = prev;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
|
|
|||
Loading…
Reference in a new issue