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

Subversion Repositories or1k

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

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *  include/asm-s390/uaccess.h
3
 *
4
 *  S390 version
5
 *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
6
 *    Author(s): Hartmut Penner (hpenner@de.ibm.com),
7
 *               Martin Schwidefsky (schwidefsky@de.ibm.com)
8
 *
9
 *  Derived from "include/asm-i386/uaccess.h"
10
 */
11
#ifndef __S390_UACCESS_H
12
#define __S390_UACCESS_H
13
 
14
/*
15
 * User space memory access functions
16
 */
17
#include <linux/sched.h>
18
 
19
#define VERIFY_READ     0
20
#define VERIFY_WRITE    1
21
 
22
 
23
/*
24
 * The fs value determines whether argument validity checking should be
25
 * performed or not.  If get_fs() == USER_DS, checking is performed, with
26
 * get_fs() == KERNEL_DS, checking is bypassed.
27
 *
28
 * For historical reasons, these macros are grossly misnamed.
29
 */
30
 
31
#define MAKE_MM_SEG(s)  ((mm_segment_t) { (s) })
32
 
33
 
34
#define KERNEL_DS       MAKE_MM_SEG(0)
35
#define USER_DS         MAKE_MM_SEG(1)
36
 
37
#define get_ds()        (KERNEL_DS)
38
#define get_fs()        (current->addr_limit)
39
#define set_fs(x)       ({asm volatile("sar   4,%0"::"a" ((x).ar4));\
40
                          current->addr_limit = (x);})
41
 
42
#define segment_eq(a,b) ((a).ar4 == (b).ar4)
43
 
44
 
45
#define __access_ok(addr,size) (1)
46
 
47
#define access_ok(type,addr,size) __access_ok(addr,size)
48
 
49
extern inline int verify_area(int type, const void * addr, unsigned long size)
50
{
51
        return access_ok(type,addr,size)?0:-EFAULT;
52
}
53
 
54
/*
55
 * The exception table consists of pairs of addresses: the first is the
56
 * address of an instruction that is allowed to fault, and the second is
57
 * the address at which the program should continue.  No registers are
58
 * modified, so it is entirely up to the continuation code to figure out
59
 * what to do.
60
 *
61
 * All the routines below use bits of fixup code that are out of line
62
 * with the main instruction path.  This means when everything is well,
63
 * we don't even have to jump over them.  Further, they do not intrude
64
 * on our cache or tlb entries.
65
 */
66
 
67
struct exception_table_entry
68
{
69
        unsigned long insn, fixup;
70
};
71
 
72
/* Returns 0 if exception not found and fixup otherwise.  */
73
extern unsigned long search_exception_table(unsigned long);
74
 
75
 
76
/*
77
 * These are the main single-value transfer routines.  They automatically
78
 * use the right size if we just have the right pointer type.
79
 */
80
 
81
extern inline int __put_user_asm_8(__u64 x, void *ptr)
82
{
83
        int err;
84
 
85
        __asm__ __volatile__ (  "   sr    %1,%1\n"
86
                                "   la    4,%0\n"
87
                                "   sacf  512\n"
88
                                "0: stg   %2,0(4)\n"
89
                                "1: sacf  0\n"
90
                                ".section .fixup,\"ax\"\n"
91
                                "2: lhi   %1,%h3\n"
92
                                "   jg    1b\n"
93
                                ".previous\n"
94
                                ".section __ex_table,\"a\"\n"
95
                                "   .align 8\n"
96
                                "   .quad  0b,2b\n"
97
                                ".previous"
98
                                : "=m" (*((__u64*) ptr)) , "=&d" (err)
99
                                : "d" (x), "K" (-EFAULT)
100
                                : "cc", "4" );
101
        return err;
102
}
103
extern inline int __put_user_asm_4(__u32 x, void *ptr)
104
{
105
        int err;
106
 
107
        __asm__ __volatile__ (  "   sr    %1,%1\n"
108
                                "   la    4,%0\n"
109
                                "   sacf  512\n"
110
                                "0: st    %2,0(4)\n"
111
                                "1: sacf  0\n"
112
                                ".section .fixup,\"ax\"\n"
113
                                "2: lhi   %1,%h3\n"
114
                                "   jg    1b\n"
115
                                ".previous\n"
116
                                ".section __ex_table,\"a\"\n"
117
                                "   .align 8\n"
118
                                "   .quad  0b,2b\n"
119
                                ".previous"
120
                                : "=m" (*((__u32*) ptr)) , "=&d" (err)
121
                                : "d" (x), "K" (-EFAULT)
122
                                : "cc", "4" );
123
        return err;
124
}
125
 
