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