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

TOMOYO Linux Cross Reference
Linux/arch/loongarch/include/asm/uaccess.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 /*
  3  * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
  4  *
  5  * Derived from MIPS:
  6  * Copyright (C) 1996, 1997, 1998, 1999, 2000, 03, 04 by Ralf Baechle
  7  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  8  * Copyright (C) 2007  Maciej W. Rozycki
  9  * Copyright (C) 2014, Imagination Technologies Ltd.
 10  */
 11 #ifndef _ASM_UACCESS_H
 12 #define _ASM_UACCESS_H
 13 
 14 #include <linux/kernel.h>
 15 #include <linux/string.h>
 16 #include <linux/extable.h>
 17 #include <asm/pgtable.h>
 18 #include <asm/extable.h>
 19 #include <asm/asm-extable.h>
 20 #include <asm-generic/access_ok.h>
 21 
 22 extern u64 __ua_limit;
 23 
 24 #define __UA_ADDR       ".dword"
 25 #define __UA_LIMIT      __ua_limit
 26 
 27 /*
 28  * get_user: - Get a simple variable from user space.
 29  * @x:   Variable to store result.
 30  * @ptr: Source address, in user space.
 31  *
 32  * Context: User context only. This function may sleep if pagefaults are
 33  *          enabled.
 34  *
 35  * This macro copies a single simple variable from user space to kernel
 36  * space.  It supports simple types like char and int, but not larger
 37  * data types like structures or arrays.
 38  *
 39  * @ptr must have pointer-to-simple-variable type, and the result of
 40  * dereferencing @ptr must be assignable to @x without a cast.
 41  *
 42  * Returns zero on success, or -EFAULT on error.
 43  * On error, the variable @x is set to zero.
 44  */
 45 #define get_user(x, ptr) \
 46 ({                                                                      \
 47         const __typeof__(*(ptr)) __user *__p = (ptr);                   \
 48                                                                         \
 49         might_fault();                                                  \
 50         access_ok(__p, sizeof(*__p)) ? __get_user((x), __p) :           \
 51                                        ((x) = 0, -EFAULT);              \
 52 })
 53 
 54 /*
 55  * put_user: - Write a simple value into user space.
 56  * @x:   Value to copy to user space.
 57  * @ptr: Destination address, in user space.
 58  *
 59  * Context: User context only. This function may sleep if pagefaults are
 60  *          enabled.
 61  *
 62  * This macro copies a single simple value from kernel space to user
 63  * space.  It supports simple types like char and int, but not larger
 64  * data types like structures or arrays.
 65  *
 66  * @ptr must have pointer-to-simple-variable type, and @x must be assignable
 67  * to the result of dereferencing @ptr.
 68  *
 69  * Returns zero on success, or -EFAULT on error.
 70  */
 71 #define put_user(x, ptr) \
 72 ({                                                                      \
 73         __typeof__(*(ptr)) __user *__p = (ptr);                         \
 74                                                                         \
 75         might_fault();                                                  \
 76         access_ok(__p, sizeof(*__p)) ? __put_user((x), __p) : -EFAULT;  \
 77 })
 78 
 79 /*
 80  * __get_user: - Get a simple variable from user space, with less checking.
 81  * @x:   Variable to store result.
 82  * @ptr: Source address, in user space.
 83  *
 84  * Context: User context only. This function may sleep if pagefaults are
 85  *          enabled.
 86  *
 87  * This macro copies a single simple variable from user space to kernel
 88  * space.  It supports simple types like char and int, but not larger
 89  * data types like structures or arrays.
 90  *
 91  * @ptr must have pointer-to-simple-variable type, and the result of
 92  * dereferencing @ptr must be assignable to @x without a cast.
 93  *
 94  * Caller must check the pointer with access_ok() before calling this
 95  * function.
 96  *
 97  * Returns zero on success, or -EFAULT on error.
 98  * On error, the variable @x is set to zero.
 99  */
