1 /* SPDX-License-Identifier: GPL-2.0 */
3 * Copyright (c) 2006 Ralf Baechle (ralf@linux-mips.org)
4 * Copyright (c) 2018 Jim Wilson (jimw@sifive.com)
10 #ifndef CONFIG_RISCV_ISA_A
12 * Use the generic interrupt disabling versions if the A extension
16 #error "Can't support generic futex calls without A extension on SMP"
18 #include <asm-generic/futex.h>
20 #else /* CONFIG_RISCV_ISA_A */
22 #include <linux/futex.h>
23 #include <linux/uaccess.h>
24 #include <linux/errno.h>
27 #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
30 __enable_user_access(); \
31 __asm__ __volatile__ ( \
34 " .section .fixup,\"ax\" \n" \
36 "3: li %[r],%[e] \n" \
39 " .section __ex_table,\"a\" \n" \
40 " .balign " RISCV_SZPTR " \n" \
41 " " RISCV_PTR " 1b, 3b \n" \
43 : [r] "+r" (ret), [ov] "=&r" (oldval), \
44 [u] "+m" (*uaddr), [t] "=&r" (tmp) \
45 : [op] "Jr" (oparg), [e] "i" (-EFAULT) \
47 __disable_user_access(); \
51 arch_futex_atomic_op_inuser(int op
, int oparg
, int *oval
, u32 __user
*uaddr
)
53 int oldval
= 0, ret
= 0;
59 __futex_atomic_op("amoswap.w.aqrl %[ov],%z[op],%[u]",
60 ret
, oldval
, uaddr
, oparg
);
63 __futex_atomic_op("amoadd.w.aqrl %[ov],%z[op],%[u]",
64 ret
, oldval
, uaddr
, oparg
);
67 __futex_atomic_op("amoor.w.aqrl %[ov],%z[op],%[u]",
68 ret
, oldval
, uaddr
, oparg
);
71 __futex_atomic_op("amoand.w.aqrl %[ov],%z[op],%[u]",
72 ret
, oldval
, uaddr
, ~oparg
);
75 __futex_atomic_op("amoxor.w.aqrl %[ov],%z[op],%[u]",
76 ret
, oldval
, uaddr
, oparg
);
91 futex_atomic_cmpxchg_inatomic(u32
*uval
, u32 __user
*uaddr
,
92 u32 oldval
, u32 newval
)
98 if (!access_ok(uaddr
, sizeof(u32
)))
101 __enable_user_access();
102 __asm__
__volatile__ (
103 "1: lr.w.aqrl %[v],%[u] \n"
104 " bne %[v],%z[ov],3f \n"
105 "2: sc.w.aqrl %[t],%z[nv],%[u] \n"
108 " .section .fixup,\"ax\" \n"
113 " .section __ex_table,\"a\" \n"
114 " .balign " RISCV_SZPTR
" \n"
115 " " RISCV_PTR
" 1b, 4b \n"
116 " " RISCV_PTR
" 2b, 4b \n"
118 : [r
] "+r" (ret
), [v
] "=&r" (val
), [u
] "+m" (*uaddr
), [t
] "=&r" (tmp
)
119 : [ov
] "Jr" (oldval
), [nv
] "Jr" (newval
), [e
] "i" (-EFAULT
)
121 __disable_user_access();
127 #endif /* CONFIG_RISCV_ISA_A */
128 #endif /* _ASM_FUTEX_H */