linux/include/asm-arm26/uaccess.h
<<
>>
Prefs
   1#ifndef _ASMARM_UACCESS_H
   2#define _ASMARM_UACCESS_H
   3
   4/*
   5 * User space memory access functions
   6 */
   7#include <linux/sched.h>
   8#include <asm/errno.h>
   9
  10#define VERIFY_READ 0
  11#define VERIFY_WRITE 1
  12
  13/*
  14 * The exception table consists of pairs of addresses: the first is the
  15 * address of an instruction that is allowed to fault, and the second is
  16 * the address at which the program should continue.  No registers are
  17 * modified, so it is entirely up to the continuation code to figure out
  18 * what to do.
  19 *
  20 * All the routines below use bits of fixup code that are out of line
  21 * with the main instruction path.  This means when everything is well,
  22 * we don't even have to jump over them.  Further, they do not intrude
  23 * on our cache or tlb entries.
  24 */
  25
  26struct exception_table_entry
  27{
  28        unsigned long insn, fixup;
  29};
  30
  31/* Returns 0 if exception not found and fixup otherwise.  */
  32extern unsigned long search_exception_table(unsigned long);
  33extern int fixup_exception(struct pt_regs *regs);
  34
  35#define get_ds()        (KERNEL_DS)
  36#define get_fs()        (current_thread_info()->addr_limit)
  37#define segment_eq(a,b) ((a) == (b))
  38
  39#include <asm/uaccess-asm.h>
  40
  41#define access_ok(type,addr,size)       (__range_ok(addr,size) == 0)
  42
  43static inline int verify_area(int type, const void * addr, unsigned long size)
  44{
  45        return access_ok(type, addr, size) ? 0 : -EFAULT;
  46}
  47
  48/*
  49 * Single-value transfer routines.  They automatically use the right
  50 * size if we just have the right pointer type.  Note that the functions
  51 * which read from user space (*get_*) need to take care not to leak
  52 * kernel data even if the calling code is buggy and fails to check
  53 * the return value.  This means zeroing out the destination variable
  54 * or buffer on error.  Normally this is done out of line by the
  55 * fixup code, but there are a few places where it intrudes on the
  56 * main code path.  When we only write to user space, there is no
  57 * problem.
  58 *
  59 * The "__xxx" versions of the user access functions do not verify the
  60 * address space - it must have been done previously with a separate
  61 * "access_ok()" call.
  62 *
  63 * The "xxx_error" versions set the third argument to EFAULT if an
  64 * error occurs, and leave it unchanged on success.  Note that these
  65 * versions are void (ie, don't return a value as such).
  66 */
  67
  68extern int __get_user_1(void *);
  69extern int __get_user_2(void *);
  70extern int __get_user_4(void *);
  71extern int __get_user_8(void *);
  72extern int __get_user_bad(void);
  73
  74#define __get_user_x(__r1,__p,__e,__s,__i...)                           \
  75           __asm__ __volatile__ ("bl    __get_user_" #__s               \
  76                : "=&r" (__e), "=r" (__r1)                              \
  77                : "0" (__p)                                             \
  78                : __i)
  79
  80#define get_user(x,p)                                                   \
  81        ({                                                              \
  82                const register typeof(*(p)) *__p asm("r0") = (p);       \
  83                register typeof(*(p)) __r1 asm("r1");                   \
  84                register int __e asm("r0");                             \
  85                switch (sizeof(*(p))) {                                 \
  86                case 1:                                                 \
  87                        __get_user_x(__r1, __p, __e, 1, "lr");          \
  88                        break;                                          \
  89                case 2:                                                 \
  90                        __get_user_x(__r1, __p, __e, 2, "r2", "lr");    \
  91                        break;                                          \
  92                case 4:                                                 \
  93                        __get_user_x(__r1, __p, __e, 4, "lr");          \
  94                        break;                                          \
  95                case 8:                                                 \
  96                        __get_user_x(__r1, __p, __e, 8, "lr");          \
  97                        break;                                          \
  98                default: __e = __get_user_bad(); break;                 \
  99                }                                                       \
 100                x = __r1;                                               \
 101                __e;                                                    \
 102        })
 103
 104
 105#define __get_user(x,ptr)                                               \
 106({                                                                      \
 107        long __gu_err = 0;                                              \
 108        __get_user_err((x),(ptr),__gu_err);                             \
 109        __gu_err;                                                       \
 110})
 111
 112#define __get_user_error(x,ptr,err)                                     \
 113({                                                                      \
 114        __get_user_err((x),(ptr),err);                                  \
 115        (void) 0;                                                       \
 116})
 117
 118#define __get_user_err(x,ptr,err)                                       \
 119do {                                                                    \
 120        unsigned long __gu_addr = (unsigned long)(ptr);                 \
 121        unsigned long __gu_val;                                         \
 122        switch (sizeof(*(ptr))) {                                       \
 123        case 1: __get_user_asm_byte(__gu_val,__gu_addr,err);    break;  \
 124        case 2: __get_user_asm_half(__gu_val,__gu_addr,err);    break;  \
 125        case 4: __get_user_asm_word(__gu_val,__gu_addr,err);    break;  \
 126        default: (__gu_val) = __get_user_bad();                         \
 127        }                                                               \
 128        (x) = (__typeof__(*(ptr)))__gu_val;                             \
 129} while (0)
 130
 131extern int __put_user_1(void *, unsigned int);
 132extern int __put_user_2(void *, unsigned int);
 133extern int __put_user_4(void *, unsigned int);
 134extern int __put_user_8(void *, unsigned long long);
 135extern int __put_user_bad(void);
 136
 137#define __put_user_x(__r1,__p,__e,__s)                                  \
 138           __asm__ __volatile__ (                                       \
 139                __asmeq("%0", "r0") __asmeq("%2", "r1")                 \
 140                "bl     __put_user_" #__s                               \
 141                : "=&r" (__e)                                           \
 142                : "0" (__p), "r" (__r1)                                 \
 143                : "ip", "lr", "cc")
 144
 145#define put_user(x,p)                                                   \
 146        ({                                                              \
 147                const register typeof(*(p)) __r1 asm("r1") = (x);       \
 148                const register typeof(*(p)) *__p asm("r0") = (p);       \
 149                register int __e asm("r0");                             \
 150                switch (sizeof(*(__p))) {                               \
 151                case 1:                                                 \
 152                        __put_user_x(__r1, __p, __e, 1);                \
 153                        break;                                          \
 154                case 2:                                                 \
 155                        __put_user_x(__r1, __p, __e, 2);                \
 156                        break;                                          \
 157                case 4:                                                 \
 158                        __put_user_x(__r1, __p, __e, 4);                \
 159                        break;                                          \
 160                case 8:                                                 \
 161                        __put_user_x(__r1, __p, __e, 8);                \
 162                        break;                                          \
 163                default: __e = __put_user_bad(); break;                 \
 164                }                                                       \
 165                __e;                                                    \
 166        })
 167
 168#if 0
 169/*********************   OLD METHOD *******************/
 170#define __put_user_x(__r1,__p,__e,__s,__i...)                           \
 171           __asm__ __volatile__ ("bl    __put_user_" #__s               \
 172                : "=&r" (__e)                                           \
 173                : "0" (__p), "r" (__r1)                                 \
 174                : __i)
 175
 176#define put_user(x,p)                                                   \
 177        ({                                                              \
 178                const register typeof(*(p)) __r1 asm("r1") = (x);       \
 179                const register typeof(*(p)) *__p asm("r0") = (p);       \
 180                register int __e asm("r0");                             \
 181                switch (sizeof(*(p))) {                                 \
 182                case 1:                                                 \
 183                        __put_user_x(__r1, __p, __e, 1, "r2", "lr");    \
 184                        break;                                          \
 185                case 2:                                                 \
 186                        __put_user_x(__r1, __p, __e, 2, "r2", "lr");    \
 187                        break;                                          \
 188                case 4:                                                 \
 189                        __put_user_x(__r1, __p, __e, 4, "r2", "lr");    \
 190                        break;                                          \
 191                case 8:                                                 \
 192                        __put_user_x(__r1, __p, __e, 8, "r2", "ip", "lr");      \
 193                        break;                                          \
 194                default: __e = __put_user_bad(); break;                 \
 195                }                                                       \
 196                __e;                                                    \
 197        })
 198/*************************************************/
 199#endif
 200
 201#define __put_user(x,ptr)                                               \
 202({                                                                      \
 203        long __pu_err = 0;                                              \
 204        __put_user_err((x),(ptr),__pu_err);                             \
 205        __pu_err;                                                       \
 206})
 207
 208#define __put_user_error(x,ptr,err)                                     \
 209({                                                                      \
 210        __put_user_err((x),(ptr),err);                                  \
 211        (void) 0;                                                       \
 212})
 213
 214#define __put_user_err(x,ptr,err)                                       \
 215do {                                                                    \
 216        unsigned long __pu_addr = (unsigned long)(ptr);                 \
 217        __typeof__(*(ptr)) __pu_val = (x);                              \
 218        switch (sizeof(*(ptr))) {                                       \
 219        case 1: __put_user_asm_byte(__pu_val,__pu_addr,err);    break;  \
 220        case 2: __put_user_asm_half(__pu_val,__pu_addr,err);    break;  \
 221        case 4: __put_user_asm_word(__pu_val,__pu_addr,err);    break;  \
 222        case 8: __put_user_asm_dword(__pu_val,__pu_addr,err);   break;  \
 223        default: __put_user_bad();                                      \
 224        }                                                               \
 225} while (0)
 226
 227static __inline__ unsigned long copy_from_user(void *to, const void *from, unsigned long n)
 228{
 229        if (access_ok(VERIFY_READ, from, n))
 230                __do_copy_from_user(to, from, n);
 231        else /* security hole - plug it */
 232                memzero(to, n);
 233        return n;
 234}
 235
 236static __inline__ unsigned long __copy_from_user(void *to, const void *from, unsigned long n)
 237{
 238        __do_copy_from_user(to, from, n);
 239        return n;
 240}
 241
 242static __inline__ unsigned long copy_to_user(void *to, const void *from, unsigned long n)
 243{
 244        if (access_ok(VERIFY_WRITE, to, n))
 245                __do_copy_to_user(to, from, n);
 246        return n;
 247}
 248
 249static __inline__ unsigned long __copy_to_user(void *to, const void *from, unsigned long n)
 250{
 251        __do_copy_to_user(to, from, n);
 252        return n;
 253}
 254
 255#define __copy_to_user_inatomic __copy_to_user
 256#define __copy_from_user_inatomic __copy_from_user
 257
 258static __inline__ unsigned long clear_user (void *to, unsigned long n)
 259{
 260        if (access_ok(VERIFY_WRITE, to, n))
 261                __do_clear_user(to, n);
 262        return n;
 263}
 264
 265static __inline__ unsigned long __clear_user (void *to, unsigned long n)
 266{
 267        __do_clear_user(to, n);
 268        return n;
 269}
 270
 271static __inline__ long strncpy_from_user (char *dst, const char *src, long count)
 272{
 273        long res = -EFAULT;
 274        if (access_ok(VERIFY_READ, src, 1))
 275                __do_strncpy_from_user(dst, src, count, res);
 276        return res;
 277}
 278
 279static __inline__ long __strncpy_from_user (char *dst, const char *src, long count)
 280{
 281        long res;
 282        __do_strncpy_from_user(dst, src, count, res);
 283        return res;
 284}
 285
 286#define strlen_user(s)  strnlen_user(s, ~0UL >> 1)
 287
 288static inline long strnlen_user(const char *s, long n)
 289{
 290        unsigned long res = 0;
 291
 292        if (__addr_ok(s))
 293                __do_strnlen_user(s, n, res);
 294
 295        return res;
 296}
 297
 298#endif /* _ASMARM_UACCESS_H */
 299
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.