1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __ASM_OPENRISC_FUTEX_H
3 #define __ASM_OPENRISC_FUTEX_H
7 #include <linux/futex.h>
8 #include <linux/uaccess.h>
11 #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
13 __asm__ __volatile__ ( \
14 "1: l.lwa %0, %2 \n" \
16 "2: l.swa %2, %1 \n" \
18 " l.ori %1, r0, 0 \n" \
20 ".section .fixup,\"ax\" \n" \
22 " l.addi %1, r0, %3 \n" \
24 ".section __ex_table,\"a\" \n" \
25 ".word 1b,4b,2b,4b \n" \
27 : "=&r" (oldval), "=&r" (ret), "+m" (*uaddr) \
28 : "i" (-EFAULT), "r" (oparg) \
34 arch_futex_atomic_op_inuser(int op
, int oparg
, int *oval
, u32 __user
*uaddr
)
38 if (!access_ok(uaddr
, sizeof(u32
)))
43 __futex_atomic_op("l.or %1,%4,%4", ret
, oldval
, uaddr
, oparg
);
46 __futex_atomic_op("l.add %1,%0,%4", ret
, oldval
, uaddr
, oparg
);
49 __futex_atomic_op("l.or %1,%0,%4", ret
, oldval
, uaddr
, oparg
);
52 __futex_atomic_op("l.and %1,%0,%4", ret
, oldval
, uaddr
, ~oparg
);
55 __futex_atomic_op("l.xor %1,%0,%4", ret
, oldval
, uaddr
, oparg
);
68 futex_atomic_cmpxchg_inatomic(u32
*uval
, u32 __user
*uaddr
,
69 u32 oldval
, u32 newval
)
74 if (!access_ok(uaddr
, sizeof(u32
)))
77 __asm__
__volatile__ ( \
78 "1: l.lwa %1, %2 \n" \
82 "2: l.swa %2, %4 \n" \
86 ".section .fixup,\"ax\" \n" \
88 " l.addi %0, r0, %5 \n" \
90 ".section __ex_table,\"a\" \n" \
91 ".word 1b,4b,2b,4b \n" \
93 : "+r" (ret
), "=&r" (prev
), "+m" (*uaddr
) \
94 : "r" (oldval
), "r" (newval
), "i" (-EFAULT
) \
102 #endif /* __KERNEL__ */
104 #endif /* __ASM_OPENRISC_FUTEX_H */