~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/include/asm-generic/futex.h

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0 */
  2 #ifndef _ASM_GENERIC_FUTEX_H
  3 #define _ASM_GENERIC_FUTEX_H
  4 
  5 #include <linux/futex.h>
  6 #include <linux/uaccess.h>
  7 #include <asm/errno.h>
  8 
  9 #ifndef futex_atomic_cmpxchg_inatomic
 10 #ifndef CONFIG_SMP
 11 /*
 12  * The following implementation only for uniprocessor machines.
 13  * It relies on preempt_disable() ensuring mutual exclusion.
 14  *
 15  */
 16 #define futex_atomic_cmpxchg_inatomic(uval, uaddr, oldval, newval) \
 17         futex_atomic_cmpxchg_inatomic_local(uval, uaddr, oldval, newval)
 18 #define arch_futex_atomic_op_inuser(op, oparg, oval, uaddr) \
 19         futex_atomic_op_inuser_local(op, oparg, oval, uaddr)
 20 #endif /* CONFIG_SMP */
 21 #endif
 22 
 23 /**
 24  * futex_atomic_op_inuser_local() - Atomic arithmetic operation with constant
 25  *                        argument and comparison of the previous
 26  *                        futex value with another constant.
 27  *
 28  * @encoded_op: encoded operation to execute
 29  * @uaddr:      pointer to user space address
 30  *
 31  * Return:
 32  * 0 - On success
 33  * -EFAULT - User access resulted in a page fault
 34  * -EAGAIN - Atomic operation was unable to complete due to contention
 35  * -ENOSYS - Operation not supported
 36  */
 37 static inline int
 38 futex_atomic_op_inuser_local(int op, u32 oparg, int *oval, u32 __user *uaddr)
 39 {
 40         int oldval, ret;
 41         u32 tmp;
 42 
 43         preempt_disable();
 44 
 45         ret = -EFAULT;
 46         if (unlikely(get_user(oldval, uaddr) != 0))
 47                 goto out_pagefault_enable;
 48 
 49         ret = 0;
 50         tmp = oldval;
 51 
 52         switch (op) {
 53         case FUTEX_OP_SET:
 54                 tmp = oparg;
 55                 break;
 56         case FUTEX_OP_ADD:
 57                 tmp += oparg;
 58                 break;
 59         case FUTEX_OP_OR:
 60                 tmp |= oparg;
 61                 break;
 62         case FUTEX_OP_ANDN:
 63                 tmp &= ~oparg;
 64                 break;
 65         case FUTEX_OP_XOR:
 66                 tmp ^= oparg;
 67                 break;
 68         default:
 69                 ret = -ENOSYS;
 70         }
 71 
 72         if (ret == 0 && unlikely(put_user(tmp, uaddr) != 0))
 73                 ret = -EFAULT;
 74 
 75 out_pagefault_enable:
 76         preempt_enable();
 77 
 78         if (ret == 0)
 79                 *oval = oldval;
 80 
 81         return ret;
 82 }
 83 
 84 /**
 85  * futex_atomic_cmpxchg_inatomic_local() - Compare and exchange the content of the
 86  *                              uaddr with newval if the current value is
 87  *                              oldval.
 88  * @uval:       pointer to store content of @uaddr
 89  * @uaddr:      pointer to user space address
 90  * @oldval:     old value
 91  * @newval:     new value to store to @uaddr
 92  *
 93  * Return:
 94  * 0 - On success
 95  * -EFAULT - User access resulted in a page fault
 96  * -EAGAIN - Atomic operation was unable to complete due to contention
 97  */
 98 static inline int
 99 futex_atomic_cmpxchg_inatomic_local(u32 *uval, u32 __user *uaddr,
100                               u32 oldval, u32 newval)
101 {
102         u32 val;
103 
104         preempt_disable();
105         if (unlikely(get_user(val, uaddr) != 0)) {
106                 preempt_enable();
107                 return -EFAULT;
108         }
109 
110         if (val == oldval && unlikely(put_user(newval, uaddr) != 0)) {
111                 preempt_enable();
112                 return -EFAULT;
113         }
114 
115         *uval = val;
116         preempt_enable();
117 
118         return 0;
119 }
120 
121 #endif
122 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php