OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [include/] [asm-mips/] [uaccess.h] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1276 phoenix
/*
2
 * This file is subject to the terms and conditions of the GNU General Public
3
 * License.  See the file "COPYING" in the main directory of this archive
4
 * for more details.
5
 *
6
 * Copyright (C) 1996, 1997, 1998, 1999, 2000, 03 by Ralf Baechle
7
 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
8
 */
9
#ifndef _ASM_UACCESS_H
10
#define _ASM_UACCESS_H
11
 
12
#include <linux/compiler.h>
13
#include <linux/errno.h>
14
#include <linux/sched.h>
15
 
16
#define STR(x)  __STR(x)
17
#define __STR(x)  #x
18
 
19
/*
20
 * The fs value determines whether argument validity checking should be
21
 * performed or not.  If get_fs() == USER_DS, checking is performed, with
22
 * get_fs() == KERNEL_DS, checking is bypassed.
23
 *
24
 * For historical reasons, these macros are grossly misnamed.
25
 */
26
#define KERNEL_DS       ((mm_segment_t) { (unsigned long) 0L })
27
#define USER_DS         ((mm_segment_t) { (unsigned long) -1L })
28
 
29
#define VERIFY_READ    0
30
#define VERIFY_WRITE   1
31
 
32
#define get_fs()        (current->thread.current_ds)
33
#define get_ds()        (KERNEL_DS)
34
#define set_fs(x)       (current->thread.current_ds=(x))
35
 
36
#define segment_eq(a,b) ((a).seg == (b).seg)
37
 
38
 
39
/*
40
 * Is a address valid? This does a straighforward calculation rather
41
 * than tests.
42
 *
43
 * Address valid if:
44
 *  - "addr" doesn't have any high-bits set
45
 *  - AND "size" doesn't have any high-bits set
46
 *  - AND "addr+size" doesn't have any high-bits set
47
 *  - OR we are in kernel mode.
48
 */
49
#define __ua_size(size)                                                 \
50
        (__builtin_constant_p(size) && (signed long) (size) > 0 ? 0 : (size))
51
 
52
#define __access_ok(addr,size,mask)                                     \
53
        (((signed long)((mask)&(addr | (addr + size) | __ua_size(size)))) >= 0)
54
 
55
#define __access_mask ((long)(get_fs().seg))
56
 
57
/*
58
 * access_ok: - Checks if a user space pointer is valid
59
 * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE.  Note that
60
 *        %VERIFY_WRITE is a superset of %VERIFY_READ - if it is safe
61
 *        to write to a block, it is always safe to read from it.
62
 * @addr: User space pointer to start of block to check
63
 * @size: Size of block to check
64
 *
65
 * Context: User context only.  This function may sleep.
66
 *
67
 * Checks if a pointer to a block of memory in user space is valid.
68
 *
69
 * Returns true (nonzero) if the memory block may be valid, false (zero)
70
 * if it is definitely invalid.
71
 *
72
 * Note that, depending on architecture, this function probably just
73
 * checks that the pointer is in the user space range - after calling
74
 * this function, memory access functions may still return -EFAULT.
75
 */
76
#define access_ok(type, addr, size)                                     \
77
        likely(__access_ok((unsigned long)(addr), (size), __access_mask))
78
 
79
/*
80
 * verify_area: - Obsolete, use access_ok()
81
 * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE
82
 * @addr: User space pointer to start of block to check
83
 * @size: Size of block to check
84
 *
85
 * Context: User context only.  This function may sleep.
86
 *
87
 * This function has been replaced by access_ok().
88
 *
89
 * Checks if a pointer to a block of memory in user space is valid.
90
 *
91
 * Returns zero if the memory block may be valid, -EFAULT
92
 * if it is definitely invalid.
93
 *
94
 * See access_ok() for more details.
95
 */
96
static inline int verify_area(int type, const void * addr, unsigned long size)
97
{
98
        return access_ok(type, addr, size) ? 0 : -EFAULT;
99
}
100
 