126
extern inline int __put_user_asm_2(__u16 x, void *ptr)
127
{
128
        int err;
129
 
130
        __asm__ __volatile__ (  "   sr    %1,%1\n"
131
                                "   la    4,%0\n"
132
                                "   sacf  512\n"
133
                                "0: sth   %2,0(4)\n"
134
                                "1: sacf  0\n"
135
                                ".section .fixup,\"ax\"\n"
136
                                "2: lhi   %1,%h3\n"
137
                                "   jg    1b\n"
138
                                ".previous\n"
139
                                ".section __ex_table,\"a\"\n"
140
                                "   .align 8\n"
141
                                "   .quad  0b,2b\n"
142
                                ".previous"
143
                                : "=m" (*((__u16*) ptr)) , "=&d" (err)
144
                                : "d" (x), "K" (-EFAULT)
145
                                : "cc", "4" );
146
        return err;
147
}
148
 
149
extern inline int __put_user_asm_1(__u8 x, void *ptr)
150
{
151
        int err;
152
 
153
        __asm__ __volatile__ (  "   sr    %1,%1\n"
154
                                "   la    4,%0\n"
155
                                "   sacf  512\n"
156
                                "0: stc   %2,0(4)\n"
157
                                "1: sacf  0\n"
158
                                ".section .fixup,\"ax\"\n"
159
                                "2: lhi   %1,%h3\n"
160
                                "   jg    1b\n"
161
                                ".previous\n"
162
                                ".section __ex_table,\"a\"\n"
163
                                "   .align 8\n"
164
                                "   .quad  0b,2b\n"
165
                                ".previous"
166
                                : "=m" (*((__u8*) ptr)) , "=&d" (err)
167
                                : "d" (x), "K" (-EFAULT)
168
                                : "cc", "1", "4" );
169
        return err;
170
}
171
 
172
/*
173
 * (u?)(u64) ... autsch, but that the only way we can suppress the
174
 * warnings when compiling binfmt_elf.c
175
 */
176
#define __put_user(x, ptr)                                      \
177
({                                                              \
178
        __typeof__(*(ptr)) *__pu_addr = (ptr);                  \
179
        __typeof__(*(ptr)) __x = (x);                           \
180
        int __pu_err;                                           \
181
        switch (sizeof (*(__pu_addr))) {                        \
182
        case 1:                                                 \
183
                __pu_err = __put_user_asm_1((__u8)(__u64)(__x), \
184
                                            __pu_addr);         \
185
                break;                                          \
186
        case 2:                                                 \
187
                __pu_err = __put_user_asm_2((__u16)(__u64)(__x),\
188
                                            __pu_addr);         \
189
                break;                                          \
190
        case 4:                                                 \
191
                __pu_err = __put_user_asm_4((__u32)(__u64)(__x),\
192
                                            __pu_addr);         \
193
                break;                                          \
194
        case 8:                                                 \
195
                __pu_err = __put_user_asm_8((__u64)(__x),       \
196
                                            __pu_addr);         \
197
                break;                                          \
198
        default:                                                \
199
                __pu_err = __put_user_bad();                    \
200
                break;                                          \
201
         }                                                      \
202
        __pu_err;                                               \
203
})
204
 
205
#define put_user(x, ptr) __put_user(x, ptr)
206
 
207
extern int __put_user_bad(void);
208
 
209
#define __get_user_asm_8(x, ptr, err)                                      \
210
({                                                                         \
211
        __asm__ __volatile__ (  "   sr    %1,%1\n"                         \
212
                                "   la    4,%2\n"                          \
213
                                "   sacf  512\n"                           \
214
                                "0: lg    %0,0(4)\n"                       \
215
                                "1: sacf  0\n"                             \
216
                                ".section .fixup,\"ax\"\n"                 \
217
                                "2: lhi   %1,%h3\n"                        \
218
                                "   jg    1b\n"                            \
219
                                ".previous\n"                              \
220
                                ".section __ex_table,\"a\"\n"              \
221
                                "   .align 8\n"                            \
222
                                "   .quad 0b,2b\n"                         \
223
                                ".previous"                                \
224
                                : "=d" (x) , "=&d" (err)                   \
225
                                : "m" (*(const __u64*)(ptr)),"K" (-EFAULT) \
226
                                : "cc", "4" );                             \
227
})
228
#define __get_user_asm_4(x, ptr, err)                                      \
229
({                                                                         \
230
        __asm__ __volatile__ (  "   sr    %1,%1\n"                         \
231
                                "   la    4,%2\n"                          \
232
                                "   sacf  512\n"                           \
233
                                "0: l     %0,0(4)\n"                       \
234
                                "1: sacf  0\n"                             \
235
                                ".section .fixup,\"ax\"\n"                 \
236
                                "2: lhi   %1,%h3\n"                        \
237
                                "   jg    1b\n"                            \
238
                                ".previous\n"                              \
239
                                ".section __ex_table,\"a\"\n"              \
240
                                "   .align 8\n"                            \
241
                                "   .quad 0b,2b\n"                         \
242
                                ".previous"                                \
243
                                : "=d" (x) , "=&d" (err)                   \
244
                                : "m" (*(const __u32*)(ptr)),"K" (-EFAULT) \
245
                                : "cc", "4" );                             \
246
})
247
 
