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

TOMOYO Linux Cross Reference
Linux/arch/microblaze/include/asm/uaccess.h

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ 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 /*
  3  * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
  4  * Copyright (C) 2008-2009 PetaLogix
  5  * Copyright (C) 2006 Atmark Techno, Inc.
  6  */
  7 
  8 #ifndef _ASM_MICROBLAZE_UACCESS_H
  9 #define _ASM_MICROBLAZE_UACCESS_H
 10 
 11 #include <linux/kernel.h>
 12 
 13 #include <asm/mmu.h>
 14 #include <asm/page.h>
 15 #include <linux/pgtable.h>
 16 #include <asm/extable.h>
 17 #include <linux/string.h>
 18 #include <asm-generic/access_ok.h>
 19 
 20 # define __FIXUP_SECTION        ".section .fixup,\"ax\"\n"
 21 # define __EX_TABLE_SECTION     ".section __ex_table,\"a\"\n"
 22 
 23 extern unsigned long __copy_tofrom_user(void __user *to,
 24                 const void __user *from, unsigned long size);
 25 
 26 /* Return: number of not copied bytes, i.e. 0 if OK or non-zero if fail. */
 27 static inline unsigned long __must_check __clear_user(void __user *to,
 28                                                         unsigned long n)
 29 {
 30         /* normal memset with two words to __ex_table */
 31         __asm__ __volatile__ (                          \
 32                         "1:     sb      r0, %1, r0;"    \
 33                         "       addik   %0, %0, -1;"    \
 34                         "       bneid   %0, 1b;"        \
 35                         "       addik   %1, %1, 1;"     \
 36                         "2:                     "       \
 37                         __EX_TABLE_SECTION              \
 38                         ".word  1b,2b;"                 \
 39                         ".previous;"                    \
 40                 : "=r"(n), "=r"(to)                     \
 41                 : ""(n), "1"(to)
 42         );
 43         return n;
 44 }
 45 
 46 static inline unsigned long __must_check clear_user(void __user *to,
 47                                                         unsigned long n)
 48 {
 49         might_fault();
 50         if (unlikely(!access_ok(to, n)))
 51                 return n;
 52 
 53         return __clear_user(to, n);
 54 }
 55 
 56 /* put_user and get_user macros */
 57 extern long __user_bad(void);
 58 
 59 #define __get_user_asm(insn, __gu_ptr, __gu_val, __gu_err)      \
 60 ({                                                              \
 61         __asm__ __volatile__ (                                  \
 62                         "1:"    insn    " %1, %2, r0;"          \
 63                         "       addk    %0, r0, r0;"            \
 64                         "2:                     "               \
 65                         __FIXUP_SECTION                         \
 66                         "3:     brid    2b;"                    \
 67                         "       addik   %0, r0, %3;"            \
 68                         ".previous;"                            \
 69                         __EX_TABLE_SECTION                      \
 70                         ".word  1b,3b;"                         \
 71                         ".previous;"                            \
 72                 : "=&r"(__gu_err), "=r"(__gu_val)               \
 73                 : "r"(__gu_ptr), "i"(-EFAULT)                   \
 74         );                                                      \
 75 })
 76 
 77 /**
 78  * get_user: - Get a simple variable from user space.
 79  * @x:   Variable to store result.
 80  * @ptr: Source address, in user space.
 81  *
 82  * Context: User context only. This function may sleep if pagefaults are
 83  *          enabled.
 84  *
 85  * This macro copies a single simple variable from user space to kernel
 86  * space.  It supports simple types like char and int, but not larger
 87  * data types like structures or arrays.
 88  *
 89  * @ptr must have pointer-to-simple-variable type, and the result of
 90  * dereferencing @ptr must be assignable to @x without a cast.
 91  *
 92  * Returns zero on success, or -EFAULT on error.
 93  * On error, the variable @x is set to zero.
 94  */
 95 #define get_user(x, ptr) ({                             \
 96         const typeof(*(ptr)) __user *__gu_ptr = (ptr);  \
 97         access_ok(__gu_ptr, sizeof(*__gu_ptr)) ?        \
 98                 __get_user(x, __gu_ptr) : -EFAULT;      \
 99 })
