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