248
#define __get_user_asm_2(x, ptr, err)                                      \
249
({                                                                         \
250
        __asm__ __volatile__ (  "   sr    %1,%1\n"                         \
251
                                "   la    4,%2\n"                          \
252
                                "   sacf  512\n"                           \
253
                                "0: lh    %0,0(4)\n"                       \
254
                                "1: sacf  0\n"                             \
255
                                ".section .fixup,\"ax\"\n"                 \
256
                                "2: lhi   %1,%h3\n"                        \
257
                                "   jg    1b\n"                            \
258
                                ".previous\n"                              \
259
                                ".section __ex_table,\"a\"\n"              \
260
                                "   .align 8\n"                            \
261
                                "   .quad 0b,2b\n"                         \
262
                                ".previous"                                \
263
                                : "=d" (x) , "=&d" (err)                   \
264
                                : "m" (*(const __u16*)(ptr)),"K" (-EFAULT) \
265
                                : "cc", "4" );                             \
266
})
267
 
268
#define __get_user_asm_1(x, ptr, err)                                     \
269
({                                                                        \
270
        __asm__ __volatile__ (  "   sr    %1,%1\n"                        \
271
                                "   la    4,%2\n"                         \
272
                                "   sr    %0,%0\n"                        \
273
                                "   sacf  512\n"                          \
274
                                "0: ic    %0,0(4)\n"                      \
275
                                "1: sacf  0\n"                            \
276
                                ".section .fixup,\"ax\"\n"                \
277
                                "2: lhi   %1,%h3\n"                       \
278
                                "   jg    1b\n"                           \
279
                                ".previous\n"                             \
280
                                ".section __ex_table,\"a\"\n"             \
281
                                "   .align 8\n"                           \
282
                                "   .quad 0b,2b\n"                        \
283
                                ".previous"                               \
284
                                : "=d" (x) , "=&d" (err)                  \
285
                                : "m" (*(const __u8*)(ptr)),"K" (-EFAULT) \
286
                                : "cc", "4" );                            \
287
})
288
 
289
#define __get_user(x, ptr)                                      \
290
({                                                              \
291
        __typeof__(ptr) __gu_addr = (ptr);                      \
292
        __typeof__(*(ptr)) __x;                                 \
293
        int __gu_err;                                           \
294
        switch (sizeof(*(ptr))) {                               \
295
        case 1:                                                 \
296
                __get_user_asm_1(__x,__gu_addr,__gu_err);       \
297
                break;                                          \
298
        case 2:                                                 \
299
                __get_user_asm_2(__x,__gu_addr,__gu_err);       \
300
                break;                                          \
301
        case 4:                                                 \
302
                __get_user_asm_4(__x,__gu_addr,__gu_err);       \
303
                break;                                          \
304
        case 8:                                                 \
305
                __get_user_asm_8(__x,__gu_addr,__gu_err);       \
306
                break;                                          \
307
        default:                                                \
308
                __x = 0;                                        \
309
                __gu_err = __get_user_bad();                    \
310
                break;                                          \
311
        }                                                       \
312
        (x) = __x;                                              \
313
        __gu_err;                                               \
314
})
315
 
316
#define get_user(x, ptr) __get_user(x, ptr)
317
 
318
extern int __get_user_bad(void);
319
 
320
/*
321
 * access register are set up, that 4 points to secondary (user) , 2 to primary (kernel)
322
 */
323
 
324
extern long __copy_to_user_asm(const void *from, long n, void *to);
325
 
326
#define __copy_to_user(to, from, n)                             \
327
({                                                              \
328
        __copy_to_user_asm(from, n, to);                        \
329
})
330
 
331
#define copy_to_user(to, from, n)                               \
332
({                                                              \
333
        long err = 0;                                           \
334
        __typeof__(n) __n = (n);                                \
335
        if (__access_ok(to,__n)) {                              \
336
                err = __copy_to_user_asm(from, __n, to);        \
337
        }                                                       \
338
        else                                                    \
339
                err = __n;                                      \
340
        err;                                                    \
341
})
342
 
343
extern long __copy_from_user_asm(void *to, long n, const void *from);
344
 
345
#define __copy_from_user(to, from, n)                           \
346
({                                                              \
347
        __copy_from_user_asm(to, n, from);                      \
348
})
349
 
