]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - arch/microblaze/include/asm/futex.h
futex: Remove duplicated code and fix undefined behaviour
[mirror_ubuntu-artful-kernel.git] / arch / microblaze / include / asm / futex.h
CommitLineData
fd3db0a6
MS
1#ifndef _ASM_MICROBLAZE_FUTEX_H
2#define _ASM_MICROBLAZE_FUTEX_H
3
4#ifdef __KERNEL__
5
6#include <linux/futex.h>
7#include <linux/uaccess.h>
8#include <asm/errno.h>
9
10#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
11({ \
12 __asm__ __volatile__ ( \
13 "1: lwx %0, %2, r0; " \
14 insn \
15 "2: swx %1, %2, r0; \
16 addic %1, r0, 0; \
17 bnei %1, 1b; \
18 3: \
19 .section .fixup,\"ax\"; \
20 4: brid 3b; \
21 addik %1, r0, %3; \
22 .previous; \
23 .section __ex_table,\"a\"; \
24 .word 1b,4b,2b,4b; \
25 .previous;" \
26 : "=&r" (oldval), "=&r" (ret) \
8cf662ed 27 : "r" (uaddr), "i" (-EFAULT), "r" (oparg) \
fd3db0a6
MS
28 ); \
29})
30
31static inline int
5961958c 32arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
fd3db0a6 33{
fd3db0a6 34 int oldval = 0, ret;
fd3db0a6
MS
35
36 pagefault_disable();
37
38 switch (op) {
39 case FUTEX_OP_SET:
40 __futex_atomic_op("or %1,%4,%4;", ret, oldval, uaddr, oparg);
41 break;
42 case FUTEX_OP_ADD:
43 __futex_atomic_op("add %1,%0,%4;", ret, oldval, uaddr, oparg);
44 break;
45 case FUTEX_OP_OR:
46 __futex_atomic_op("or %1,%0,%4;", ret, oldval, uaddr, oparg);
47 break;
48 case FUTEX_OP_ANDN:
4bb30baa 49 __futex_atomic_op("andn %1,%0,%4;", ret, oldval, uaddr, oparg);
fd3db0a6
MS
50 break;
51 case FUTEX_OP_XOR:
52 __futex_atomic_op("xor %1,%0,%4;", ret, oldval, uaddr, oparg);
53 break;
54 default:
55 ret = -ENOSYS;
56 }
57
58 pagefault_enable();
59
5961958c
JS
60 if (!ret)
61 *oval = oldval;
62
fd3db0a6
MS
63 return ret;
64}
65
66static inline int
8d7718aa
ML
67futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
68 u32 oldval, u32 newval)
fd3db0a6 69{
8d7718aa
ML
70 int ret = 0, cmp;
71 u32 prev;
fd3db0a6 72
8d7718aa 73 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
fd3db0a6
MS
74 return -EFAULT;
75
37a9d912
ML
76 __asm__ __volatile__ ("1: lwx %1, %3, r0; \
77 cmp %2, %1, %4; \
f6a12a7d 78 bnei %2, 3f; \
37a9d912
ML
79 2: swx %5, %3, r0; \
80 addic %2, r0, 0; \
81 bnei %2, 1b; \
fd3db0a6
MS
82 3: \
83 .section .fixup,\"ax\"; \
84 4: brid 3b; \
37a9d912 85 addik %0, r0, %6; \
fd3db0a6
MS
86 .previous; \
87 .section __ex_table,\"a\"; \
88 .word 1b,4b,2b,4b; \
89 .previous;" \
37a9d912 90 : "+r" (ret), "=&r" (prev), "=&r"(cmp) \
fd3db0a6
MS
91 : "r" (uaddr), "r" (oldval), "r" (newval), "i" (-EFAULT));
92
37a9d912
ML
93 *uval = prev;
94 return ret;
fd3db0a6
MS
95}
96
97#endif /* __KERNEL__ */
98
99#endif