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

TOMOYO Linux Cross Reference
Linux/arch/arc/include/asm/futex.h

Version: ~ [ linux-5.11-rc1 ] ~ [ linux-5.10.4 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.86 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.164 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.213 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.249 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.249 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ 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.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
  3  *
  4  * This program is free software; you can redistribute it and/or modify
  5  * it under the terms of the GNU General Public License version 2 as
  6  * published by the Free Software Foundation.
  7  *
  8  * Vineetg: August 2010: From Android kernel work
  9  */
 10 
 11 #ifndef _ASM_FUTEX_H
 12 #define _ASM_FUTEX_H
 13 
 14 #include <linux/futex.h>
 15 #include <linux/preempt.h>
 16 #include <linux/uaccess.h>
 17 #include <asm/errno.h>
 18 
 19 #ifdef CONFIG_ARC_HAS_LLSC
 20 
 21 #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg)\
 22                                                         \
 23         smp_mb();                                       \
 24         __asm__ __volatile__(                           \
 25         "1:     llock   %1, [%2]                \n"     \
 26                 insn                            "\n"    \
 27         "2:     scond   %0, [%2]                \n"     \
 28         "       bnz     1b                      \n"     \
 29         "       mov %0, 0                       \n"     \
 30         "3:                                     \n"     \
 31         "       .section .fixup,\"ax\"          \n"     \
 32         "       .align  4                       \n"     \
 33         "4:     mov %0, %4                      \n"     \
 34         "       j   3b                          \n"     \
 35         "       .previous                       \n"     \
 36         "       .section __ex_table,\"a\"       \n"     \
 37         "       .align  4                       \n"     \
 38         "       .word   1b, 4b                  \n"     \
 39         "       .word   2b, 4b                  \n"     \
 40         "       .previous                       \n"     \
 41                                                         \
 42         : "=&r" (ret), "=&r" (oldval)                   \
 43         : "r" (uaddr), "r" (oparg), "ir" (-EFAULT)      \
 44         : "cc", "memory");                              \
 45         smp_mb()                                        \
 46 
 47 #else   /* !CONFIG_ARC_HAS_LLSC */
 48 
 49 #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg)\
 50                                                         \
 51         smp_mb();                                       \
 52         __asm__ __volatile__(                           \
 53         "1:     ld      %1, [%2]                \n"     \
 54                 insn                            "\n"    \
 55         "2:     st      %0, [%2]                \n"     \
 56         "       mov %0, 0                       \n"     \
 57         "3:                                     \n"     \
 58         "       .section .fixup,\"ax\"          \n"     \
 59         "       .align  4                       \n"     \
 60         "4:     mov %0, %4                      \n"     \
 61         "       j   3b                          \n"     \
 62         "       .previous                       \n"     \
 63         "       .section __ex_table,\"a\"       \n"     \
 64         "       .align  4                       \n"     \
 65         "       .word   1b, 4b                  \n"     \
 66         "       .word   2b, 4b                  \n"     \
 67         "       .previous                       \n"     \
 68                                                         \
 69         : "=&r" (ret), "=&r" (oldval)                   \
 70         : "r" (uaddr), "r" (oparg), "ir" (-EFAULT)      \
 71         : "cc", "memory");                              \
 72         smp_mb()                                        \
 73 
 74 #endif
 75 
 76 static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
 77 {
 78         int op = (encoded_op >> 28) & 7;
 79         int cmp = (encoded_op >> 24) & 15;
 80         int oparg = (encoded_op << 8) >> 20;
 81         int cmparg = (encoded_op << 20) >> 20;
 82         int oldval = 0, ret;
 83 
 84         if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
 85                 oparg = 1 << oparg;
 86 
 87         if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
 88                 return -EFAULT;
 89 
 90 #ifndef CONFIG_ARC_HAS_LLSC
 91         preempt_disable();      /* to guarantee atomic r-m-w of futex op */
 92 #endif
 93         pagefault_disable();
 94 
 95         switch (op) {
 96         case FUTEX_OP_SET:
 97                 __futex_atomic_op("mov %0, %3", ret, oldval, uaddr, oparg);
 98                 break;
 99         case FUTEX_OP_ADD:
100                 /* oldval = *uaddr; *uaddr += oparg ; ret = *uaddr */
101                 __futex_atomic_op("add %0, %1, %3", ret, oldval, uaddr, oparg);
102                 break;
103         case FUTEX_OP_OR:
104                 __futex_atomic_op("or  %0, %1, %3", ret, oldval, uaddr, oparg);
105                 break;
106         case FUTEX_OP_ANDN:
107                 __futex_atomic_op("bic %0, %1, %3", ret, oldval, uaddr, oparg);
108                 break;
109         case FUTEX_OP_XOR:
110                 __futex_atomic_op("xor %0, %1, %3", ret, oldval, uaddr, oparg);
111                 break;
112         default:
113                 ret = -ENOSYS;
114         }
115 
116         pagefault_enable();
117 #ifndef CONFIG_ARC_HAS_LLSC
118         preempt_enable();
119 #endif
120 
121         if (!ret) {
122                 switch (cmp) {
123                 case FUTEX_OP_CMP_EQ:
124                         ret = (oldval == cmparg);
125                         break;
126                 case FUTEX_OP_CMP_NE:
127                         ret = (oldval != cmparg);
128                         break;
129                 case FUTEX_OP_CMP_LT:
130                         ret = (oldval < cmparg);
131                         break;
132                 case FUTEX_OP_CMP_GE:
133                         ret = (oldval >= cmparg);
134                         break;
135                 case FUTEX_OP_CMP_LE:
136                         ret = (oldval <= cmparg);
137                         break;
138                 case FUTEX_OP_CMP_GT:
139                         ret = (oldval > cmparg);
140                         break;
141                 default:
142                         ret = -ENOSYS;
143                 }
144         }
145         return ret;
146 }
147 
148 /*
149  * cmpxchg of futex (pagefaults disabled by caller)
150  * Return 0 for success, -EFAULT otherwise
151  */
152 static inline int
153 futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 expval,
154                               u32 newval)
155 {
156         int ret = 0;
157         u32 existval;
158 
159         if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
160                 return -EFAULT;
161 
162 #ifndef CONFIG_ARC_HAS_LLSC
163         preempt_disable();      /* to guarantee atomic r-m-w of futex op */
164 #endif
165         smp_mb();
166 
167         __asm__ __volatile__(
168 #ifdef CONFIG_ARC_HAS_LLSC
169         "1:     llock   %1, [%4]                \n"
170         "       brne    %1, %2, 3f              \n"
171         "2:     scond   %3, [%4]                \n"
172         "       bnz     1b                      \n"
173 #else
174         "1:     ld      %1, [%4]                \n"
175         "       brne    %1, %2, 3f              \n"
176         "2:     st      %3, [%4]                \n"
177 #endif
178         "3:     \n"
179         "       .section .fixup,\"ax\"  \n"
180         "4:     mov %0, %5      \n"
181         "       j   3b  \n"
182         "       .previous       \n"
183         "       .section __ex_table,\"a\"       \n"
184         "       .align  4       \n"
185         "       .word   1b, 4b  \n"
186         "       .word   2b, 4b  \n"
187         "       .previous\n"
188         : "+&r"(ret), "=&r"(existval)
189         : "r"(expval), "r"(newval), "r"(uaddr), "ir"(-EFAULT)
190         : "cc", "memory");
191 
192         smp_mb();
193 
194 #ifndef CONFIG_ARC_HAS_LLSC
195         preempt_enable();
196 #endif
197         *uval = existval;
198         return ret;
199 }
200 
201 #endif
202 

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

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | 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.

osdn.jp