Skip to content

Commit

Permalink
Merge branch 'core-futexes-for-linus' of git://git.kernel.org/pub/scm…
Browse files Browse the repository at this point in the history
…/linux/kernel/git/tip/linux-2.6-tip

* 'core-futexes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  arm: Remove bogus comment in futex_atomic_cmpxchg_inatomic()
  futex: Deobfuscate handle_futex_death()
  plist: Add priority list test
  plist: Shrink struct plist_head
  futex,plist: Remove debug lock assignment from plist_node
  futex,plist: Pass the real head of the priority list to plist_del()
  futex: Sanitize futex ops argument types
  futex: Sanitize cmpxchg_futex_value_locked API
  futex: Remove redundant pagefault_disable in futex_atomic_cmpxchg_inatomic()
  futex: Avoid redudant evaluation of task_pid_vnr()
  futex: Update futex_wait_setup comments about locking
  • Loading branch information
torvalds committed Mar 16, 2011
2 parents c345f60 + 07d5eca commit b80cd62
Show file tree
Hide file tree
Showing 23 changed files with 404 additions and 276 deletions.
29 changes: 16 additions & 13 deletions arch/alpha/include/asm/futex.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
: "r" (uaddr), "r"(oparg) \
: "memory")

static inline int futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
{
int op = (encoded_op >> 28) & 7;
int cmp = (encoded_op >> 24) & 15;
Expand All @@ -39,7 +39,7 @@ static inline int futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
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, sizeof(u32)))
return -EFAULT;

pagefault_disable();
Expand Down Expand Up @@ -81,21 +81,23 @@ 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(u32 *uval, u32 __user *uaddr,
u32 oldval, u32 newval)
{
int prev, cmp;
int ret = 0, cmp;
u32 prev;

if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
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"
Expand All @@ -105,11 +107,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__ */
Expand Down
29 changes: 14 additions & 15 deletions arch/arm/include/asm/futex.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
: "cc", "memory")

static inline int
futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
{
int op = (encoded_op >> 28) & 7;
int cmp = (encoded_op >> 24) & 15;
Expand All @@ -46,7 +46,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
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, sizeof(u32)))
return -EFAULT;

pagefault_disable(); /* implies preempt_disable() */
Expand Down Expand Up @@ -88,36 +88,35 @@ 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(u32 *uval, u32 __user *uaddr,
u32 oldval, u32 newval)
{
int val;
int ret = 0;
u32 val;

if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
return -EFAULT;

pagefault_disable(); /* implies preempt_disable() */

__asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
"1: " T(ldr) " %0, [%3]\n"
" teq %0, %1\n"
"1: " T(ldr) " %1, [%4]\n"
" teq %1, %2\n"
" it eq @ explicit IT needed for the 2b label\n"
"2: " T(streq) " %2, [%3]\n"
"2: " T(streq) " %3, [%4]\n"
"3:\n"
" .pushsection __ex_table,\"a\"\n"
" .align 3\n"
" .long 1b, 4f, 2b, 4f\n"
" .popsection\n"
" .pushsection .fixup,\"ax\"\n"
"4: mov %0, %4\n"
"4: mov %0, %5\n"
" b 3b\n"
" .popsection"
: "=&r" (val)
: "+r" (ret), "=&r" (val)
: "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT)
: "cc", "memory");

pagefault_enable(); /* subsumes preempt_enable() */

return val;
*uval = val;
return ret;
}

#endif /* !SMP */
Expand Down
5 changes: 3 additions & 2 deletions arch/frv/include/asm/futex.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@
#include <asm/errno.h>
#include <asm/uaccess.h>

extern int futex_atomic_op_inuser(int encoded_op, int __user *uaddr);
extern int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr);

