diff options
author | John David Anglin <dave.anglin@bell.net> | 2016-05-21 15:03:54 -0400 |
---|---|---|
committer | Helge Deller <deller@gmx.de> | 2016-05-22 15:48:54 -0400 |
commit | 99aed91a8dc6e398003333decacc101e5e504988 (patch) | |
tree | 133a66f66d9285385f735620a1eb0e5f7d422f02 /arch | |
parent | 4df3c9ec12077384e0add54f28a9b079a87b59ef (diff) |
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>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/parisc/include/asm/futex.h | 70 |
1 files changed, 29 insertions, 41 deletions
diff --git a/arch/parisc/include/asm/futex.h b/arch/parisc/include/asm/futex.h index 49df14805a9b..ac8bd586ace8 100644 --- a/arch/parisc/include/asm/futex.h +++ b/arch/parisc/include/asm/futex.h | |||
@@ -35,70 +35,57 @@ static inline int | |||
35 | futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) | 35 | futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) |
36 | { | 36 | { |
37 | unsigned long int flags; | 37 | unsigned long int flags; |
38 | u32 val; | ||
39 | int op = (encoded_op >> 28) & 7; | 38 | int op = (encoded_op >> 28) & 7; |
40 | int cmp = (encoded_op >> 24) & 15; | 39 | int cmp = (encoded_op >> 24) & 15; |
41 | int oparg = (encoded_op << 8) >> 20; | 40 | int oparg = (encoded_op << 8) >> 20; |
42 | int cmparg = (encoded_op << 20) >> 20; | 41 | int cmparg = (encoded_op << 20) >> 20; |
43 | int oldval = 0, ret; | 42 | int oldval, ret; |
43 | u32 tmp; | ||
44 | |||
44 | if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) | 45 | if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) |
45 | oparg = 1 << oparg; | 46 | oparg = 1 << oparg; |
46 | 47 | ||
47 | if (!access_ok(VERIFY_WRITE, uaddr, sizeof(*uaddr))) | 48 | if (!access_ok(VERIFY_WRITE, uaddr, sizeof(*uaddr))) |
48 | return -EFAULT; | 49 | return -EFAULT; |
49 | 50 | ||
51 | _futex_spin_lock_irqsave(uaddr, &flags); | ||
50 | pagefault_disable(); | 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 | switch (op) { | 61 | switch (op) { |
55 | case FUTEX_OP_SET: | 62 | case FUTEX_OP_SET: |
56 | /* *(int *)UADDR2 = OPARG; */ | 63 | tmp = oparg; |
57 | ret = get_user(oldval, uaddr); | ||
58 | if (!ret) | ||
59 | ret = put_user(oparg, uaddr); | ||
60 | break; | 64 | break; |
61 | case FUTEX_OP_ADD: | 65 | case FUTEX_OP_ADD: |
62 | /* *(int *)UADDR2 += OPARG; */ | 66 | tmp += oparg; |
63 | ret = get_user(oldval, uaddr); | ||
64 | if (!ret) { | ||
65 | val = oldval + oparg; | ||
66 | ret = put_user(val, uaddr); | ||
67 | } | ||
68 | break; | 67 | break; |
69 | case FUTEX_OP_OR: | 68 | case FUTEX_OP_OR: |
70 | /* *(int *)UADDR2 |= OPARG; */ | 69 | tmp |= oparg; |
71 | ret = get_user(oldval, uaddr); | ||
72 | if (!ret) { | ||
73 | val = oldval | oparg; | ||
74 | ret = put_user(val, uaddr); | ||
75 | } | ||
76 | break; | 70 | break; |
77 | case FUTEX_OP_ANDN: | 71 | case FUTEX_OP_ANDN: |
78 | /* *(int *)UADDR2 &= ~OPARG; */ | 72 | tmp &= ~oparg; |
79 | ret = get_user(oldval, uaddr); | ||
80 | if (!ret) { | ||
81 | val = oldval & ~oparg; | ||
82 | ret = put_user(val, uaddr); | ||
83 | } | ||
84 | break; | 73 | break; |
85 | case FUTEX_OP_XOR: | 74 | case FUTEX_OP_XOR: |
86 | /* *(int *)UADDR2 ^= OPARG; */ | 75 | tmp ^= oparg; |
87 | ret = get_user(oldval, uaddr); | ||
88 | if (!ret) { | ||
89 | val = oldval ^ oparg; | ||
90 | ret = put_user(val, uaddr); | ||
91 | } | ||
92 | break; | 76 | break; |
93 | default: | 77 | default: |
94 | ret = -ENOSYS; | 78 | ret = -ENOSYS; |
95 | } | 79 | } |
96 | 80 | ||
97 | _futex_spin_unlock_irqrestore(uaddr, &flags); | 81 | if (ret == 0 && unlikely(put_user(tmp, uaddr) != 0)) |
82 | ret = -EFAULT; | ||
98 | 83 | ||
84 | out_pagefault_enable: | ||
99 | pagefault_enable(); | 85 | pagefault_enable(); |
86 | _futex_spin_unlock_irqrestore(uaddr, &flags); | ||
100 | 87 | ||
101 | if (!ret) { | 88 | if (ret == 0) { |
102 | switch (cmp) { | 89 | switch (cmp) { |
103 | case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; | 90 | case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; |
104 | case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; | 91 | case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; |
@@ -112,12 +99,10 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) | |||
112 | return ret; | 99 | return ret; |
113 | } | 100 | } |
114 | 101 | ||
115 | /* Non-atomic version */ | ||
116 | static inline int | 102 | static inline int |
117 | futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | 103 | futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, |
118 | u32 oldval, u32 newval) | 104 | u32 oldval, u32 newval) |
119 | { | 105 | { |
120 | int ret; | ||
121 | u32 val; | 106 | u32 val; |
122 | unsigned long flags; | 107 | unsigned long flags; |
123 | 108 | ||
@@ -137,17 +122,20 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | |||
137 | */ | 122 | */ |
138 | 123 | ||
139 | _futex_spin_lock_irqsave(uaddr, &flags); | 124 | _futex_spin_lock_irqsave(uaddr, &flags); |
125 | if (unlikely(get_user(val, uaddr) != 0)) { | ||
126 | _futex_spin_unlock_irqrestore(uaddr, &flags); | ||
127 | return -EFAULT; | ||
128 | } | ||
140 | 129 | ||
141 | ret = get_user(val, uaddr); | 130 | if (val == oldval && unlikely(put_user(newval, uaddr) != 0)) { |
142 | 131 | _futex_spin_unlock_irqrestore(uaddr, &flags); | |
143 | if (!ret && val == oldval) | 132 | return -EFAULT; |
144 | ret = put_user(newval, uaddr); | 133 | } |
145 | 134 | ||
146 | *uval = val; | 135 | *uval = val; |
147 | |||
148 | _futex_spin_unlock_irqrestore(uaddr, &flags); | 136 | _futex_spin_unlock_irqrestore(uaddr, &flags); |
149 | 137 | ||
150 | return ret; | 138 | return 0; |
151 | } | 139 | } |
152 | 140 | ||
153 | #endif /*__KERNEL__*/ | 141 | #endif /*__KERNEL__*/ |