]> git.ipfire.org Git - thirdparty/linux.git/blame - arch/powerpc/include/asm/futex.h
License cleanup: add SPDX GPL-2.0 license identifier to files with no license
[thirdparty/linux.git] / arch / powerpc / include / asm / futex.h
CommitLineData
b2441318 1/* SPDX-License-Identifier: GPL-2.0 */
2ff2ae7a
DG
2#ifndef _ASM_POWERPC_FUTEX_H
3#define _ASM_POWERPC_FUTEX_H
4732efbe
JJ
4
5#ifdef __KERNEL__
6
7#include <linux/futex.h>
730f412c 8#include <linux/uaccess.h>
4732efbe 9#include <asm/errno.h>
feaf7cf1 10#include <asm/synch.h>
3ddfbcf1 11#include <asm/asm-compat.h>
4732efbe
JJ
12
13#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
2ff2ae7a 14 __asm__ __volatile ( \
b97021f8 15 PPC_ATOMIC_ENTRY_BARRIER \
2ff2ae7a
DG
16"1: lwarx %0,0,%2\n" \
17 insn \
3ddfbcf1 18 PPC405_ERR77(0, %2) \
2ff2ae7a
DG
19"2: stwcx. %1,0,%2\n" \
20 "bne- 1b\n" \
b97021f8 21 PPC_ATOMIC_EXIT_BARRIER \
2ff2ae7a
DG
22 "li %1,0\n" \
23"3: .section .fixup,\"ax\"\n" \
24"4: li %1,%3\n" \
25 "b 3b\n" \
26 ".previous\n" \
24bfa6a9
NP
27 EX_TABLE(1b, 4b) \
28 EX_TABLE(2b, 4b) \
2ff2ae7a 29 : "=&r" (oldval), "=&r" (ret) \
306a8288 30 : "b" (uaddr), "i" (-EFAULT), "r" (oparg) \
4732efbe
JJ
31 : "cr0", "memory")
32
30d6e0a4
JS
33static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval,
34 u32 __user *uaddr)
4732efbe 35{
4732efbe 36 int oldval = 0, ret;
4732efbe 37
a866374a 38 pagefault_disable();
4732efbe
JJ
39
40 switch (op) {
41 case FUTEX_OP_SET:
306a8288 42 __futex_atomic_op("mr %1,%4\n", ret, oldval, uaddr, oparg);
4732efbe
JJ
43 break;
44 case FUTEX_OP_ADD:
306a8288 45 __futex_atomic_op("add %1,%0,%4\n", ret, oldval, uaddr, oparg);
4732efbe
JJ
46 break;
47 case FUTEX_OP_OR:
306a8288 48 __futex_atomic_op("or %1,%0,%4\n", ret, oldval, uaddr, oparg);
4732efbe
JJ
49 break;
50 case FUTEX_OP_ANDN:
306a8288 51 __futex_atomic_op("andc %1,%0,%4\n", ret, oldval, uaddr, oparg);
4732efbe
JJ
52 break;
53 case FUTEX_OP_XOR:
306a8288 54 __futex_atomic_op("xor %1,%0,%4\n", ret, oldval, uaddr, oparg);
4732efbe
JJ
55 break;
56 default:
57 ret = -ENOSYS;
58 }
59
a866374a 60 pagefault_enable();
4732efbe 61
30d6e0a4
JS
62 if (!ret)
63 *oval = oldval;
64
4732efbe
JJ
65 return ret;
66}
67
e9056f13 68static inline int
8d7718aa
ML
69futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
70 u32 oldval, u32 newval)
e9056f13 71{
8d7718aa
ML
72 int ret = 0;
73 u32 prev;
69588298 74
8d7718aa 75 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
69588298
DW
76 return -EFAULT;
77
78 __asm__ __volatile__ (
b97021f8 79 PPC_ATOMIC_ENTRY_BARRIER
37a9d912
ML
80"1: lwarx %1,0,%3 # futex_atomic_cmpxchg_inatomic\n\
81 cmpw 0,%1,%4\n\
69588298 82 bne- 3f\n"
37a9d912
ML
83 PPC405_ERR77(0,%3)
84"2: stwcx. %5,0,%3\n\
69588298 85 bne- 1b\n"
b97021f8 86 PPC_ATOMIC_EXIT_BARRIER
69588298 87"3: .section .fixup,\"ax\"\n\
37a9d912 884: li %0,%6\n\
69588298 89 b 3b\n\
24bfa6a9
NP
90 .previous\n"
91 EX_TABLE(1b, 4b)
92 EX_TABLE(2b, 4b)
37a9d912 93 : "+r" (ret), "=&r" (prev), "+m" (*uaddr)
69588298
DW
94 : "r" (uaddr), "r" (oldval), "r" (newval), "i" (-EFAULT)
95 : "cc", "memory");
96
37a9d912
ML
97 *uval = prev;
98 return ret;
e9056f13
IM
99}
100
2ff2ae7a
DG
101#endif /* __KERNEL__ */
102#endif /* _ASM_POWERPC_FUTEX_H */