100 #define __get_user(x, ptr) \
101 ({                                                                      \
102         int __gu_err = 0;                                               \
103                                                                         \
104         __chk_user_ptr(ptr);                                            \
105         __get_user_common((x), sizeof(*(ptr)), ptr);                    \
106         __gu_err;                                                       \
107 })
108 
109 /*
110  * __put_user: - Write a simple value into user space, with less checking.
111  * @x:   Value to copy to user space.
112  * @ptr: Destination address, in user space.
113  *
114  * Context: User context only. This function may sleep if pagefaults are
115  *          enabled.
116  *
117  * This macro copies a single simple value from kernel space to user
118  * space.  It supports simple types like char and int, but not larger
119  * data types like structures or arrays.
120  *
121  * @ptr must have pointer-to-simple-variable type, and @x must be assignable
122  * to the result of dereferencing @ptr.
123  *
124  * Caller must check the pointer with access_ok() before calling this
125  * function.
126  *
127  * Returns zero on success, or -EFAULT on error.
128  */
129 #define __put_user(x, ptr) \
130 ({                                                                      \
131         int __pu_err = 0;                                               \
132         __typeof__(*(ptr)) __pu_val;                                    \
133                                                                         \
134         __pu_val = (x);                                                 \
135         __chk_user_ptr(ptr);                                            \
136         __put_user_common(ptr, sizeof(*(ptr)));                         \
137         __pu_err;                                                       \
138 })
139 
140 struct __large_struct { unsigned long buf[100]; };
141 #define __m(x) (*(struct __large_struct __user *)(x))
142 
143 #define __get_user_common(val, size, ptr)                               \
144 do {                                                                    \
145         switch (size) {                                                 \
146         case 1: __get_data_asm(val, "ld.b", ptr); break;                \
147         case 2: __get_data_asm(val, "ld.h", ptr); break;                \
148         case 4: __get_data_asm(val, "ld.w", ptr); break;                \
149         case 8: __get_data_asm(val, "ld.d", ptr); break;                \
150         default: BUILD_BUG(); break;                                    \
151         }                                                               \
152 } while (0)
153 
154 #define __get_kernel_common(val, size, ptr) __get_user_common(val, size, ptr)
155 
156 #define __get_data_asm(val, insn, ptr)                                  \
157 {                                                                       \
158         long __gu_tmp;                                                  \
159                                                                         \
160         __asm__ __volatile__(                                           \
161         "1:     " insn "        %1, %2                          \n"     \
162         "2:                                                     \n"     \
163         _ASM_EXTABLE_UACCESS_ERR_ZERO(1b, 2b, %0, %1)                   \
164         : "+r" (__gu_err), "=r" (__gu_tmp)                              \
165         : "m" (__m(ptr)));                                              \
166                                                                         \
167         (val) = (__typeof__(*(ptr))) __gu_tmp;                          \
168 }
169 
170 #define __put_user_common(ptr, size)                                    \
171 do {                                                                    \
172         switch (size) {                                                 \
173         case 1: __put_data_asm("st.b", ptr); break;                     \
174         case 2: __put_data_asm("st.h", ptr); break;                     \
175         case 4: __put_data_asm("st.w", ptr); break;                     \
176         case 8: __put_data_asm("st.d", ptr); break;                     \
177         default: BUILD_BUG(); break;                                    \
178         }                                                               \
179 } while (0)
180 
181 #define __put_kernel_common(ptr, size) __put_user_common(ptr, size)
182 
183 #define __put_data_asm(insn, ptr)                                       \
184 {                                                                       \
185         __asm__ __volatile__(                                           \
186         "1:     " insn "        %z2, %1         # __put_user_asm\n"     \
187         "2:                                                     \n"     \
188         _ASM_EXTABLE_UACCESS_ERR(1b, 2b, %0)                            \
189         : "+r" (__pu_err), "=m" (__m(ptr))                              \
190         : "Jr" (__pu_val));                                             \
191 }
192 
193 #define __get_kernel_nofault(dst, src, type, err_label)                 \
194 do {                                                                    \
195         int __gu_err = 0;                                               \
196                                                                         \
197         __get_kernel_common(*((type *)(dst)), sizeof(type),             \
198                             (__force type *)(src));                     \
199         if (unlikely(__gu_err))                                         \
200                 goto err_label;                                         \
201 } while (0)
202 
203 #define __put_kernel_nofault(dst, src, type, err_label)                 \
204 do {                                                                    \
205         type __pu_val;                                                  \
206         int __pu_err = 0;                                               \
207                                                                         \
208         __pu_val = *(__force type *)(src);                              \
209         __put_kernel_common(((type *)(dst)), sizeof(type));             \
210         if (unlikely(__pu_err))                                         \
211                 goto err_label;                                         \
212 } while (0)
213 
214 extern unsigned long __copy_user(void *to, const void *from, __kernel_size_t n);
215 
216 static inline unsigned long __must_check
217 raw_copy_from_user(void *to, const void __user *from, unsigned long n)
218 {
219         return __copy_user(to, (__force const void *)from, n);
220 }
221 
222 static inline unsigned long __must_check
223 raw_copy_to_user(void __user *to, const void *from, unsigned long n)
224 {
225         return __copy_user((__force void *)to, from, n);
226 }
227 
228 #define INLINE_COPY_FROM_USER
229 #define INLINE_COPY_TO_USER
230 
231 /*
232  * __clear_user: - Zero a block of memory in user space, with less checking.
233  * @addr: Destination address, in user space.
234  * @size: Number of bytes to zero.
235  *
236  * Zero a block of memory in user space.  Caller must check
237  * the specified block with access_ok() before calling this function.
238  *
239  * Returns number of bytes that could not be cleared.
240  * On success, this will be zero.
241  */
242 extern unsigned long __clear_user(void __user *addr, __kernel_size_t size);
243 
244 #define clear_user(addr, n)                                             \
245 ({                                                                      \
246         void __user *__cl_addr = (addr);                                \
247         unsigned long __cl_size = (n);                                  \
248         if (__cl_size && access_ok(__cl_addr, __cl_size))               \
249                 __cl_size = __clear_user(__cl_addr, __cl_size);         \
250         __cl_size;                                                      \
251 })
252 
253 extern long strncpy_from_user(char *to, const char __user *from, long n);
254 extern long strnlen_user(const char __user *str, long n);
255 
256 #endif /* _ASM_UACCESS_H */
257 

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