Blame view
include/asm-generic/futex.h
3.72 KB
f8aaeacec [PATCH] consolida... |
1 2 |
#ifndef _ASM_GENERIC_FUTEX_H #define _ASM_GENERIC_FUTEX_H |
f8aaeacec [PATCH] consolida... |
3 |
#include <linux/futex.h> |
730f412c0 asm-*/futex.h sho... |
4 |
#include <linux/uaccess.h> |
f8aaeacec [PATCH] consolida... |
5 |
#include <asm/errno.h> |
f8aaeacec [PATCH] consolida... |
6 |
|
00f634bc5 asm-generic: add ... |
7 8 9 |
#ifndef CONFIG_SMP /* * The following implementation only for uniprocessor machines. |
f3dae07e4 sched/preempt, fu... |
10 |
* It relies on preempt_disable() ensuring mutual exclusion. |
00f634bc5 asm-generic: add ... |
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
* */ /** * futex_atomic_op_inuser() - Atomic arithmetic operation with constant * argument and comparison of the previous * futex value with another constant. * * @encoded_op: encoded operation to execute * @uaddr: pointer to user space address * * Return: * 0 - On success * <0 - On error */ 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; int oparg = (encoded_op << 8) >> 20; int cmparg = (encoded_op << 20) >> 20; int oldval, ret; u32 tmp; if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) oparg = 1 << oparg; |
f3dae07e4 sched/preempt, fu... |
38 |
preempt_disable(); |
00f634bc5 asm-generic: add ... |
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
pagefault_disable(); ret = -EFAULT; if (unlikely(get_user(oldval, uaddr) != 0)) goto out_pagefault_enable; ret = 0; tmp = oldval; switch (op) { case FUTEX_OP_SET: tmp = oparg; break; case FUTEX_OP_ADD: tmp += oparg; break; case FUTEX_OP_OR: tmp |= oparg; break; case FUTEX_OP_ANDN: tmp &= ~oparg; break; case FUTEX_OP_XOR: tmp ^= oparg; break; default: ret = -ENOSYS; } if (ret == 0 && unlikely(put_user(tmp, uaddr) != 0)) ret = -EFAULT; out_pagefault_enable: pagefault_enable(); |
f3dae07e4 sched/preempt, fu... |
73 |
preempt_enable(); |
00f634bc5 asm-generic: add ... |
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
if (ret == 0) { switch (cmp) { case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; default: ret = -ENOSYS; } } return ret; } /** * futex_atomic_cmpxchg_inatomic() - Compare and exchange the content of the * uaddr with newval if the current value is * oldval. * @uval: pointer to store content of @uaddr * @uaddr: pointer to user space address * @oldval: old value * @newval: new value to store to @uaddr * * Return: * 0 - On success * <0 - On error */ static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 oldval, u32 newval) { u32 val; |
d9b9ff8c1 sched/preempt, fu... |
107 |
preempt_disable(); |
fba7cd681 asm-generic/futex... |
108 109 |
if (unlikely(get_user(val, uaddr) != 0)) { preempt_enable(); |
00f634bc5 asm-generic: add ... |
110 |
return -EFAULT; |
fba7cd681 asm-generic/futex... |
111 |
} |
00f634bc5 asm-generic: add ... |
112 |
|
fba7cd681 asm-generic/futex... |
113 114 |
if (val == oldval && unlikely(put_user(newval, uaddr) != 0)) { preempt_enable(); |
00f634bc5 asm-generic: add ... |
115 |
return -EFAULT; |
fba7cd681 asm-generic/futex... |
116 |
} |
00f634bc5 asm-generic: add ... |
117 118 |
*uval = val; |
d9b9ff8c1 sched/preempt, fu... |
119 |
preempt_enable(); |
00f634bc5 asm-generic: add ... |
120 121 122 123 124 |
return 0; } #else |
f8aaeacec [PATCH] consolida... |
125 |
static inline int |
8d7718aa0 futex: Sanitize f... |
126 |
futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) |
f8aaeacec [PATCH] consolida... |
127 128 129 130 131 132 133 134 |
{ int op = (encoded_op >> 28) & 7; int cmp = (encoded_op >> 24) & 15; int oparg = (encoded_op << 8) >> 20; int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) oparg = 1 << oparg; |
8d7718aa0 futex: Sanitize f... |
135 |
if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) |
f8aaeacec [PATCH] consolida... |
136 |
return -EFAULT; |
a866374ae [PATCH] mm: pagef... |
137 |
pagefault_disable(); |
f8aaeacec [PATCH] consolida... |
138 139 140 141 142 143 144 145 146 147 |
switch (op) { case FUTEX_OP_SET: case FUTEX_OP_ADD: case FUTEX_OP_OR: case FUTEX_OP_ANDN: case FUTEX_OP_XOR: default: ret = -ENOSYS; } |
a866374ae [PATCH] mm: pagef... |
148 |
pagefault_enable(); |
f8aaeacec [PATCH] consolida... |
149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
if (!ret) { switch (cmp) { case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; default: ret = -ENOSYS; } } return ret; } |
e9056f13b [PATCH] lightweig... |
163 |
static inline int |
8d7718aa0 futex: Sanitize f... |
164 165 |
futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 oldval, u32 newval) |
e9056f13b [PATCH] lightweig... |
166 167 168 |
{ return -ENOSYS; } |
00f634bc5 asm-generic: add ... |
169 |
#endif /* CONFIG_SMP */ |
f8aaeacec [PATCH] consolida... |
170 |
#endif |