Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

John David Anglin and committed by
Helge Deller
99aed91a 4df3c9ec

+30 -42
+30 -42
arch/parisc/include/asm/futex.h
··· 35 35 futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) 36 36 { 37 37 unsigned long int flags; 38 - u32 val; 39 38 int op = (encoded_op >> 28) & 7; 40 39 int cmp = (encoded_op >> 24) & 15; 41 40 int oparg = (encoded_op << 8) >> 20; 42 41 int cmparg = (encoded_op << 20) >> 20; 43 - int oldval = 0, ret; 42 + int oldval, ret; 43 + u32 tmp; 44 + 44 45 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) 45 46 oparg = 1 << oparg; 46 47 47 48 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(*uaddr))) 48 49 return -EFAULT; 49 50 51 + _futex_spin_lock_irqsave(uaddr, &flags); 50 52 pagefault_disable(); 51 53 52 - _futex_spin_lock_irqsave(uaddr, &flags); 54 + ret = -EFAULT; 55 + if (unlikely(get_user(oldval, uaddr) != 0)) 56 + goto out_pagefault_enable; 57 + 58 + ret = 0; 59 + tmp = oldval; 53 60 54 61 switch (op) { 55 62 case FUTEX_OP_SET: 56 - /* *(int *)UADDR2 = OPARG; */ 57 - ret = get_user(oldval, uaddr); 58 - if (!ret) 59 - ret = put_user(oparg, uaddr); 63 + tmp = oparg; 60 64 break; 61 65 case FUTEX_OP_ADD: 62 - /* *(int *)UADDR2 += OPARG; */ 63 - ret = get_user(oldval, uaddr); 64 - if (!ret) { 65 - val = oldval + oparg; 66 - ret = put_user(val, uaddr); 67 - } 66 + tmp += oparg; 68 67 break; 69 68 case FUTEX_OP_OR: 70 - /* *(int *)UADDR2 |= OPARG; */ 71 - ret = get_user(oldval, uaddr); 72 - if (!ret) { 73 - val = oldval | oparg; 74 - ret = put_user(val, uaddr); 75 - } 69 + tmp |= oparg; 76 70 break; 77 71 case FUTEX_OP_ANDN: 78 - /* *(int *)UADDR2 &= ~OPARG; */ 79 - ret = get_user(oldval, uaddr); 80 - if (!ret) { 81 - val = oldval & ~oparg; 82 - ret = put_user(val, uaddr); 83 - } 72 + tmp &= ~oparg; 84 73 break; 85 74 case FUTEX_OP_XOR: 86 - /* *(int *)UADDR2 ^= OPARG; */ 87 - ret = get_user(oldval, uaddr); 88 - if (!ret) { 89 - val = oldval ^ oparg; 90 - ret = put_user(val, uaddr); 91 - } 75 + tmp ^= oparg; 92 76 break; 93 77 default: 94 78 ret = -ENOSYS; 95 79 } 96 80 81 + if (ret == 0 && unlikely(put_user(tmp, uaddr) != 0)) 82 + ret = -EFAULT; 83 + 84 + out_pagefault_enable: 85 + pagefault_enable(); 97 86 _futex_spin_unlock_irqrestore(uaddr, &flags); 98 87 99 - pagefault_enable(); 100 - 101 - if (!ret) { 88 + if (ret == 0) { 102 89 switch (cmp) { 103 90 case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; 104 91 case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; ··· 99 112 return ret; 100 113 } 101 114 102 - /* Non-atomic version */ 103 115 static inline int 104 116 futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, 105 117 u32 oldval, u32 newval) 106 118 { 107 - int ret; 108 119 u32 val; 109 120 unsigned long flags; 110 121 ··· 122 137 */ 123 138 124 139 _futex_spin_lock_irqsave(uaddr, &flags); 140 + if (unlikely(get_user(val, uaddr) != 0)) { 141 + _futex_spin_unlock_irqrestore(uaddr, &flags); 142 + return -EFAULT; 143 + } 125 144 126 - ret = get_user(val, uaddr); 127 - 128 - if (!ret && val == oldval) 129 - ret = put_user(newval, uaddr); 145 + if (val == oldval && unlikely(put_user(newval, uaddr) != 0)) { 146 + _futex_spin_unlock_irqrestore(uaddr, &flags); 147 + return -EFAULT; 148 + } 130 149 131 150 *uval = val; 132 - 133 151 _futex_spin_unlock_irqrestore(uaddr, &flags); 134 152 135 - return ret; 153 + return 0; 136 154 } 137 155 138 156 #endif /*__KERNEL__*/