• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _ASM_M68K_FUTEX_H
2 #define _ASM_M68K_FUTEX_H
3 
4 #ifdef __KERNEL__
5 #if !defined(CONFIG_MMU)
6 #include <asm-generic/futex.h>
7 #else	/* CONFIG_MMU */
8 
9 #include <linux/futex.h>
10 #include <linux/uaccess.h>
11 #include <asm/errno.h>
12 
13 static inline int
futex_atomic_cmpxchg_inatomic(u32 * uval,u32 __user * uaddr,u32 oldval,u32 newval)14 futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
15 			      u32 oldval, u32 newval)
16 {
17 	u32 val;
18 
19 	if (unlikely(get_user(val, uaddr) != 0))
20 		return -EFAULT;
21 
22 	if (val == oldval && unlikely(put_user(newval, uaddr) != 0))
23 		return -EFAULT;
24 
25 	*uval = val;
26 
27 	return 0;
28 }
29 
30 static inline int
futex_atomic_op_inuser(int encoded_op,u32 __user * uaddr)31 futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
32 {
33 	int op = (encoded_op >> 28) & 7;
34 	int cmp = (encoded_op >> 24) & 15;
35 	int oparg = (encoded_op << 8) >> 20;
36 	int cmparg = (encoded_op << 20) >> 20;
37 	int oldval, ret;
38 	u32 tmp;
39 
40 	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
41 		oparg = 1 << oparg;
42 
43 	pagefault_disable();	/* implies preempt_disable() */
44 
45 	ret = -EFAULT;
46 	if (unlikely(get_user(oldval, uaddr) != 0))
47 		goto out_pagefault_enable;
48 
49 	ret = 0;
50 	tmp = oldval;
51 
52 	switch (op) {
53 	case FUTEX_OP_SET:
54 		tmp = oparg;
55 		break;
56 	case FUTEX_OP_ADD:
57 		tmp += oparg;
58 		break;
59 	case FUTEX_OP_OR:
60 		tmp |= oparg;
61 		break;
62 	case FUTEX_OP_ANDN:
63 		tmp &= ~oparg;
64 		break;
65 	case FUTEX_OP_XOR:
66 		tmp ^= oparg;
67 		break;
68 	default:
69 		ret = -ENOSYS;
70 	}
71 
72 	if (ret == 0 && unlikely(put_user(tmp, uaddr) != 0))
73 		ret = -EFAULT;
74 
75 out_pagefault_enable:
76 	pagefault_enable();	/* subsumes preempt_enable() */
77 
78 	if (ret == 0) {
79 		switch (cmp) {
80 		case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
81 		case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
82 		case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
83 		case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
84 		case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
85 		case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
86 		default: ret = -ENOSYS;
87 		}
88 	}
89 	return ret;
90 }
91 
92 #endif /* CONFIG_MMU */
93 #endif /* __KERNEL__ */
94 #endif /* _ASM_M68K_FUTEX_H */
95