101
/*
102
 * put_user: - Write a simple value into user space.
103
 * @x:   Value to copy to user space.
104
 * @ptr: Destination address, in user space.
105
 *
106
 * Context: User context only.  This function may sleep.
107
 *
108
 * This macro copies a single simple value from kernel space to user
109
 * space.  It supports simple types like char and int, but not larger
110
 * data types like structures or arrays.
111
 *
112
 * @ptr must have pointer-to-simple-variable type, and @x must be assignable
113
 * to the result of dereferencing @ptr.
114
 *
115
 * Returns zero on success, or -EFAULT on error.
116
 */
117
#define put_user(x,ptr) \
118
        __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
119
 
120
/*
121
 * get_user: - Get a simple variable from user space.
122
 * @x:   Variable to store result.
123
 * @ptr: Source address, in user space.
124
 *
125
 * Context: User context only.  This function may sleep.
126
 *
127
 * This macro copies a single simple variable from user space to kernel
128
 * space.  It supports simple types like char and int, but not larger
129
 * data types like structures or arrays.
130
 *
131
 * @ptr must have pointer-to-simple-variable type, and the result of
132
 * dereferencing @ptr must be assignable to @x without a cast.
133
 *
134
 * Returns zero on success, or -EFAULT on error.
135
 * On error, the variable @x is set to zero.
136
 */
137
#define get_user(x,ptr) \
138
        __get_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
139
 
140
/*
141
 * __put_user: - Write a simple value into user space, with less checking.
142
 * @x:   Value to copy to user space.
143
 * @ptr: Destination address, in user space.
144
 *
145
 * Context: User context only.  This function may sleep.
146
 *
147
 * This macro copies a single simple value from kernel space to user
148
 * space.  It supports simple types like char and int, but not larger
149
 * data types like structures or arrays.
150
 *
151
 * @ptr must have pointer-to-simple-variable type, and @x must be assignable
152
 * to the result of dereferencing @ptr.
153
 *
154
 * Caller must check the pointer with access_ok() before calling this
155
 * function.
156
 *
157
 * Returns zero on success, or -EFAULT on error.
158
 */
159
#define __put_user(x,ptr) \
160
        __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
161
 
162
/*
163
 * __get_user: - Get a simple variable from user space, with less checking.
164
 * @x:   Variable to store result.
165
 * @ptr: Source address, in user space.
166
 *
167
 * Context: User context only.  This function may sleep.
168
 *
169
 * This macro copies a single simple variable from user space to kernel
170
 * space.  It supports simple types like char and int, but not larger
171
 * data types like structures or arrays.
172
 *
173
 * @ptr must have pointer-to-simple-variable type, and the result of
174
 * dereferencing @ptr must be assignable to @x without a cast.
175
 *
176
 * Caller must check the pointer with access_ok() before calling this
177
 * function.
178
 *
179
 * Returns zero on success, or -EFAULT on error.
180
 * On error, the variable @x is set to zero.
181
 */
182
#define __get_user(x,ptr) \
183
        __get_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
184
 
185
struct __large_struct { unsigned long buf[100]; };
186
#define __m(x) (*(struct __large_struct *)(x))
187
 
188
/*
189
 * Yuck.  We need two variants, one for 64bit operation and one
190
 * for 32 bit mode and old iron.
191
 */
192
#ifdef __mips64
193
#define __GET_USER_DW __get_user_asm("ld")
194
#else
195
#define __GET_USER_DW __get_user_asm_ll32
196
#endif
197
 
198
#define __get_user_nocheck(x,ptr,size)                                  \
199
({                                                                      \
200
        long __gu_err;                                                  \
201
        __typeof(*(ptr)) __gu_val;                                      \
202
        long __gu_addr;                                                 \
203
        __asm__("":"=r" (__gu_val));                                    \
204
        __gu_addr = (long) (ptr);                                       \
205
        __asm__("":"=r" (__gu_err));                                    \
206
        switch (size) {                                                 \
207
                case 1: __get_user_asm("lb"); break;                    \
208
                case 2: __get_user_asm("lh"); break;                    \
209
                case 4: __get_user_asm("lw"); break;                    \
210
                case 8: __GET_USER_DW; break;                           \
211
                default: __get_user_unknown(); break;                   \
212
        } x = (__typeof__(*(ptr))) __gu_val;                            \
213
        __gu_err;                                                       \
214
})
215
 
