parisc: Update futex.h to match generic implementation

The attached patch updates the parisc version of futex.h to match the
current generic implementation except for the spinlock code.

Signed-off-by: John David Anglin <dave.anglin@bell.net>
Signed-off-by: Helge Deller <deller@gmx.de>
This commit is contained in:
John David Anglin 2016-05-21 15:03:54 -04:00 committed by Helge Deller
parent 4df3c9ec12
commit 99aed91a8d

View file

@ -35,70 +35,57 @@ static inline int
futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
{ {
unsigned long int flags; unsigned long int flags;
u32 val;
int op = (encoded_op >> 28) & 7; int op = (encoded_op >> 28) & 7;
int cmp = (encoded_op >> 24) & 15; int cmp = (encoded_op >> 24) & 15;
int oparg = (encoded_op << 8) >> 20; int oparg = (encoded_op << 8) >> 20;
int cmparg = (encoded_op << 20) >> 20; int cmparg = (encoded_op << 20) >> 20;
int oldval = 0, ret; int oldval, ret;
u32 tmp;
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg; oparg = 1 << oparg;
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(*uaddr))) if (!access_ok(VERIFY_WRITE, uaddr, sizeof(*uaddr)))
return -EFAULT; return -EFAULT;
_futex_spin_lock_irqsave(uaddr, &flags);
pagefault_disable(); pagefault_disable();
_futex_spin_lock_irqsave(uaddr, &flags); ret = -EFAULT;
if (unlikely(get_user(oldval, uaddr) != 0))
goto out_pagefault_enable;
ret = 0;
tmp = oldval;
switch (op) { switch (op) {
case FUTEX_OP_SET: case FUTEX_OP_SET:
/* *(int *)UADDR2 = OPARG; */ tmp = oparg;
ret = get_user(oldval, uaddr);
if (!ret)
ret = put_user(oparg, uaddr);
break; break;
case FUTEX_OP_ADD: case FUTEX_OP_ADD:
/* *(int *)UADDR2 += OPARG; */ tmp += oparg;
ret = get_user(oldval, uaddr);
if (!ret) {
val = oldval + oparg;
ret = put_user(val, uaddr);
}
break; break;
case FUTEX_OP_OR: case FUTEX_OP_OR:
/* *(int *)UADDR2 |= OPARG; */ tmp |= oparg;
ret = get_user(oldval, uaddr);
if (!ret) {
val = oldval | oparg;
ret = put_user(val, uaddr);
}
break; break;
case FUTEX_OP_ANDN: case FUTEX_OP_ANDN:
/* *(int *)UADDR2 &= ~OPARG; */ tmp &= ~oparg;
ret = get_user(oldval, uaddr);
if (!ret) {
val = oldval & ~oparg;
ret = put_user(val, uaddr);
}
break; break;
case FUTEX_OP_XOR: case FUTEX_OP_XOR:
/* *(int *)UADDR2 ^= OPARG; */ tmp ^= oparg;
ret = get_user(oldval, uaddr);
if (!ret) {
val = oldval ^ oparg;
ret = put_user(val, uaddr);
}
break; break;
default: default:
ret = -ENOSYS; ret = -ENOSYS;
} }
if (ret == 0 && unlikely(put_user(tmp, uaddr) != 0))
ret = -EFAULT;
out_pagefault_enable:
pagefault_enable();
_futex_spin_unlock_irqrestore(uaddr, &flags); _futex_spin_unlock_irqrestore(uaddr, &flags);
pagefault_enable(); if (ret == 0) {
if (!ret) {
switch (cmp) { switch (cmp) {
case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
@ -112,12 +99,10 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
return ret; return ret;
} }
/* Non-atomic version */
static inline int static inline int
futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
u32 oldval, u32 newval) u32 oldval, u32 newval)
{ {
int ret;
u32 val; u32 val;
unsigned long flags; unsigned long flags;
@ -137,17 +122,20 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
*/ */
_futex_spin_lock_irqsave(uaddr, &flags); _futex_spin_lock_irqsave(uaddr, &flags);
if (unlikely(get_user(val, uaddr) != 0)) {
_futex_spin_unlock_irqrestore(uaddr, &flags);
return -EFAULT;
}
ret = get_user(val, uaddr); if (val == oldval && unlikely(put_user(newval, uaddr) != 0)) {
_futex_spin_unlock_irqrestore(uaddr, &flags);
if (!ret && val == oldval) return -EFAULT;
ret = put_user(newval, uaddr); }
*uval = val; *uval = val;
_futex_spin_unlock_irqrestore(uaddr, &flags); _futex_spin_unlock_irqrestore(uaddr, &flags);
return ret; return 0;
} }
#endif /*__KERNEL__*/ #endif /*__KERNEL__*/