| Viewing file:  futex.h (2.16 KB)      -rw-r--r-- Select action/file-type:
 
  (+) |  (+) |  (+) | Code (+) | Session (+) |  (+) | SDB (+) |  (+) |  (+) |  (+) |  (+) |  (+) | 
 
#ifndef _ASM_X86_FUTEX_H#define _ASM_X86_FUTEX_H
 
 #ifdef __KERNEL__
 
 #include <linux/futex.h>
 #include <linux/uaccess.h>
 
 #include <asm/asm.h>
 #include <asm/errno.h>
 #include <asm/processor.h>
 #include <asm/smap.h>
 
 #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg)    \
 asm volatile("\t" ASM_STAC "\n"                \
 "1:\t" insn "\n"                \
 "2:\t" ASM_CLAC "\n"            \
 "\t.section .fixup,\"ax\"\n"        \
 "3:\tmov\t%3, %1\n"            \
 "\tjmp\t2b\n"                \
 "\t.previous\n"                \
 _ASM_EXTABLE(1b, 3b)            \
 : "=r" (oldval), "=r" (ret), "+m" (*uaddr)    \
 : "i" (-EFAULT), "0" (oparg), "1" (0))
 
 #define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg)    \
 asm volatile("\t" ASM_STAC "\n"                \
 "1:\tmovl    %2, %0\n"            \
 "\tmovl\t%0, %3\n"                \
 "\t" insn "\n"                \
 "2:\t" LOCK_PREFIX "cmpxchgl %3, %2\n"    \
 "\tjnz\t1b\n"                \
 "3:\t" ASM_CLAC "\n"            \
 "\t.section .fixup,\"ax\"\n"        \
 "4:\tmov\t%5, %1\n"            \
 "\tjmp\t3b\n"                \
 "\t.previous\n"                \
 _ASM_EXTABLE(1b, 4b)            \
 _ASM_EXTABLE(2b, 4b)            \
 : "=&a" (oldval), "=&r" (ret),        \
 "+m" (*uaddr), "=&r" (tem)        \
 : "r" (oparg), "i" (-EFAULT), "1" (0))
 
 static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval,
 u32 __user *uaddr)
 {
 int oldval = 0, ret, tem;
 
 pagefault_disable();
 
 switch (op) {
 case FUTEX_OP_SET:
 __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
 break;
 case FUTEX_OP_ADD:
 __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret, oldval,
 uaddr, oparg);
 break;
 case FUTEX_OP_OR:
 __futex_atomic_op2("orl %4, %3", ret, oldval, uaddr, oparg);
 break;
 case FUTEX_OP_ANDN:
 __futex_atomic_op2("andl %4, %3", ret, oldval, uaddr, ~oparg);
 break;
 case FUTEX_OP_XOR:
 __futex_atomic_op2("xorl %4, %3", ret, oldval, uaddr, oparg);
 break;
 default:
 ret = -ENOSYS;
 }
 
 pagefault_enable();
 
 if (!ret)
 *oval = oldval;
 
 return ret;
 }
 
 static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
 u32 oldval, u32 newval)
 {
 return user_atomic_cmpxchg_inatomic(uval, uaddr, oldval, newval);
 }
 
 #endif
 #endif /* _ASM_X86_FUTEX_H */
 
 |