216
#define __get_user_check(x,ptr,size)                                    \
217
({                                                                      \
218
        long __gu_err;                                                  \
219
        __typeof__(*(ptr)) __gu_val;                                    \
220
        long __gu_addr;                                                 \
221
        __asm__("":"=r" (__gu_val));                                    \
222
        __gu_addr = (long) (ptr);                                       \
223
        __asm__("":"=r" (__gu_err));                                    \
224
        if (access_ok(VERIFY_READ, __gu_addr, size)) {                  \
225
                switch (size) {                                         \
226
                case 1: __get_user_asm("lb"); break;                    \
227
                case 2: __get_user_asm("lh"); break;                    \
228
                case 4: __get_user_asm("lw"); break;                    \
229
                case 8: __GET_USER_DW; break;                           \
230
                default: __get_user_unknown(); break;                   \
231
                }                                                       \
232
        } x = (__typeof__(*(ptr))) __gu_val;                            \
233
        __gu_err;                                                       \
234
})
235
 
236
#define __get_user_asm(insn)                                            \
237
({                                                                      \
238
        __asm__ __volatile__(                                           \
239
        "1:\t" insn "\t%1,%2\n\t"                                       \
240
        "move\t%0,$0\n"                                                 \
241
        "2:\n\t"                                                        \
242
        ".section\t.fixup,\"ax\"\n"                                     \
243
        "3:\tli\t%0,%3\n\t"                                             \
244
        "move\t%1,$0\n\t"                                               \
245
        "j\t2b\n\t"                                                     \
246
        ".previous\n\t"                                                 \
247
        ".section\t__ex_table,\"a\"\n\t"                                \
248
        ".word\t1b,3b\n\t"                                              \
249
        ".previous"                                                     \
250
        :"=r" (__gu_err), "=r" (__gu_val)                               \
251
        :"o" (__m(__gu_addr)), "i" (-EFAULT));                          \
252
})
253
 
254
/*
255
 * Get a long long 64 using 32 bit registers.
256
 */
257
#define __get_user_asm_ll32                                             \
258
({                                                                      \
259
__asm__ __volatile__(                                                   \
260
        "1:\tlw\t%1,%2\n"                                               \
261
        "2:\tlw\t%D1,%3\n\t"                                            \
262
        "move\t%0,$0\n"                                                 \
263
        "3:\t.section\t.fixup,\"ax\"\n"                                 \
264
        "4:\tli\t%0,%4\n\t"                                             \
265
        "move\t%1,$0\n\t"                                               \
266
        "move\t%D1,$0\n\t"                                              \
267
        "j\t3b\n\t"                                                     \
268
        ".previous\n\t"                                                 \
269
        ".section\t__ex_table,\"a\"\n\t"                                \
270
        ".word\t1b,4b\n\t"                                              \
271
        ".word\t2b,4b\n\t"                                              \
272
        ".previous"                                                     \
273
        :"=r" (__gu_err), "=&r" (__gu_val)                              \
274
        :"o" (__m(__gu_addr)), "o" (__m(__gu_addr + 4)),                \
275
         "i" (-EFAULT));                                                \
276
})
277
 
278
extern void __get_user_unknown(void);
279
 
280
/*
281
 * Yuck.  We need two variants, one for 64bit operation and one
282
 * for 32 bit mode and old iron.
283
 */
284
#ifdef __mips64
285
#define __PUT_USER_DW __put_user_asm("sd")
286
#else
287
#define __PUT_USER_DW __put_user_asm_ll32
288
#endif
289
 
290
#define __put_user_nocheck(x,ptr,size)                                  \
291
({                                                                      \
292
        long __pu_err;                                                  \
293
        __typeof__(*(ptr)) __pu_val;                                    \
294
        long __pu_addr;                                                 \
295
        __pu_val = (x);                                                 \
296
        __pu_addr = (long) (ptr);                                       \
297
        __asm__("":"=r" (__pu_err));                                    \
298
        switch (size) {                                                 \
299
                case 1: __put_user_asm("sb"); break;                    \
300
                case 2: __put_user_asm("sh"); break;                    \
301
                case 4: __put_user_asm("sw"); break;                    \
302
                case 8: __PUT_USER_DW; break;                           \
303
                default: __put_user_unknown(); break;                   \
304
        }                                                               \
305
        __pu_err;                                                       \
306
})
307
 