100 
101 #define __get_user(x, ptr)                                              \
102 ({                                                                      \
103         long __gu_err;                                                  \
104         switch (sizeof(*(ptr))) {                                       \
105         case 1:                                                         \
106                 __get_user_asm("lbu", (ptr), x, __gu_err);              \
107                 break;                                                  \
108         case 2:                                                         \
109                 __get_user_asm("lhu", (ptr), x, __gu_err);              \
110                 break;                                                  \
111         case 4:                                                         \
112                 __get_user_asm("lw", (ptr), x, __gu_err);               \
113                 break;                                                  \
114         case 8: {                                                       \
115                 __u64 __x = 0;                                          \
116                 __gu_err = raw_copy_from_user(&__x, ptr, 8) ?           \
117                                                         -EFAULT : 0;    \
118                 (x) = (typeof(x))(typeof((x) - (x)))__x;                \
119                 break;                                                  \
120         }                                                               \
121         default:                                                        \
122                 /* __gu_val = 0; __gu_err = -EINVAL;*/ __gu_err = __user_bad();\
123         }                                                               \
124         __gu_err;                                                       \
125 })
126 
127 
128 #define __put_user_asm(insn, __gu_ptr, __gu_val, __gu_err)      \
129 ({                                                              \
130         __asm__ __volatile__ (                                  \
131                         "1:"    insn    " %1, %2, r0;"          \
132                         "       addk    %0, r0, r0;"            \
133                         "2:                     "               \
134                         __FIXUP_SECTION                         \
135                         "3:     brid    2b;"                    \
136                         "       addik   %0, r0, %3;"            \
137                         ".previous;"                            \
138                         __EX_TABLE_SECTION                      \
139                         ".word  1b,3b;"                         \
140                         ".previous;"                            \
141                 : "=&r"(__gu_err)                               \
142                 : "r"(__gu_val), "r"(__gu_ptr), "i"(-EFAULT)    \
143         );                                                      \
144 })
145 
146 #define __put_user_asm_8(__gu_ptr, __gu_val, __gu_err)          \
147 ({                                                              \
148         __asm__ __volatile__ (" lwi     %0, %1, 0;"             \
149                         "1:     swi     %0, %2, 0;"             \
150                         "       lwi     %0, %1, 4;"             \
151                         "2:     swi     %0, %2, 4;"             \
152                         "       addk    %0, r0, r0;"            \
153                         "3:                     "               \
154                         __FIXUP_SECTION                         \
155                         "4:     brid    3b;"                    \
156                         "       addik   %0, r0, %3;"            \
157                         ".previous;"                            \
158                         __EX_TABLE_SECTION                      \
159                         ".word  1b,4b,2b,4b;"                   \
160                         ".previous;"                            \
161                 : "=&r"(__gu_err)                               \
162                 : "r"(&__gu_val), "r"(__gu_ptr), "i"(-EFAULT)   \
163                 );                                              \
164 })
165 
166 /**
167  * put_user: - Write a simple value into user space.
168  * @x:   Value to copy to user space.
169  * @ptr: Destination address, in user space.
170  *
171  * Context: User context only. This function may sleep if pagefaults are
172  *          enabled.
173  *
174  * This macro copies a single simple value from kernel space to user
175  * space.  It supports simple types like char and int, but not larger
176  * data types like structures or arrays.
177  *
178  * @ptr must have pointer-to-simple-variable type, and @x must be assignable
179  * to the result of dereferencing @ptr.
180  *
181  * Returns zero on success, or -EFAULT on error.
182  */
183 #define put_user(x, ptr)                                                \
184         __put_user_check((x), (ptr), sizeof(*(ptr)))
185 
186 #define __put_user_check(x, ptr, size)                                  \
187 ({                                                                      \
188         typeof(*(ptr)) volatile __pu_val = x;                           \
189         typeof(*(ptr)) __user *__pu_addr = (ptr);                       \
190         int __pu_err = 0;                                               \
191                                                                         \
192         if (access_ok(__pu_addr, size)) {                       \
193                 switch (size) {                                         \
194                 case 1:                                                 \
195                         __put_user_asm("sb", __pu_addr, __pu_val,       \
196                                        __pu_err);                       \
197                         break;                                          \
198                 case 2:                                                 \
199                         __put_user_asm("sh", __pu_addr, __pu_val,       \
200                                        __pu_err);                       \
201                         break;                                          \
202                 case 4:                                                 \
203                         __put_user_asm("sw", __pu_addr, __pu_val,       \
204                                        __pu_err);                       \
205                         break;                                          \
206                 case 8:                                                 \
207                         __put_user_asm_8(__pu_addr, __pu_val, __pu_err);\
208                         break;                                          \
209                 default:                                                \
210                         __pu_err = __user_bad();                        \
211                         break;                                          \
212                 }                                                       \
213         } else {                                                        \
214                 __pu_err = -EFAULT;                                     \
215         }                                                               \
216         __pu_err;                                                       \
217 })
218 
219 #define __put_user(x, ptr)                                              \
220 ({                                                                      \
221         __typeof__(*(ptr)) volatile __gu_val = (x);                     \
222         long __gu_err = 0;                                              \
223         switch (sizeof(__gu_val)) {                                     \
224         case 1:                                                         \
225                 __put_user_asm("sb", (ptr), __gu_val, __gu_err);        \
226                 break;                                                  \
227         case 2:                                                         \
228                 __put_user_asm("sh", (ptr), __gu_val, __gu_err);        \
229                 break;                                                  \
230         case 4:                                                         \
231                 __put_user_asm("sw", (ptr), __gu_val, __gu_err);        \
232                 break;                                                  \
233         case 8:                                                         \
234                 __put_user_asm_8((ptr), __gu_val, __gu_err);            \
235                 break;                                                  \
236         default:                                                        \
237                 /*__gu_err = -EINVAL;*/ __gu_err = __user_bad();        \
238         }                                                               \
239         __gu_err;                                                       \
240 })
241 
242 static inline unsigned long
243 raw_copy_from_user(void *to, const void __user *from, unsigned long n)
244 {
245         return __copy_tofrom_user((__force void __user *)to, from, n);
246 }
247 
248 static inline unsigned long
249 raw_copy_to_user(void __user *to, const void *from, unsigned long n)
250 {
251         return __copy_tofrom_user(to, (__force const void __user *)from, n);
252 }
253 #define INLINE_COPY_FROM_USER
254 #define INLINE_COPY_TO_USER
255 
256 /*
257  * Copy a null terminated string from userspace.
258  */
259 __must_check long strncpy_from_user(char *dst, const char __user *src,
260                                     long count);
261 
262 /*
263  * Return the size of a string (including the ending 0)
264  *
265  * Return 0 on exception, a value greater than N if too long
266  */
267 __must_check long strnlen_user(const char __user *sstr, long len);
268 
269 #endif /* _ASM_MICROBLAZE_UACCESS_H */
270 

~ [ 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