1 /* SPDX-License-Identifier: GPL-2.0 */ 1 2 #ifndef _ASM_MICROBLAZE_FUTEX_H 3 #define _ASM_MICROBLAZE_FUTEX_H 4 5 #ifdef __KERNEL__ 6 7 #include <linux/futex.h> 8 #include <linux/uaccess.h> 9 #include <asm/errno.h> 10 11 #define __futex_atomic_op(insn, ret, oldval, u 12 ({ 13 __asm__ __volatile__ ( 14 "1: lwx %0, %2 15 insn 16 "2: swx %1, %2 17 addic %1, r0 18 bnei %1, 1b 19 3: 20 .section .fixup,\"ax\" 21 4: brid 3b; 22 addik %1, r0 23 .previous; 24 .section __ex_table,\" 25 .word 1b,4b,2b,4b; 26 .previous;" 27 : "=&r" (oldval), "=&r" (ret) 28 : "r" (uaddr), "i" (-EFAULT), "r" (opa 29 ); 30 }) 31 32 static inline int 33 arch_futex_atomic_op_inuser(int op, int oparg, 34 { 35 int oldval = 0, ret; 36 37 if (!access_ok(uaddr, sizeof(u32))) 38 return -EFAULT; 39 40 switch (op) { 41 case FUTEX_OP_SET: 42 __futex_atomic_op("or %1,%4,%4 43 break; 44 case FUTEX_OP_ADD: 45 __futex_atomic_op("add %1,%0,% 46 break; 47 case FUTEX_OP_OR: 48 __futex_atomic_op("or %1,%0,%4 49 break; 50 case FUTEX_OP_ANDN: 51 __futex_atomic_op("andn %1,%0, 52 break; 53 case FUTEX_OP_XOR: 54 __futex_atomic_op("xor %1,%0,% 55 break; 56 default: 57 ret = -ENOSYS; 58 } 59 60 if (!ret) 61 *oval = oldval; 62 63 return ret; 64 } 65 66 static inline int 67 futex_atomic_cmpxchg_inatomic(u32 *uval, u32 _ 68 u32 oldval, u32 69 { 70 int ret = 0, cmp; 71 u32 prev; 72 73 if (!access_ok(uaddr, sizeof(u32))) 74 return -EFAULT; 75 76 __asm__ __volatile__ ("1: lwx 77 cmp 78 bnei 79 2: swx 80 addic 81 bnei 82 3: 83 .section .fixu 84 4: brid 85 addik 86 .previous; 87 .section __ex_ 88 .word 1b,4b, 89 .previous;" 90 : "+r" (ret), "=&r" (prev), "= 91 : "r" (uaddr), "r" (oldval), " 92 93 *uval = prev; 94 return ret; 95 } 96 97 #endif /* __KERNEL__ */ 98 99 #endif 100
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.