308
#define __put_user_check(x,ptr,size)                                    \
309
({                                                                      \
310
        long __pu_err;                                                  \
311
        __typeof__(*(ptr)) __pu_val;                                    \
312
        long __pu_addr;                                                 \
313
        __pu_val = (x);                                                 \
314
        __pu_addr = (long) (ptr);                                       \
315
        __asm__("":"=r" (__pu_err));                                    \
316
        if (access_ok(VERIFY_WRITE, __pu_addr, size)) {                 \
317
                switch (size) {                                         \
318
                case 1: __put_user_asm("sb"); break;                    \
319
                case 2: __put_user_asm("sh"); break;                    \
320
                case 4: __put_user_asm("sw"); break;                    \
321
                case 8: __PUT_USER_DW; break;                           \
322
                default: __put_user_unknown(); break;                   \
323
                }                                                       \
324
        }                                                               \
325
        __pu_err;                                                       \
326
})
327
 
328
#define __put_user_asm(insn)                                            \
329
({                                                                      \
330
        __asm__ __volatile__(                                           \
331
        "1:\t" insn "\t%z1, %2\t\t\t# __put_user_asm\n\t"               \
332
        "move\t%0, $0\n"                                                \
333
        "2:\n\t"                                                        \
334
        ".section\t.fixup,\"ax\"\n"                                     \
335
        "3:\tli\t%0, %3\n\t"                                            \
336
        "j\t2b\n\t"                                                     \
337
        ".previous\n\t"                                                 \
338
        ".section\t__ex_table,\"a\"\n\t"                                \
339
        ".word\t1b, 3b\n\t"                                             \
340
        ".previous"                                                     \
341
        :"=r" (__pu_err)                                                \
342
        :"Jr" (__pu_val), "o" (__m(__pu_addr)), "i" (-EFAULT));         \
343
})
344
 
345
#define __put_user_asm_ll32                                             \
346
({                                                                      \
347
__asm__ __volatile__(                                                   \
348
        "1:\tsw\t%1, %2\t\t\t# __put_user_asm_ll32\n\t"                 \
349
        "2:\tsw\t%D1, %3\n"                                             \
350
        "move\t%0, $0\n"                                                \
351
        "3:\n\t"                                                        \
352
        ".section\t.fixup,\"ax\"\n"                                     \
353
        "4:\tli\t%0, %4\n\t"                                            \
354
        "j\t3b\n\t"                                                     \
355
        ".previous\n\t"                                                 \
356
        ".section\t__ex_table,\"a\"\n\t"                                \
357
        ".word\t1b,4b\n\t"                                              \
358
        ".word\t2b,4b\n\t"                                              \
359
        ".previous"                                                     \
360
        :"=r" (__pu_err)                                                \
361
        :"r" (__pu_val), "o" (__m(__pu_addr)), "o" (__m(__pu_addr + 4)),\
362
         "i" (-EFAULT));                                                \
363
})
364
 
365
extern void __put_user_unknown(void);
366
 
367
/*
368
 * We're generating jump to subroutines which will be outside the range of
369
 * jump instructions
370
 */
371
#ifdef MODULE
372
#define __MODULE_JAL(destination)                                       \
373
        ".set\tnoat\n\t"                                                \
374
        "la\t$1, " #destination "\n\t"                                  \
375
        "jalr\t$1\n\t"                                                  \
376
        ".set\tat\n\t"
377
#else
378
#define __MODULE_JAL(destination)                                       \
379
        "jal\t" #destination "\n\t"
380
#endif
381
 
382
extern size_t __copy_user(void *__to, const void *__from, size_t __n);
383
 
384
#define __invoke_copy_to_user(to,from,n)                                \
385
({                                                                      \
386
        register void *__cu_to_r __asm__ ("$4");                        \
387
        register const void *__cu_from_r __asm__ ("$5");                \
388
        register long __cu_len_r __asm__ ("$6");                        \
389
                                                                        \
390
        __cu_to_r = (to);                                               \
391
        __cu_from_r = (from);                                           \
392
        __cu_len_r = (n);                                               \
393
        __asm__ __volatile__(                                           \
394
        __MODULE_JAL(__copy_user)                                       \
395
        : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r)       \
396
        :                                                               \
397
        : "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31",         \
398
          "memory");                                                    \
399
        __cu_len_r;                                                     \
400
})
401
 