350
#define copy_from_user(to, from, n)                             \
351
({                                                              \
352
        long err = 0;                                           \
353
        __typeof__(n) __n = (n);                                \
354
        if (__access_ok(from,__n)) {                            \
355
                err = __copy_from_user_asm(to, __n, from);      \
356
        }                                                       \
357
        else                                                    \
358
                err = __n;                                      \
359
        err;                                                    \
360
})
361
 
362
/*
363
 * Copy a null terminated string from userspace.
364
 */
365
 
366
static inline long
367
__strncpy_from_user(char *dst, const char *src, long count)
368
{
369
        long len;
370
        __asm__ __volatile__ (  "   slgr  %0,%0\n"
371
                                "   lgr   2,%1\n"
372
                                "   lgr   4,%2\n"
373
                                "   slr   3,3\n"
374
                                "   sacf  512\n"
375
                                "0: ic    3,0(%0,4)\n"
376
                                "1: stc   3,0(%0,2)\n"
377
                                "   ltr   3,3\n"
378
                                "   jz    2f\n"
379
                                "   aghi  %0,1\n"
380
                                "   cgr   %0,%3\n"
381
                                "   jl    0b\n"
382
                                "2: sacf  0\n"
383
                                ".section .fixup,\"ax\"\n"
384
                                "3: lghi  %0,%h4\n"
385
                                "   jg    2b\n"
386
                                ".previous\n"
387
                                ".section __ex_table,\"a\"\n"
388
                                "   .align 8\n"
389
                                "   .quad  0b,3b\n"
390
                                "   .quad  1b,3b\n"
391
                                ".previous"
392
                                : "=&a" (len)
393
                                : "a"  (dst), "d" (src), "d" (count),
394
                                  "K" (-EFAULT)
395
                                : "cc", "2" ,"3", "4" );
396
        return len;
397
}
398
 
399
static inline long
400
strncpy_from_user(char *dst, const char *src, long count)
401
{
402
        long res = -EFAULT;
403
        if (access_ok(VERIFY_READ, src, 1))
404
                res = __strncpy_from_user(dst, src, count);
405
        return res;
406
}
407
 
408
/*
409
 * Return the size of a string (including the ending 0)
410
 *
411
 * Return 0 for error
412
 */
413
static inline unsigned long
414
strnlen_user(const char * src, unsigned long n)
415
{
416
#if 0
417
        __asm__ __volatile__ ("   algr  %0,%1\n"
418
                              "   slgr  0,0\n"
419
                              "   lgr   4,%1\n"
420
                              "   sacf  512\n"
421
                              "0: srst  %0,4\n"
422
                              "   jo    0b\n"
423
                              "   slgr  %0,%1\n"
424
                              "   aghi  %0,1\n"
425
                              "1: sacf  0\n"
426
                              ".section .fixup,\"ax\"\n"
427
                              "2: slgr  %0,%0\n"
428
                              "   jg    1b\n"
429
                              ".previous\n"
430
                              ".section __ex_table,\"a\"\n"
431
                              "   .align 8\n"
432
                              "   .quad  0b,2b\n"
433
                              ".previous"
434
                              : "+&a" (n) : "d" (src)
435
                              : "cc", "0", "4" );
436
#else
437
        __asm__ __volatile__ ("   lgr   4,%1\n"
438
                              "   sacf  512\n"
439
                              "0: cli   0(4),0x00\n"
440
                              "   la    4,1(4)\n"
441
                              "   je    1f\n"
442
                              "   brctg %0,0b\n"
443
                              "1: lgr   %0,4\n"
444
                              "   slgr  %0,%1\n"
445
                              "2: sacf  0\n"
446
                              ".section .fixup,\"ax\"\n"
447
                              "3: slgr  %0,%0\n"
448
                              "   jg    2b\n"
449
                              ".previous\n"
450
                              ".section __ex_table,\"a\"\n"
451
                              "   .align 8\n"
452
                              "   .quad  0b,3b\n"
453
                              ".previous"
454
                              : "+&a" (n) : "d" (src)
455
                              : "cc", "4" );
456
#endif
457
        return n;
458
}
459
#define strlen_user(str) strnlen_user(str, ~0UL)
460
 
461
/*
462
 * Zero Userspace
463
 */
464
 
465
extern long __clear_user_asm(void *to, long n);
466
 
467
#define __clear_user(to, n)                                     \
468
({                                                              \
469
        __clear_user_asm(to, n);                                \
470
})
471
 
472
static inline unsigned long
473
clear_user(void *to, unsigned long n)
474
{
475
        if (access_ok(VERIFY_WRITE, to, n))
476
                n = __clear_user(to, n);
477
        return n;
478
}
479
 
480
#endif                                 /* _S390_UACCESS_H                  */
481
 
482
 
483
 
484
 
485
 

powered by: WebSVN 2.1.0

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