root/arch/microblaze/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_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, uaddr, oparg) \
  12 ({                                                                      \
  13         __asm__ __volatile__ (                                          \
  14                         "1:     lwx     %0, %2, r0; "                   \
  15                                 insn                                    \
  16                         "2:     swx     %1, %2, r0;                     \
  17                                 addic   %1, r0, 0;                      \
  18                                 bnei    %1, 1b;                         \
  19                         3:                                              \
  20                         .section .fixup,\"ax\";                         \
  21                         4:      brid    3b;                             \
  22                                 addik   %1, r0, %3;                     \
  23                         .previous;                                      \
  24                         .section __ex_table,\"a\";                      \
  25                         .word   1b,4b,2b,4b;                            \
  26                         .previous;"                                     \
  27         : "=&r" (oldval), "=&r" (ret)                                   \
  28         : "r" (uaddr), "i" (-EFAULT), "r" (oparg)                       \
  29         );                                                              \
  30 })
  31 
  32 static inline int
  33 arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
  34 {
  35         int oldval = 0, ret;
  36 
  37         pagefault_disable();
  38 
  39         switch (op) {
  40         case FUTEX_OP_SET:
  41                 __futex_atomic_op("or %1,%4,%4;", ret, oldval, uaddr, oparg);
  42                 break;
  43         case FUTEX_OP_ADD:
  44                 __futex_atomic_op("add %1,%0,%4;", ret, oldval, uaddr, oparg);
  45                 break;
  46         case FUTEX_OP_OR:
  47                 __futex_atomic_op("or %1,%0,%4;", ret, oldval, uaddr, oparg);
  48                 break;
  49         case FUTEX_OP_ANDN:
  50                 __futex_atomic_op("andn %1,%0,%4;", ret, oldval, uaddr, oparg);
  51                 break;
  52         case FUTEX_OP_XOR:
  53                 __futex_atomic_op("xor %1,%0,%4;", ret, oldval, uaddr, oparg);
  54                 break;
  55         default:
  56                 ret = -ENOSYS;
  57         }
  58 
  59         pagefault_enable();
  60 
  61         if (!ret)
  62                 *oval = oldval;
  63 
  64         return ret;
  65 }
  66 
  67 static inline int
  68 futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
  69                               u32 oldval, u32 newval)
  70 {
  71         int ret = 0, cmp;
  72         u32 prev;
  73 
  74         if (!access_ok(uaddr, sizeof(u32)))
  75                 return -EFAULT;
  76 
  77         __asm__ __volatile__ ("1:       lwx     %1, %3, r0;             \
  78                                         cmp     %2, %1, %4;             \
  79                                         bnei    %2, 3f;                 \
  80                                 2:      swx     %5, %3, r0;             \
  81                                         addic   %2, r0, 0;              \
  82                                         bnei    %2, 1b;                 \
  83                                 3:                                      \
  84                                 .section .fixup,\"ax\";                 \
  85                                 4:      brid    3b;                     \
  86                                         addik   %0, r0, %6;             \
  87                                 .previous;                              \
  88                                 .section __ex_table,\"a\";              \
  89                                 .word   1b,4b,2b,4b;                    \
  90                                 .previous;"                             \
  91                 : "+r" (ret), "=&r" (prev), "=&r"(cmp)  \
  92                 : "r" (uaddr), "r" (oldval), "r" (newval), "i" (-EFAULT));
  93 
  94         *uval = prev;
  95         return ret;
  96 }
  97 
  98 #endif /* __KERNEL__ */
  99 
 100 #endif

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