402
/*
403
 * __copy_to_user: - Copy a block of data into user space, with less checking.
404
 * @to:   Destination address, in user space.
405
 * @from: Source address, in kernel space.
406
 * @n:    Number of bytes to copy.
407
 *
408
 * Context: User context only.  This function may sleep.
409
 *
410
 * Copy data from kernel space to user space.  Caller must check
411
 * the specified block with access_ok() before calling this function.
412
 *
413
 * Returns number of bytes that could not be copied.
414
 * On success, this will be zero.
415
 */
416
#define __copy_to_user(to,from,n)                                       \
417
({                                                                      \
418
        void *__cu_to;                                                  \
419
        const void *__cu_from;                                          \
420
        long __cu_len;                                                  \
421
                                                                        \
422
        __cu_to = (to);                                                 \
423
        __cu_from = (from);                                             \
424
        __cu_len = (n);                                                 \
425
        __cu_len = __invoke_copy_to_user(__cu_to, __cu_from, __cu_len); \
426
        __cu_len;                                                       \
427
})
428
 
429
/*
430
 * copy_to_user: - Copy a block of data into user space.
431
 * @to:   Destination address, in user space.
432
 * @from: Source address, in kernel space.
433
 * @n:    Number of bytes to copy.
434
 *
435
 * Context: User context only.  This function may sleep.
436
 *
437
 * Copy data from kernel space to user space.
438
 *
439
 * Returns number of bytes that could not be copied.
440
 * On success, this will be zero.
441
 */
442
#define copy_to_user(to,from,n)                                         \
443
({                                                                      \
444
        void *__cu_to;                                                  \
445
        const void *__cu_from;                                          \
446
        long __cu_len;                                                  \
447
                                                                        \
448
        __cu_to = (to);                                                 \
449
        __cu_from = (from);                                             \
450
        __cu_len = (n);                                                 \
451
        if (access_ok(VERIFY_WRITE, __cu_to, __cu_len))                 \
452
                __cu_len = __invoke_copy_to_user(__cu_to, __cu_from,    \
453
                                                 __cu_len);             \
454
        __cu_len;                                                       \
455
})
456
 
457
#define __invoke_copy_from_user(to,from,n)                              \
458
({                                                                      \
459
        register void *__cu_to_r __asm__ ("$4");                        \
460
        register const void *__cu_from_r __asm__ ("$5");                \
461
        register long __cu_len_r __asm__ ("$6");                        \
462
                                                                        \
463
        __cu_to_r = (to);                                               \
464
        __cu_from_r = (from);                                           \
465
        __cu_len_r = (n);                                               \
466
        __asm__ __volatile__(                                           \
467
        ".set\tnoreorder\n\t"                                           \
468
        __MODULE_JAL(__copy_user)                                       \
469
        ".set\tnoat\n\t"                                                \
470
        "addu\t$1, %1, %2\n\t"                                          \
471
        ".set\tat\n\t"                                                  \
472
        ".set\treorder\n\t"                                             \
473
        : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r)       \
474
        :                                                               \
475
        : "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31",         \
476
          "memory");                                                    \
477
        __cu_len_r;                                                     \
478
})
479
 
480
/*
481
 * __copy_from_user: - Copy a block of data from user space, with less checking. * @to:   Destination address, in kernel space.
482
 * @from: Source address, in user space.
483
 * @n:    Number of bytes to copy.
484
 *
485
 * Context: User context only.  This function may sleep.
486
 *
487
 * Copy data from user space to kernel space.  Caller must check
488
 * the specified block with access_ok() before calling this function.
489
 *
490
 * Returns number of bytes that could not be copied.
491
 * On success, this will be zero.
492
 *
493
 * If some data could not be copied, this function will pad the copied
494
 * data to the requested size using zero bytes.
495
 */
496
#define __copy_from_user(to,from,n)                                     \
497
({                                                                      \
498
        void *__cu_to;                                                  \
499
        const void *__cu_from;                                          \
500
        long __cu_len;                                                  \
501
                                                                        \
502
        __cu_to = (to);                                                 \
503
        __cu_from = (from);                                             \
504
        __cu_len = (n);                                                 \
505
        __cu_len = __invoke_copy_from_user(__cu_to, __cu_from,          \
506
                                           __cu_len);                   \
507
        __cu_len;                                                       \
508
})
509
 
