]> git.karo-electronics.de Git - karo-tx-linux.git/blob - arch/metag/include/asm/uaccess.h
new helper: uaccess_kernel()
[karo-tx-linux.git] / arch / metag / include / asm / uaccess.h
1 #ifndef __METAG_UACCESS_H
2 #define __METAG_UACCESS_H
3
4 /*
5  * User space memory access functions
6  */
7
8 /*
9  * The fs value determines whether argument validity checking should be
10  * performed or not.  If get_fs() == USER_DS, checking is performed, with
11  * get_fs() == KERNEL_DS, checking is bypassed.
12  *
13  * For historical reasons, these macros are grossly misnamed.
14  */
15
16 #define MAKE_MM_SEG(s)  ((mm_segment_t) { (s) })
17
18 #define KERNEL_DS       MAKE_MM_SEG(0xFFFFFFFF)
19 #define USER_DS         MAKE_MM_SEG(PAGE_OFFSET)
20
21 #define get_ds()        (KERNEL_DS)
22 #define get_fs()        (current_thread_info()->addr_limit)
23 #define set_fs(x)       (current_thread_info()->addr_limit = (x))
24
25 #define segment_eq(a, b)        ((a).seg == (b).seg)
26
27 #define __kernel_ok (uaccess_kernel())
28 /*
29  * Explicitly allow NULL pointers here. Parts of the kernel such
30  * as readv/writev use access_ok to validate pointers, but want
31  * to allow NULL pointers for various reasons. NULL pointers are
32  * safe to allow through because the first page is not mappable on
33  * Meta.
34  *
35  * We also wish to avoid letting user code access the system area
36  * and the kernel half of the address space.
37  */
38 #define __user_bad(addr, size) (((addr) > 0 && (addr) < META_MEMORY_BASE) || \
39                                 ((addr) > PAGE_OFFSET &&                \
40                                  (addr) < LINCORE_BASE))
41
42 static inline int __access_ok(unsigned long addr, unsigned long size)
43 {
44         return __kernel_ok || !__user_bad(addr, size);
45 }
46
47 #define access_ok(type, addr, size) __access_ok((unsigned long)(addr),  \
48                                                 (unsigned long)(size))
49
50 static inline int verify_area(int type, const void *addr, unsigned long size)
51 {
52         return access_ok(type, addr, size) ? 0 : -EFAULT;
53 }
54
55 /*
56  * The exception table consists of pairs of addresses: the first is the
57  * address of an instruction that is allowed to fault, and the second is
58  * the address at which the program should continue.  No registers are
59  * modified, so it is entirely up to the continuation code to figure out
60  * what to do.
61  *
62  * All the routines below use bits of fixup code that are out of line
63  * with the main instruction path.  This means when everything is well,
64  * we don't even have to jump over them.  Further, they do not intrude
65  * on our cache or tlb entries.
66  */
67 struct exception_table_entry {
68         unsigned long insn, fixup;
69 };
70
71 extern int fixup_exception(struct pt_regs *regs);
72
73 /*
74  * These are the main single-value transfer routines.  They automatically
75  * use the right size if we just have the right pointer type.
76  */
77
78 #define put_user(x, ptr) \
79         __put_user_check((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
80 #define __put_user(x, ptr) \
81         __put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
82
83 extern void __put_user_bad(void);
84
85 #define __put_user_nocheck(x, ptr, size)                \
86 ({                                                      \
87         long __pu_err;                                  \
88         __put_user_size((x), (ptr), (size), __pu_err);  \
89         __pu_err;                                       \
90 })
91
92 #define __put_user_check(x, ptr, size)                          \
93 ({                                                              \
94         long __pu_err = -EFAULT;                                \
95         __typeof__(*(ptr)) __user *__pu_addr = (ptr);           \
96         if (access_ok(VERIFY_WRITE, __pu_addr, size))           \
97                 __put_user_size((x), __pu_addr, (size), __pu_err);      \
98         __pu_err;                                               \
99 })
100
101 extern long __put_user_asm_b(unsigned int x, void __user *addr);
102 extern long __put_user_asm_w(unsigned int x, void __user *addr);
103 extern long __put_user_asm_d(unsigned int x, void __user *addr);
104 extern long __put_user_asm_l(unsigned long long x, void __user *addr);
105
106 #define __put_user_size(x, ptr, size, retval)                           \
107 do {                                                                    \
108         retval = 0;                                                     \
109         switch (size) {                                                 \
110         case 1:                                                         \
111                 retval = __put_user_asm_b((__force unsigned int)x, ptr);\
112                 break;                                                  \
113         case 2:                                                         \
114                 retval = __put_user_asm_w((__force unsigned int)x, ptr);\
115                 break;                                                  \
116         case 4:                                                         \
117                 retval = __put_user_asm_d((__force unsigned int)x, ptr);\
118                 break;                                                  \
119         case 8:                                                         \
120                 retval = __put_user_asm_l((__force unsigned long long)x,\
121                                           ptr);                         \
122                 break;                                                  \
123         default:                                                        \
124                 __put_user_bad();                                       \
125         }                                                               \
126 } while (0)
127
128 #define get_user(x, ptr) \
129         __get_user_check((x), (ptr), sizeof(*(ptr)))
130 #define __get_user(x, ptr) \
131         __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
132
133 extern long __get_user_bad(void);
134
135 #define __get_user_nocheck(x, ptr, size)                        \
136 ({                                                              \
137         long __gu_err, __gu_val;                                \
138         __get_user_size(__gu_val, (ptr), (size), __gu_err);     \
139         (x) = (__force __typeof__(*(ptr)))__gu_val;             \
140         __gu_err;                                               \
141 })
142
143 #define __get_user_check(x, ptr, size)                                  \
144 ({                                                                      \
145         long __gu_err = -EFAULT, __gu_val = 0;                          \
146         const __typeof__(*(ptr)) __user *__gu_addr = (ptr);             \
147         if (access_ok(VERIFY_READ, __gu_addr, size))                    \
148                 __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
149         (x) = (__force __typeof__(*(ptr)))__gu_val;                     \
150         __gu_err;                                                       \
151 })
152
153 extern unsigned char __get_user_asm_b(const void __user *addr, long *err);
154 extern unsigned short __get_user_asm_w(const void __user *addr, long *err);
155 extern unsigned int __get_user_asm_d(const void __user *addr, long *err);
156
157 #define __get_user_size(x, ptr, size, retval)                   \
158 do {                                                            \
159         retval = 0;                                             \
160         switch (size) {                                         \
161         case 1:                                                 \
162                 x = __get_user_asm_b(ptr, &retval); break;      \
163         case 2:                                                 \
164                 x = __get_user_asm_w(ptr, &retval); break;      \
165         case 4:                                                 \
166                 x = __get_user_asm_d(ptr, &retval); break;      \
167         default:                                                \
168                 (x) = __get_user_bad();                         \
169         }                                                       \
170 } while (0)
171
172 /*
173  * Copy a null terminated string from userspace.
174  *
175  * Must return:
176  * -EFAULT              for an exception
177  * count                if we hit the buffer limit
178  * bytes copied         if we hit a null byte
179  * (without the null byte)
180  */
181
182 extern long __must_check __strncpy_from_user(char *dst, const char __user *src,
183                                              long count);
184
185 #define strncpy_from_user(dst, src, count) __strncpy_from_user(dst, src, count)
186
187 /*
188  * Return the size of a string (including the ending 0)
189  *
190  * Return 0 on exception, a value greater than N if too long
191  */
192 extern long __must_check strnlen_user(const char __user *src, long count);
193
194 #define strlen_user(str) strnlen_user(str, 32767)
195
196 extern unsigned long __must_check __copy_user_zeroing(void *to,
197                                                       const void __user *from,
198                                                       unsigned long n);
199
200 static inline unsigned long
201 copy_from_user(void *to, const void __user *from, unsigned long n)
202 {
203         if (likely(access_ok(VERIFY_READ, from, n)))
204                 return __copy_user_zeroing(to, from, n);
205         memset(to, 0, n);
206         return n;
207 }
208
209 #define __copy_from_user(to, from, n) __copy_user_zeroing(to, from, n)
210 #define __copy_from_user_inatomic __copy_from_user
211
212 extern unsigned long __must_check __copy_user(void __user *to,
213                                               const void *from,
214                                               unsigned long n);
215
216 static inline unsigned long copy_to_user(void __user *to, const void *from,
217                                          unsigned long n)
218 {
219         if (access_ok(VERIFY_WRITE, to, n))
220                 return __copy_user(to, from, n);
221         return n;
222 }
223
224 #define __copy_to_user(to, from, n) __copy_user(to, from, n)
225 #define __copy_to_user_inatomic __copy_to_user
226
227 /*
228  * Zero Userspace
229  */
230
231 extern unsigned long __must_check __do_clear_user(void __user *to,
232                                                   unsigned long n);
233
234 static inline unsigned long clear_user(void __user *to, unsigned long n)
235 {
236         if (access_ok(VERIFY_WRITE, to, n))
237                 return __do_clear_user(to, n);
238         return n;
239 }
240
241 #define __clear_user(to, n)            __do_clear_user(to, n)
242
243 #endif /* _METAG_UACCESS_H */