static inline int
futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
u32 oldval, u32 newval)
{
return -ENOSYS;
}
Expand Down
14 changes: 7 additions & 7 deletions arch/frv/kernel/futex.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* the various futex operations; MMU fault checking is ignored under no-MMU
* conditions
*/
static inline int atomic_futex_op_xchg_set(int oparg, int __user *uaddr, int *_oldval)
static inline int atomic_futex_op_xchg_set(int oparg, u32 __user *uaddr, int *_oldval)
{
int oldval, ret;

Expand Down Expand Up @@ -50,7 +50,7 @@ static inline int atomic_futex_op_xchg_set(int oparg, int __user *uaddr, int *_o
return ret;
}

static inline int atomic_futex_op_xchg_add(int oparg, int __user *uaddr, int *_oldval)
static inline int atomic_futex_op_xchg_add(int oparg, u32 __user *uaddr, int *_oldval)
{
int oldval, ret;

Expand Down Expand Up @@ -83,7 +83,7 @@ static inline int atomic_futex_op_xchg_add(int oparg, int __user *uaddr, int *_o
return ret;
}

static inline int atomic_futex_op_xchg_or(int oparg, int __user *uaddr, int *_oldval)
static inline int atomic_futex_op_xchg_or(int oparg, u32 __user *uaddr, int *_oldval)
{
int oldval, ret;

Expand Down Expand Up @@ -116,7 +116,7 @@ static inline int atomic_futex_op_xchg_or(int oparg, int __user *uaddr, int *_ol
return ret;
}

static inline int atomic_futex_op_xchg_and(int oparg, int __user *uaddr, int *_oldval)
static inline int atomic_futex_op_xchg_and(int oparg, u32 __user *uaddr, int *_oldval)
{
int oldval, ret;

Expand Down Expand Up @@ -149,7 +149,7 @@ static inline int atomic_futex_op_xchg_and(int oparg, int __user *uaddr, int *_o
return ret;
}

static inline int atomic_futex_op_xchg_xor(int oparg, int __user *uaddr, int *_oldval)
static inline int atomic_futex_op_xchg_xor(int oparg, u32 __user *uaddr, int *_oldval)
{
int oldval, ret;

Expand Down Expand Up @@ -186,7 +186,7 @@ static inline int atomic_futex_op_xchg_xor(int oparg, int __user *uaddr, int *_o
/*
* do the futex operations
*/
int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
{
int op = (encoded_op >> 28) & 7;
int cmp = (encoded_op >> 24) & 15;
Expand All @@ -197,7 +197,7 @@ int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
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, sizeof(u32)))
return -EFAULT;

pagefault_disable();
Expand Down
15 changes: 9 additions & 6 deletions arch/ia64/include/asm/futex.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ do { \
} while (0)

static inline int
futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
{
int op = (encoded_op >> 28) & 7;
int cmp = (encoded_op >> 24) & 15;
Expand All @@ -56,7 +56,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
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, sizeof(u32)))
return -EFAULT;

pagefault_disable();
Expand Down Expand Up @@ -100,23 +100,26 @@ 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(u32 *uval, u32 __user *uaddr,
u32 oldval, u32 newval)
{
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
return -EFAULT;

{
register unsigned long r8 __asm ("r8");
register unsigned long r8 __asm ("r8") = 0;
unsigned long prev;
__asm__ __volatile__(
" mf;; \n"
" mov ar.ccv=%3;; \n"
"[1:] cmpxchg4.acq %0=[%1],%2,ar.ccv \n"
" .xdata4 \"__ex_table\", 1b-., 2f-. \n"
"[2:]"
: "=r" (r8)
: "=r" (prev)
: "r" (uaddr), "r" (newval),
"rO" ((long) (unsigned) oldval)
: "memory");
*uval = prev;
return r8;
}
}
Expand Down
31 changes: 17 additions & 14 deletions arch/microblaze/include/asm/futex.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
})

static inline int
futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
{
int op = (encoded_op >> 28) & 7;
int cmp = (encoded_op >> 24) & 15;
Expand All @@ -39,7 +39,7 @@ futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
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, sizeof(u32)))
return -EFAULT;

pagefault_disable();
Expand Down Expand Up @@ -94,31 +94,34 @@ 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(u32 *uval, u32 __user *uaddr,
u32 oldval, u32 newval)
{
int prev, cmp;
int ret = 0, cmp;
u32 prev;

if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
return -EFAULT;

__asm__ __volatile__ ("1: lwx %0, %2, r0; \
cmp %1, %0, %3; \
beqi %1, 3f; \
2: swx %4, %2, r0; \
addic %1, r0, 0; \
bnei %1, 1b; \
__asm__ __volatile__ ("1: lwx %1, %3, r0; \
cmp %2, %1, %4; \
beqi %2, 3f; \
2: swx %5, %3, r0; \
addic %2, r0, 0; \
bnei %2, 1b; \
3: \
.section .fixup,\"ax\"; \
4: brid 3b; \
addik %0, r0, %5; \
addik %0, r0, %6; \
.previous; \
.section __ex_table,\"a\"; \
.word 1b,4b,2b,4b; \
.previous;" \
: "=&r" (prev), "=&r"(cmp) \
: "+r" (ret), "=&r" (prev), "=&r"(cmp) \
: "r" (uaddr), "r" (oldval), "r" (newval), "i" (-EFAULT));

return prev;
*uval = prev;
return ret;
}

#endif /* __KERNEL__ */
Expand Down
Loading

0 comments on commit b80cd62

Please sign in to comment.