510
/*
511
 * copy_from_user: - Copy a block of data from user space.
512
 * @to:   Destination address, in kernel space.
513
 * @from: Source address, in user space.
514
 * @n:    Number of bytes to copy.
515
 *
516
 * Context: User context only.  This function may sleep.
517
 *
518
 * Copy data from user space to kernel space.
519
 *
520
 * Returns number of bytes that could not be copied.
521
 * On success, this will be zero.
522
 *
523
 * If some data could not be copied, this function will pad the copied
524
 * data to the requested size using zero bytes.
525
 */
526
#define copy_from_user(to,from,n)                                       \
527
({                                                                      \
528
        void *__cu_to;                                                  \
529
        const void *__cu_from;                                          \
530
        long __cu_len;                                                  \
531
                                                                        \
532
        __cu_to = (to);                                                 \
533
        __cu_from = (from);                                             \
534
        __cu_len = (n);                                                 \
535
        if (access_ok(VERIFY_READ, __cu_from, __cu_len))                \
536
                __cu_len = __invoke_copy_from_user(__cu_to, __cu_from,  \
537
                                                   __cu_len);           \
538
        __cu_len;                                                       \
539
})
540
 
541
/*
542
 * __clear_user: - Zero a block of memory in user space, with less checking.
543
 * @to:   Destination address, in user space.
544
 * @n:    Number of bytes to zero.
545
 *
546
 * Zero a block of memory in user space.  Caller must check
547
 * the specified block with access_ok() before calling this function.
548
 *
549
 * Returns number of bytes that could not be cleared.
550
 * On success, this will be zero.
551
 */
552
static inline __kernel_size_t
553
__clear_user(void *addr, __kernel_size_t size)
554
{
555
        __kernel_size_t res;
556
 
557
        __asm__ __volatile__(
558
                "move\t$4, %1\n\t"
559
                "move\t$5, $0\n\t"
560
                "move\t$6, %2\n\t"
561
                __MODULE_JAL(__bzero)
562
                "move\t%0, $6"
563
                : "=r" (res)
564
                : "r" (addr), "r" (size)
565
                : "$4", "$5", "$6", "$8", "$9", "$31");
566
 
567
        return res;
568
}
569
 
570
#define clear_user(addr,n)                                              \
571
({                                                                      \
572
        void * __cl_addr = (addr);                                      \
573
        unsigned long __cl_size = (n);                                  \
574
        if (__cl_size && access_ok(VERIFY_WRITE,                        \
575
                ((unsigned long)(__cl_addr)), __cl_size))               \
576
                __cl_size = __clear_user(__cl_addr, __cl_size);         \
577
        __cl_size;                                                      \
578
})
579
 
580
/*
581
 * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
582
 * @dst:   Destination address, in kernel space.  This buffer must be at
583
 *         least @count bytes long.
584
 * @src:   Source address, in user space.
585
 * @count: Maximum number of bytes to copy, including the trailing NUL.
586
 *
587
 * Copies a NUL-terminated string from userspace to kernel space.
588
 * Caller must check the specified block with access_ok() before calling
589
 * this function.
590
 *
591
 * On success, returns the length of the string (not including the trailing
592
 * NUL).
593
 *
594
 * If access to userspace fails, returns -EFAULT (some data may have been
595
 * copied).
596
 *
597
 * If @count is smaller than the length of the string, copies @count bytes
598
 * and returns @count.
599
 */
600
static inline long
601
__strncpy_from_user(char *__to, const char *__from, long __len)
602
{
603
        long res;
604
 
605
        __asm__ __volatile__(
606
                "move\t$4, %1\n\t"
607
                "move\t$5, %2\n\t"
608
                "move\t$6, %3\n\t"
609
                __MODULE_JAL(__strncpy_from_user_nocheck_asm)
610
                "move\t%0, $2"
611
                : "=r" (res)
612
                : "r" (__to), "r" (__from), "r" (__len)
613
                : "$2", "$3", "$4", "$5", "$6", "$8", "$31", "memory");
614
 
615
        return res;
616
}
617
 
