root/arch/hexagon/include/asm/futex.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. arch_futex_atomic_op_inuser
  2. futex_atomic_cmpxchg_inatomic

   1 /* SPDX-License-Identifier: GPL-2.0 */
   2 #ifndef _ASM_HEXAGON_FUTEX_H
   3 #define _ASM_HEXAGON_FUTEX_H
   4 
   5 #ifdef __KERNEL__
   6 
   7 #include <linux/futex.h>
   8 #include <linux/uaccess.h>
   9 #include <asm/errno.h>
  10 
  11 /* XXX TODO-- need to add sync barriers! */
  12 
  13 #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
  14         __asm__ __volatile( \
  15         "1: %0 = memw_locked(%3);\n" \
  16             /* For example: %1 = %4 */ \
  17             insn \
  18         "2: memw_locked(%3,p2) = %1;\n" \
  19         "   if (!p2) jump 1b;\n" \
  20         "   %1 = #0;\n" \
  21         "3:\n" \
  22         ".section .fixup,\"ax\"\n" \
  23         "4: %1 = #%5;\n" \
  24         "   jump 3b\n" \
  25         ".previous\n" \
  26         ".section __ex_table,\"a\"\n" \
  27         ".long 1b,4b,2b,4b\n" \
  28         ".previous\n" \
  29         : "=&r" (oldval), "=&r" (ret), "+m" (*uaddr) \
  30         : "r" (uaddr), "r" (oparg), "i" (-EFAULT) \
  31         : "p2", "memory")
  32 
  33 
  34 static inline int
  35 arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
  36 {
  37         int oldval = 0, ret;
  38 
  39         pagefault_disable();
  40 
  41         switch (op) {
  42         case FUTEX_OP_SET:
  43                 __futex_atomic_op("%1 = %4\n", ret, oldval, uaddr, oparg);
  44                 break;
  45         case FUTEX_OP_ADD:
  46                 __futex_atomic_op("%1 = add(%0,%4)\n", ret, oldval, uaddr,
  47                                   oparg);
  48                 break;
  49         case FUTEX_OP_OR:
  50                 __futex_atomic_op("%1 = or(%0,%4)\n", ret, oldval, uaddr,
  51                                   oparg);
  52                 break;
  53         case FUTEX_OP_ANDN:
  54                 __futex_atomic_op("%1 = not(%4); %1 = and(%0,%1)\n", ret,
  55                                   oldval, uaddr, oparg);
  56                 break;
  57         case FUTEX_OP_XOR:
  58                 __futex_atomic_op("%1 = xor(%0,%4)\n", ret, oldval, uaddr,
  59                                   oparg);
  60                 break;
  61         default:
  62                 ret = -ENOSYS;
  63         }
  64 
  65         pagefault_enable();
  66 
  67         if (!ret)
  68                 *oval = oldval;
  69 
  70         return ret;
  71 }
  72 
  73 static inline int
  74 futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 oldval,
  75                               u32 newval)
  76 {
  77         int prev;
  78         int ret;
  79 
  80         if (!access_ok(uaddr, sizeof(u32)))
  81                 return -EFAULT;
  82 
  83         __asm__ __volatile__ (
  84         "1: %1 = memw_locked(%3)\n"
  85         "   {\n"
  86         "      p2 = cmp.eq(%1,%4)\n"
  87         "      if (!p2.new) jump:NT 3f\n"
  88         "   }\n"
  89         "2: memw_locked(%3,p2) = %5\n"
  90         "   if (!p2) jump 1b\n"
  91         "3:\n"
  92         ".section .fixup,\"ax\"\n"
  93         "4: %0 = #%6\n"
  94         "   jump 3b\n"
  95         ".previous\n"
  96         ".section __ex_table,\"a\"\n"
  97         ".long 1b,4b,2b,4b\n"
  98         ".previous\n"
  99         : "+r" (ret), "=&r" (prev), "+m" (*uaddr)
 100         : "r" (uaddr), "r" (oldval), "r" (newval), "i"(-EFAULT)
 101         : "p2", "memory");
 102 
 103         *uval = prev;
 104         return ret;
 105 }
 106 
 107 #endif /* __KERNEL__ */
 108 #endif /* _ASM_HEXAGON_FUTEX_H */

/* [<][>][^][v][top][bottom][index][help] */