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