618
/*
619
 * strncpy_from_user: - Copy a NUL terminated string from userspace.
620
 * @dst:   Destination address, in kernel space.  This buffer must be at
621
 *         least @count bytes long.
622
 * @src:   Source address, in user space.
623
 * @count: Maximum number of bytes to copy, including the trailing NUL.
624
 *
625
 * Copies a NUL-terminated string from userspace to kernel space.
626
 *
627
 * On success, returns the length of the string (not including the trailing
628
 * NUL).
629
 *
630
 * If access to userspace fails, returns -EFAULT (some data may have been
631
 * copied).
632
 *
633
 * If @count is smaller than the length of the string, copies @count bytes
634
 * and returns @count.
635
 */
636
static inline long
637
strncpy_from_user(char *__to, const char *__from, long __len)
638
{
639
        long res;
640
 
641
        __asm__ __volatile__(
642
                "move\t$4, %1\n\t"
643
                "move\t$5, %2\n\t"
644
                "move\t$6, %3\n\t"
645
                __MODULE_JAL(__strncpy_from_user_asm)
646
                "move\t%0, $2"
647
                : "=r" (res)
648
                : "r" (__to), "r" (__from), "r" (__len)
649
                : "$2", "$3", "$4", "$5", "$6", "$8", "$31", "memory");
650
 
651
        return res;
652
}
653
 
654
/* Returns: 0 if bad, string length+1 (memory size) of string if ok */
655
static inline long __strlen_user(const char *s)
656
{
657
        long res;
658
 
659
        __asm__ __volatile__(
660
                "move\t$4, %1\n\t"
661
                __MODULE_JAL(__strlen_user_nocheck_asm)
662
                "move\t%0, $2"
663
                : "=r" (res)
664
                : "r" (s)
665
                : "$2", "$4", "$8", "$31");
666
 
667
        return res;
668
}
669
 
670
/*
671
 * strlen_user: - Get the size of a string in user space.
672
 * @str: The string to measure.
673
 *
674
 * Context: User context only.  This function may sleep.
675
 *
676
 * Get the size of a NUL-terminated string in user space.
677
 *
678
 * Returns the size of the string INCLUDING the terminating NUL.
679
 * On exception, returns 0.
680
 *
681
 * If there is a limit on the length of a valid string, you may wish to
682
 * consider using strnlen_user() instead.
683
 */
684
static inline long strlen_user(const char *s)
685
{
686
        long res;
687
 
688
        __asm__ __volatile__(
689
                "move\t$4, %1\n\t"
690
                __MODULE_JAL(__strlen_user_asm)
691
                "move\t%0, $2"
692
                : "=r" (res)
693
                : "r" (s)
694
                : "$2", "$4", "$8", "$31");
695
 
696
        return res;
697
}
698
 
699
/*
700
 * strlen_user: - Get the size of a string in user space.
701
 * @str: The string to measure.
702
 * @n:   The maximum valid length
703
 *
704
 * Get the size of a NUL-terminated string in user space.
705
 *
706
 * Returns the size of the string INCLUDING the terminating NUL.
707
 * On exception, returns 0.
708
 * If the string is too long, returns a value greater than @n.
709
 */
710
static inline long strnlen_user(const char *s, long n)
711
{
712
        long res;
713
 
714
        __asm__ __volatile__(
715
                "move\t$4, %1\n\t"
716
                "move\t$5, %2\n\t"
717
                __MODULE_JAL(__strnlen_user_asm)
718
                "move\t%0, $2"
719
                : "=r" (res)
720
                : "r" (s), "r" (n)
721
                : "$2", "$4", "$5", "$8", "$31");
722
 
723
        return res;
724
}
725
 
726
struct exception_table_entry
727
{
728
        unsigned long insn;
729
        unsigned long nextinsn;
730
};
731
 
732
/* Returns 0 if exception not found and fixup.unit otherwise.  */
733
extern unsigned long search_exception_table(unsigned long addr);
734
 
735
/* Returns the new pc */
736
#define fixup_exception(map_reg, fixup_unit, pc)                        \
737
({                                                                      \
738
        fixup_unit;                                                     \
739
})
740
 
741
#endif /* _ASM_UACCESS_H */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.