^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #ifndef __ASM_SH_FUTEX_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #define __ASM_SH_FUTEX_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/futex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <asm/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #if !defined(CONFIG_SMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <asm/futex-irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #elif defined(CONFIG_CPU_J2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <asm/futex-cas.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #elif defined(CONFIG_CPU_SH4A)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/futex-llsc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #error SMP not supported on this configuration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) u32 oldval, u32 newval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) if (!access_ok(uaddr, sizeof(u32)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) return atomic_futex_op_cmpxchg_inatomic(uval, uaddr, oldval, newval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static inline int arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) u32 __user *uaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) u32 oldval, newval, prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) ret = get_user(oldval, uaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) if (ret) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) switch (op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) case FUTEX_OP_SET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) newval = oparg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) case FUTEX_OP_ADD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) newval = oldval + oparg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) case FUTEX_OP_OR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) newval = oldval | oparg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) case FUTEX_OP_ANDN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) newval = oldval & ~oparg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) case FUTEX_OP_XOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) newval = oldval ^ oparg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) ret = -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) if (ret) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) ret = futex_atomic_cmpxchg_inatomic(&prev, uaddr, oldval, newval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) } while (!ret && prev != oldval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) *oval = oldval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #endif /* __ASM_SH_FUTEX_H */