]>
Commit | Line | Data |
---|---|---|
1 | #ifndef __ASM_SH_FUTEX_H | |
2 | #define __ASM_SH_FUTEX_H | |
3 | ||
4 | #ifdef __KERNEL__ | |
5 | ||
6 | #include <linux/futex.h> | |
7 | #include <linux/uaccess.h> | |
8 | #include <asm/errno.h> | |
9 | ||
10 | #if !defined(CONFIG_SMP) | |
11 | #include <asm/futex-irq.h> | |
12 | #elif defined(CONFIG_CPU_J2) | |
13 | #include <asm/futex-cas.h> | |
14 | #elif defined(CONFIG_CPU_SH4A) | |
15 | #include <asm/futex-llsc.h> | |
16 | #else | |
17 | #error SMP not supported on this configuration. | |
18 | #endif | |
19 | ||
20 | static inline int | |
21 | futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | |
22 | u32 oldval, u32 newval) | |
23 | { | |
24 | if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) | |
25 | return -EFAULT; | |
26 | ||
27 | return atomic_futex_op_cmpxchg_inatomic(uval, uaddr, oldval, newval); | |
28 | } | |
29 | ||
30 | static inline int arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval, | |
31 | u32 __user *uaddr) | |
32 | { | |
33 | u32 oldval, newval, prev; | |
34 | int ret; | |
35 | ||
36 | pagefault_disable(); | |
37 | ||
38 | do { | |
39 | if (op == FUTEX_OP_SET) | |
40 | ret = oldval = 0; | |
41 | else | |
42 | ret = get_user(oldval, uaddr); | |
43 | ||
44 | if (ret) break; | |
45 | ||
46 | switch (op) { | |
47 | case FUTEX_OP_SET: | |
48 | newval = oparg; | |
49 | break; | |
50 | case FUTEX_OP_ADD: | |
51 | newval = oldval + oparg; | |
52 | break; | |
53 | case FUTEX_OP_OR: | |
54 | newval = oldval | oparg; | |
55 | break; | |
56 | case FUTEX_OP_ANDN: | |
57 | newval = oldval & ~oparg; | |
58 | break; | |
59 | case FUTEX_OP_XOR: | |
60 | newval = oldval ^ oparg; | |
61 | break; | |
62 | default: | |
63 | ret = -ENOSYS; | |
64 | break; | |
65 | } | |
66 | ||
67 | if (ret) break; | |
68 | ||
69 | ret = futex_atomic_cmpxchg_inatomic(&prev, uaddr, oldval, newval); | |
70 | } while (!ret && prev != oldval); | |
71 | ||
72 | pagefault_enable(); | |
73 | ||
74 | if (!ret) | |
75 | *oval = oldval; | |
76 | ||
77 | return ret; | |
78 | } | |
79 | ||
80 | #endif /* __KERNEL__ */ | |
81 | #endif /* __ASM_SH_FUTEX_H */ |