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

TOMOYO Linux Cross Reference
Linux/arch/alpha/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 #ifndef __ALPHA_UACCESS_H
  3 #define __ALPHA_UACCESS_H
  4 
  5 #include <asm-generic/access_ok.h>
  6 /*
  7  * These are the main single-value transfer routines.  They automatically
  8  * use the right size if we just have the right pointer type.
  9  *
 10  * As the alpha uses the same address space for kernel and user
 11  * data, we can just do these as direct assignments.  (Of course, the
 12  * exception handling means that it's no longer "just"...)
 13  *
 14  * Careful to not
 15  * (a) re-use the arguments for side effects (sizeof/typeof is ok)
 16  * (b) require any knowledge of processes at this stage
 17  */
 18 #define put_user(x, ptr) \
 19   __put_user_check((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
 20 #define get_user(x, ptr) \
 21   __get_user_check((x), (ptr), sizeof(*(ptr)))
 22 
 23 /*
 24  * The "__xxx" versions do not do address space checking, useful when
 25  * doing multiple accesses to the same area (the programmer has to do the
 26  * checks by hand with "access_ok()")
 27  */
 28 #define __put_user(x, ptr) \
 29   __put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
 30 #define __get_user(x, ptr) \
 31   __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
 32   
 33 /*
 34  * The "lda %1, 2b-1b(%0)" bits are magic to get the assembler to
 35  * encode the bits we need for resolving the exception.  See the
 36  * more extensive comments with fixup_inline_exception below for
 37  * more information.
 38  */
 39 #define EXC(label,cont,res,err)                         \
 40         ".section __ex_table,\"a\"\n"                   \
 41         "       .long "#label"-.\n"                     \
 42         "       lda "#res","#cont"-"#label"("#err")\n"  \
 43         ".previous\n"
 44 
 45 extern void __get_user_unknown(void);
 46 
 47 #define __get_user_nocheck(x, ptr, size)                        \
 48 ({                                                              \
 49         long __gu_err = 0;                                      \
 50         unsigned long __gu_val;                                 \
 51         __chk_user_ptr(ptr);                                    \
 52         switch (size) {                                         \
 53           case 1: __get_user_8(ptr); break;                     \
 54           case 2: __get_user_16(ptr); break;                    \
 55           case 4: __get_user_32(ptr); break;                    \
 56           case 8: __get_user_64(ptr); break;                    \
 57           default: __get_user_unknown(); break;                 \
 58         }                                                       \
 59         (x) = (__force __typeof__(*(ptr))) __gu_val;            \
 60         __gu_err;                                               \
 61 })
 62 
 63 #define __get_user_check(x, ptr, size)                          \
 64 ({                                                              \
 65         long __gu_err = -EFAULT;                                \
 66         unsigned long __gu_val = 0;                             \
 67         const __typeof__(*(ptr)) __user *__gu_addr = (ptr);     \
 68         if (__access_ok(__gu_addr, size)) {                     \
 69                 __gu_err = 0;                                   \
 70                 switch (size) {                                 \
 71                   case 1: __get_user_8(__gu_addr); break;       \
 72                   case 2: __get_user_16(__gu_addr); break;      \
 73                   case 4: __get_user_32(__gu_addr); break;      \
 74                   case 8: __get_user_64(__gu_addr); break;      \
 75                   default: __get_user_unknown(); break;         \
 76                 }                                               \
 77         }                                                       \
 78         (x) = (__force __typeof__(*(ptr))) __gu_val;            \
 79         __gu_err;                                               \
 80 })
 81 
 82 struct __large_struct { unsigned long buf[100]; };
 83 #define __m(x) (*(struct __large_struct __user *)(x))
 84 
 85 #define __get_user_64(addr)                             \
 86         __asm__("1: ldq %0,%2\n"                        \
 87         "2:\n"                                          \
 88         EXC(1b,2b,%0,%1)                                \
 89                 : "=r"(__gu_val), "=r"(__gu_err)        \
 90                 : "m"(__m(addr)), "1"(__gu_err))
 91 
 92 #define __get_user_32(addr)                             \
 93         __asm__("1: ldl %0,%2\n"                        \
 94         "2:\n"                                          \
 95         EXC(1b,2b,%0,%1)                                \
 96                 : "=r"(__gu_val), "=r"(__gu_err)        \
 97                 : "m"(__m(addr)), "1"(__gu_err))
 98 
 99 #define __get_user_16(addr)                             \
100         __asm__("1: ldwu %0,%2\n"                       \
101         "2:\n"                                          \
102         EXC(1b,2b,%0,%1)                                \
103                 : "=r"(__gu_val), "=r"(__gu_err)        \
104                 : "m"(__m(addr)), "1"(__gu_err))
105 
106 #define __get_user_8(addr)                              \
107         __asm__("1: ldbu %0,%2\n"                       \
108         "2:\n"                                          \
109         EXC(1b,2b,%0,%1)                                \
110                 : "=r"(__gu_val), "=r"(__gu_err)        \
111                 : "m"(__m(addr)), "1"(__gu_err))
112 
113 extern void __put_user_unknown(void);
114 
115 #define __put_user_nocheck(x, ptr, size)                        \
116 ({                                                              \
117         long __pu_err = 0;                                      \
118         __chk_user_ptr(ptr);                                    \
119         switch (size) {                                         \
120           case 1: __put_user_8(x, ptr); break;                  \
121           case 2: __put_user_16(x, ptr); break;                 \
122           case 4: __put_user_32(x, ptr); break;                 \
123           case 8: __put_user_64(x, ptr); break;                 \
124           default: __put_user_unknown(); break;                 \
125         }                                                       \
126         __pu_err;                                               \
127 })
128 
129 #define __put_user_check(x, ptr, size)                          \
130 ({                                                              \
131         long __pu_err = -EFAULT;                                \
132         __typeof__(*(ptr)) __user *__pu_addr = (ptr);           \
133         if (__access_ok(__pu_addr, size)) {                     \
134                 __pu_err = 0;                                   \
135                 switch (size) {                                 \
136                   case 1: __put_user_8(x, __pu_addr); break;    \
137                   case 2: __put_user_16(x, __pu_addr); break;   \
138                   case 4: __put_user_32(x, __pu_addr); break;   \
139                   case 8: __put_user_64(x, __pu_addr); break;   \
140                   default: __put_user_unknown(); break;         \
141                 }                                               \
142         }                                                       \
143         __pu_err;                                               \
144 })
145 
146 /*
147  * The "__put_user_xx()" macros tell gcc they read from memory
148  * instead of writing: this is because they do not write to
149  * any memory gcc knows about, so there are no aliasing issues
150  */
151 #define __put_user_64(x, addr)                                  \
152 __asm__ __volatile__("1: stq %r2,%1\n"                          \
153         "2:\n"                                                  \
154         EXC(1b,2b,$31,%0)                                       \
155                 : "=r"(__pu_err)                                \
156                 : "m" (__m(addr)), "rJ" (x), ""(__pu_err))
157 
158 #define __put_user_32(x, addr)                                  \
159 __asm__ __volatile__("1: stl %r2,%1\n"                          \
160         "2:\n"                                                  \
161         EXC(1b,2b,$31,%0)                                       \
162                 : "=r"(__pu_err)                                \
163                 : "m"(__m(addr)), "rJ"(x), ""(__pu_err))
164 
165 #define __put_user_16(x, addr)                                  \
166 __asm__ __volatile__("1: stw %r2,%1\n"                          \
167         "2:\n"                                                  \
168         EXC(1b,2b,$31,%0)                                       \
169                 : "=r"(__pu_err)                                \
170                 : "m"(__m(addr)), "rJ"(x), ""(__pu_err))
171 
172 #define __put_user_8(x, addr)                                   \
173 __asm__ __volatile__("1: stb %r2,%1\n"                          \
174         "2:\n"                                                  \
175         EXC(1b,2b,$31,%0)                                       \
176                 : "=r"(__pu_err)                                \
177                 : "m"(__m(addr)), "rJ"(x), ""(__pu_err))
178 
179 /*
180  * Complex access routines
181  */
182 
183 extern long __copy_user(void *to, const void *from, long len);
184 
185 static inline unsigned long
186 raw_copy_from_user(void *to, const void __user *from, unsigned long len)
187 {
188         return __copy_user(to, (__force const void *)from, len);
189 }
190 
191 static inline unsigned long
192 raw_copy_to_user(void __user *to, const void *from, unsigned long len)
193 {
194         return __copy_user((__force void *)to, from, len);
195 }
196 
197 extern long __clear_user(void __user *to, long len);
198 
199 static inline long
200 clear_user(void __user *to, long len)
201 {
202         if (__access_ok(to, len))
203                 len = __clear_user(to, len);
204         return len;
205 }
206 
207 extern long strncpy_from_user(char *dest, const char __user *src, long count);
208 extern __must_check long strnlen_user(const char __user *str, long n);
209 
210 #include <asm/extable.h>
211 
212 #endif /* __ALPHA_UACCESS_H */
213 

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