linux/arch/score/include/asm/uaccess.h
<<
>>
Prefs
   1#ifndef __SCORE_UACCESS_H
   2#define __SCORE_UACCESS_H
   3
   4#include <linux/kernel.h>
   5#include <linux/errno.h>
   6#include <linux/thread_info.h>
   7
   8#define VERIFY_READ             0
   9#define VERIFY_WRITE            1
  10
  11#define get_ds()                (KERNEL_DS)
  12#define get_fs()                (current_thread_info()->addr_limit)
  13#define segment_eq(a, b)        ((a).seg == (b).seg)
  14
  15/*
  16 * Is a address valid? This does a straighforward calculation rather
  17 * than tests.
  18 *
  19 * Address valid if:
  20 *  - "addr" doesn't have any high-bits set
  21 *  - AND "size" doesn't have any high-bits set
  22 *  - AND "addr+size" doesn't have any high-bits set
  23 *  - OR we are in kernel mode.
  24 *
  25 * __ua_size() is a trick to avoid runtime checking of positive constant
  26 * sizes; for those we already know at compile time that the size is ok.
  27 */
  28#define __ua_size(size)                                                 \
  29        ((__builtin_constant_p(size) && (signed long) (size) > 0) ? 0 : (size))
  30
  31/*
  32 * access_ok: - Checks if a user space pointer is valid
  33 * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE.  Note that
  34 *        %VERIFY_WRITE is a superset of %VERIFY_READ - if it is safe
  35 *        to write to a block, it is always safe to read from it.
  36 * @addr: User space pointer to start of block to check
  37 * @size: Size of block to check
  38 *
  39 * Context: User context only.  This function may sleep.
  40 *
  41 * Checks if a pointer to a block of memory in user space is valid.
  42 *
  43 * Returns true (nonzero) if the memory block may be valid, false (zero)
  44 * if it is definitely invalid.
  45 *
  46 * Note that, depending on architecture, this function probably just
  47 * checks that the pointer is in the user space range - after calling
  48 * this function, memory access functions may still return -EFAULT.
  49 */
  50
  51#define __access_ok(addr, size)                                 \
  52        (((long)((get_fs().seg) &                               \
  53                 ((addr) | ((addr) + (size)) |                  \
  54                  __ua_size(size)))) == 0)
  55
  56#define access_ok(type, addr, size)                             \
  57        likely(__access_ok((unsigned long)(addr), (size)))
  58
  59/*
  60 * put_user: - Write a simple value into user space.
  61 * @x:   Value to copy to user space.
  62 * @ptr: Destination address, in user space.
  63 *
  64 * Context: User context only.  This function may sleep.
  65 *
  66 * This macro copies a single simple value from kernel space to user
  67 * space.  It supports simple types like char and int, but not larger
  68 * data types like structures or arrays.
  69 *
  70 * @ptr must have pointer-to-simple-variable type, and @x must be assignable
  71 * to the result of dereferencing @ptr.
  72 *
  73 * Returns zero on success, or -EFAULT on error.
  74 */
  75#define put_user(x, ptr) __put_user_check((x), (ptr), sizeof(*(ptr)))
  76
  77/*
  78 * get_user: - Get a simple variable from user space.
  79 * @x:   Variable to store result.
  80 * @ptr: Source address, in user space.
  81 *
  82 * Context: User context only.  This function may sleep.
  83 *
  84 * This macro copies a single simple variable from user space to kernel
  85 * space.  It supports simple types like char and int, but not larger
  86 * data types like structures or arrays.
  87 *
  88 * @ptr must have pointer-to-simple-variable type, and the result of
  89 * dereferencing @ptr must be assignable to @x without a cast.
  90 *
  91 * Returns zero on success, or -EFAULT on error.
  92 * On error, the variable @x is set to zero.
  93 */
  94#define get_user(x, ptr) __get_user_check((x), (ptr), sizeof(*(ptr)))
  95
  96/*
  97 * __put_user: - Write a simple value into user space, with less checking.
  98 * @x:   Value to copy to user space.
  99 * @ptr: Destination address, in user space.
 100 *
 101 * Context: User context only.  This function may sleep.
 102 *
 103 * This macro copies a single simple value from kernel space to user
 104 * space.  It supports simple types like char and int, but not larger
 105 * data types like structures or arrays.
 106 *
 107 * @ptr must have pointer-to-simple-variable type, and @x must be assignable
 108 * to the result of dereferencing @ptr.
 109 *
 110 * Caller must check the pointer with access_ok() before calling this
 111 * function.
 112 *
 113 * Returns zero on success, or -EFAULT on error.
 114 */
 115#define __put_user(x, ptr) __put_user_nocheck((x), (ptr), sizeof(*(ptr)))
 116
 117/*
 118 * __get_user: - Get a simple variable from user space, with less checking.
 119 * @x:   Variable to store result.
 120 * @ptr: Source address, in user space.
 121 *
 122 * Context: User context only.  This function may sleep.
 123 *
 124 * This macro copies a single simple variable from user space to kernel
 125 * space.  It supports simple types like char and int, but not larger
 126 * data types like structures or arrays.
 127 *
 128 * @ptr must have pointer-to-simple-variable type, and the result of
 129 * dereferencing @ptr must be assignable to @x without a cast.
 130 *
 131 * Caller must check the pointer with access_ok() before calling this
 132 * function.
 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) __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
 138
 139struct __large_struct { unsigned long buf[100]; };
 140#define __m(x) (*(struct __large_struct __user *)(x))
 141
 142/*
 143 * Yuck.  We need two variants, one for 64bit operation and one
 144 * for 32 bit mode and old iron.
 145 */
 146extern void __get_user_unknown(void);
 147
 148#define __get_user_common(val, size, ptr)                               \
 149do {                                                                    \
 150        switch (size) {                                                 \
 151        case 1:                                                         \
 152                __get_user_asm(val, "lb", ptr);                         \
 153                break;                                                  \
 154        case 2:                                                         \
 155                __get_user_asm(val, "lh", ptr);                         \
 156                 break;                                                 \
 157        case 4:                                                         \
 158                __get_user_asm(val, "lw", ptr);                         \
 159                 break;                                                 \
 160        case 8:                                                         \
 161                if ((copy_from_user((void *)&val, ptr, 8)) == 0)        \
 162                        __gu_err = 0;                                   \
 163                else                                                    \
 164                        __gu_err = -EFAULT;                             \
 165                break;                                                  \
 166        default:                                                        \
 167                __get_user_unknown();                                   \
 168                break;                                                  \
 169        }                                                               \
 170} while (0)
 171
 172#define __get_user_nocheck(x, ptr, size)                                \
 173({                                                                      \
 174        long __gu_err = 0;                                              \
 175        __get_user_common((x), size, ptr);                              \
 176        __gu_err;                                                       \
 177})
 178
 179#define __get_user_check(x, ptr, size)                                  \
 180({                                                                      \
 181        long __gu_err = -EFAULT;                                        \
 182        const __typeof__(*(ptr)) __user *__gu_ptr = (ptr);              \
 183                                                                        \
 184        if (likely(access_ok(VERIFY_READ, __gu_ptr, size)))             \
 185                __get_user_common((x), size, __gu_ptr);                 \
 186                                                                        \
 187        __gu_err;                                                       \
 188})
 189
 190#define __get_user_asm(val, insn, addr)                                 \
 191{                                                                       \
 192        long __gu_tmp;                                                  \
 193                                                                        \
 194        __asm__ __volatile__(                                           \
 195                "1:" insn " %1, %3\n"                                   \
 196                "2:\n"                                                  \
 197                ".section .fixup,\"ax\"\n"                              \
 198                "3:li   %0, %4\n"                                       \
 199                "j      2b\n"                                           \
 200                ".previous\n"                                           \
 201                ".section __ex_table,\"a\"\n"                           \
 202                ".word  1b, 3b\n"                                       \
 203                ".previous\n"                                           \
 204                : "=r" (__gu_err), "=r" (__gu_tmp)                      \
 205                : "0" (0), "o" (__m(addr)), "i" (-EFAULT));             \
 206                                                                        \
 207                (val) = (__typeof__(*(addr))) __gu_tmp;                 \
 208}
 209
 210/*
 211 * Yuck.  We need two variants, one for 64bit operation and one
 212 * for 32 bit mode and old iron.
 213 */
 214#define __put_user_nocheck(val, ptr, size)                              \
 215({                                                                      \
 216        __typeof__(*(ptr)) __pu_val;                                    \
 217        long __pu_err = 0;                                              \
 218                                                                        \
 219        __pu_val = (val);                                               \
 220        switch (size) {                                                 \
 221        case 1:                                                         \
 222                __put_user_asm("sb", ptr);                              \
 223                break;                                                  \
 224        case 2:                                                         \
 225                __put_user_asm("sh", ptr);                              \
 226                break;                                                  \
 227        case 4:                                                         \
 228                __put_user_asm("sw", ptr);                              \
 229                break;                                                  \
 230        case 8:                                                         \
 231                if ((__copy_to_user((void *)ptr, &__pu_val, 8)) == 0)   \
 232                        __pu_err = 0;                                   \
 233                else                                                    \
 234                        __pu_err = -EFAULT;                             \
 235                break;                                                  \
 236        default:                                                        \
 237                 __put_user_unknown();                                  \
 238                 break;                                                 \
 239        }                                                               \
 240        __pu_err;                                                       \
 241})
 242
 243
 244#define __put_user_check(val, ptr, size)                                \
 245({                                                                      \
 246        __typeof__(*(ptr)) __user *__pu_addr = (ptr);                   \
 247        __typeof__(*(ptr)) __pu_val = (val);                            \
 248        long __pu_err = -EFAULT;                                        \
 249                                                                        \
 250        if (likely(access_ok(VERIFY_WRITE, __pu_addr, size))) {         \
 251                switch (size) {                                         \
 252                case 1:                                                 \
 253                        __put_user_asm("sb", __pu_addr);                \
 254                        break;                                          \
 255                case 2:                                                 \
 256                        __put_user_asm("sh", __pu_addr);                \
 257                        break;                                          \
 258                case 4:                                                 \
 259                        __put_user_asm("sw", __pu_addr);                \
 260                        break;                                          \
 261                case 8:                                                 \
 262                        if ((__copy_to_user((void *)__pu_addr, &__pu_val, 8)) == 0)\
 263                                __pu_err = 0;                           \
 264                        else                                            \
 265                                __pu_err = -EFAULT;                     \
 266                        break;                                          \
 267                default:                                                \
 268                        __put_user_unknown();                           \
 269                        break;                                          \
 270                }                                                       \
 271        }                                                               \
 272        __pu_err;                                                       \
 273})
 274
 275#define __put_user_asm(insn, ptr)                                       \
 276        __asm__ __volatile__(                                           \
 277                "1:" insn " %2, %3\n"                                   \
 278                "2:\n"                                                  \
 279                ".section .fixup,\"ax\"\n"                              \
 280                "3:li %0, %4\n"                                         \
 281                "j 2b\n"                                                \
 282                ".previous\n"                                           \
 283                ".section __ex_table,\"a\"\n"                           \
 284                ".word 1b, 3b\n"                                        \
 285                ".previous\n"                                           \
 286                : "=r" (__pu_err)                                       \
 287                : "0" (0), "r" (__pu_val), "o" (__m(ptr)),              \
 288                  "i" (-EFAULT));
 289
 290extern void __put_user_unknown(void);
 291extern int __copy_tofrom_user(void *to, const void *from, unsigned long len);
 292
 293static inline unsigned long
 294copy_from_user(void *to, const void *from, unsigned long len)
 295{
 296        unsigned long over;
 297
 298        if (access_ok(VERIFY_READ, from, len))
 299                return __copy_tofrom_user(to, from, len);
 300
 301        if ((unsigned long)from < TASK_SIZE) {
 302                over = (unsigned long)from + len - TASK_SIZE;
 303                return __copy_tofrom_user(to, from, len - over) + over;
 304        }
 305        return len;
 306}
 307
 308static inline unsigned long
 309copy_to_user(void *to, const void *from, unsigned long len)
 310{
 311        unsigned long over;
 312
 313        if (access_ok(VERIFY_WRITE, to, len))
 314                return __copy_tofrom_user(to, from, len);
 315
 316        if ((unsigned long)to < TASK_SIZE) {
 317                over = (unsigned long)to + len - TASK_SIZE;
 318                return __copy_tofrom_user(to, from, len - over) + over;
 319        }
 320        return len;
 321}
 322
 323#define __copy_from_user(to, from, len) \
 324                __copy_tofrom_user((to), (from), (len))
 325
 326#define __copy_to_user(to, from, len)           \
 327                __copy_tofrom_user((to), (from), (len))
 328
 329static inline unsigned long
 330__copy_to_user_inatomic(void *to, const void *from, unsigned long len)
 331{
 332        return __copy_to_user(to, from, len);
 333}
 334
 335static inline unsigned long
 336__copy_from_user_inatomic(void *to, const void *from, unsigned long len)
 337{
 338        return __copy_from_user(to, from, len);
 339}
 340
 341#define __copy_in_user(to, from, len)   __copy_from_user(to, from, len)
 342
 343static inline unsigned long
 344copy_in_user(void *to, const void *from, unsigned long len)
 345{
 346        if (access_ok(VERIFY_READ, from, len) &&
 347                      access_ok(VERFITY_WRITE, to, len))
 348                return copy_from_user(to, from, len);
 349}
 350
 351/*
 352 * __clear_user: - Zero a block of memory in user space, with less checking.
 353 * @to:   Destination address, in user space.
 354 * @n:    Number of bytes to zero.
 355 *
 356 * Zero a block of memory in user space.  Caller must check
 357 * the specified block with access_ok() before calling this function.
 358 *
 359 * Returns number of bytes that could not be cleared.
 360 * On success, this will be zero.
 361 */
 362extern unsigned long __clear_user(void __user *src, unsigned long size);
 363
 364static inline unsigned long clear_user(char *src, unsigned long size)
 365{
 366        if (access_ok(VERIFY_WRITE, src, size))
 367                return __clear_user(src, size);
 368
 369        return -EFAULT;
 370}
 371/*
 372 * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
 373 * @dst:   Destination address, in kernel space.  This buffer must be at
 374 *         least @count bytes long.
 375 * @src:   Source address, in user space.
 376 * @count: Maximum number of bytes to copy, including the trailing NUL.
 377 *
 378 * Copies a NUL-terminated string from userspace to kernel space.
 379 * Caller must check the specified block with access_ok() before calling
 380 * this function.
 381 *
 382 * On success, returns the length of the string (not including the trailing
 383 * NUL).
 384 *
 385 * If access to userspace fails, returns -EFAULT (some data may have been
 386 * copied).
 387 *
 388 * If @count is smaller than the length of the string, copies @count bytes
 389 * and returns @count.
 390 */
 391extern int __strncpy_from_user(char *dst, const char *src, long len);
 392
 393static inline int strncpy_from_user(char *dst, const char *src, long len)
 394{
 395        if (access_ok(VERIFY_READ, src, 1))
 396                return __strncpy_from_user(dst, src, len);
 397
 398        return -EFAULT;
 399}
 400
 401extern int __strlen_user(const char *src);
 402static inline long strlen_user(const char __user *src)
 403{
 404        return __strlen_user(src);
 405}
 406
 407extern int __strnlen_user(const char *str, long len);
 408static inline long strnlen_user(const char __user *str, long len)
 409{
 410        if (!access_ok(VERIFY_READ, str, 0))
 411                return 0;
 412        else            
 413                return __strnlen_user(str, len);
 414}
 415
 416struct exception_table_entry {
 417        unsigned long insn;
 418        unsigned long fixup;
 419};
 420
 421extern int fixup_exception(struct pt_regs *regs);
 422
 423#endif /* __SCORE_UACCESS_H */
 424
 425