linux/arch/blackfin/include/asm/uaccess.h
<<
>>
Prefs
   1/*
   2 * Copyright 2004-2009 Analog Devices Inc.
   3 *
   4 * Licensed under the GPL-2 or later.
   5 *
   6 * Based on: include/asm-m68knommu/uaccess.h
   7 */
   8
   9#ifndef __BLACKFIN_UACCESS_H
  10#define __BLACKFIN_UACCESS_H
  11
  12/*
  13 * User space memory access functions
  14 */
  15#include <linux/mm.h>
  16#include <linux/string.h>
  17
  18#include <asm/segment.h>
  19#include <asm/sections.h>
  20
  21#define get_ds()        (KERNEL_DS)
  22#define get_fs()        (current_thread_info()->addr_limit)
  23
  24static inline void set_fs(mm_segment_t fs)
  25{
  26        current_thread_info()->addr_limit = fs;
  27}
  28
  29#define segment_eq(a, b) ((a) == (b))
  30
  31#define access_ok(type, addr, size) _access_ok((unsigned long)(addr), (size))
  32
  33/*
  34 * The fs value determines whether argument validity checking should be
  35 * performed or not.  If get_fs() == USER_DS, checking is performed, with
  36 * get_fs() == KERNEL_DS, checking is bypassed.
  37 */
  38
  39#ifndef CONFIG_ACCESS_CHECK
  40static inline int _access_ok(unsigned long addr, unsigned long size) { return 1; }
  41#else
  42extern int _access_ok(unsigned long addr, unsigned long size);
  43#endif
  44
  45#include <asm/extable.h>
  46
  47/*
  48 * These are the main single-value transfer routines.  They automatically
  49 * use the right size if we just have the right pointer type.
  50 */
  51
  52#define put_user(x, p)                                          \
  53        ({                                                      \
  54                int _err = 0;                                   \
  55                typeof(*(p)) _x = (x);                          \
  56                typeof(*(p)) __user *_p = (p);                  \
  57                if (!access_ok(VERIFY_WRITE, _p, sizeof(*(_p)))) {\
  58                        _err = -EFAULT;                         \
  59                }                                               \
  60                else {                                          \
  61                switch (sizeof (*(_p))) {                       \
  62                case 1:                                         \
  63                        __put_user_asm(_x, _p, B);              \
  64                        break;                                  \
  65                case 2:                                         \
  66                        __put_user_asm(_x, _p, W);              \
  67                        break;                                  \
  68                case 4:                                         \
  69                        __put_user_asm(_x, _p,  );              \
  70                        break;                                  \
  71                case 8: {                                       \
  72                        long _xl, _xh;                          \
  73                        _xl = ((__force long *)&_x)[0];         \
  74                        _xh = ((__force long *)&_x)[1];         \
  75                        __put_user_asm(_xl, ((__force long __user *)_p)+0, );\
  76                        __put_user_asm(_xh, ((__force long __user *)_p)+1, );\
  77                } break;                                        \
  78                default:                                        \
  79                        _err = __put_user_bad();                \
  80                        break;                                  \
  81                }                                               \
  82                }                                               \
  83                _err;                                           \
  84        })
  85
  86#define __put_user(x, p) put_user(x, p)
  87static inline int bad_user_access_length(void)
  88{
  89        panic("bad_user_access_length");
  90        return -1;
  91}
  92
  93#define __put_user_bad() (printk(KERN_INFO "put_user_bad %s:%d %s\n",\
  94                           __FILE__, __LINE__, __func__),\
  95                           bad_user_access_length(), (-EFAULT))
  96
  97/*
  98 * Tell gcc we read from memory instead of writing: this is because
  99 * we do not write to any memory gcc knows about, so there are no
 100 * aliasing issues.
 101 */
 102
 103#define __ptr(x) ((unsigned long __force *)(x))
 104
 105#define __put_user_asm(x, p, bhw)                       \
 106        __asm__ (#bhw"[%1] = %0;\n\t"                   \
 107                 : /* no outputs */                     \
 108                 :"d" (x), "a" (__ptr(p)) : "memory")
 109
 110#define get_user(x, ptr)                                        \
 111({                                                              \
 112        int _err = 0;                                           \
 113        unsigned long _val = 0;                                 \
 114        const typeof(*(ptr)) __user *_p = (ptr);                \
 115        const size_t ptr_size = sizeof(*(_p));                  \
 116        if (likely(access_ok(VERIFY_READ, _p, ptr_size))) {     \
 117                BUILD_BUG_ON(ptr_size >= 8);                    \
 118                switch (ptr_size) {                             \
 119                case 1:                                         \
 120                        __get_user_asm(_val, _p, B, (Z));       \
 121                        break;                                  \
 122                case 2:                                         \
 123                        __get_user_asm(_val, _p, W, (Z));       \
 124                        break;                                  \
 125                case 4:                                         \
 126                        __get_user_asm(_val, _p,  , );          \
 127                        break;                                  \
 128                }                                               \
 129        } else                                                  \
 130                _err = -EFAULT;                                 \
 131        x = (__force typeof(*(ptr)))_val;                       \
 132        _err;                                                   \
 133})
 134
 135#define __get_user(x, p) get_user(x, p)
 136
 137#define __get_user_bad() (bad_user_access_length(), (-EFAULT))
 138
 139#define __get_user_asm(x, ptr, bhw, option)     \
 140({                                              \
 141        __asm__ __volatile__ (                  \
 142                "%0 =" #bhw "[%1]" #option ";"  \
 143                : "=d" (x)                      \
 144                : "a" (__ptr(ptr)));            \
 145})
 146
 147static inline unsigned long __must_check
 148raw_copy_from_user(void *to, const void __user *from, unsigned long n)
 149{
 150        memcpy(to, (const void __force *)from, n);
 151        return 0;
 152}
 153
 154static inline unsigned long __must_check
 155raw_copy_to_user(void __user *to, const void *from, unsigned long n)
 156{
 157        memcpy((void __force *)to, from, n);
 158        SSYNC();
 159        return 0;
 160}
 161
 162#define INLINE_COPY_FROM_USER
 163#define INLINE_COPY_TO_USER
 164/*
 165 * Copy a null terminated string from userspace.
 166 */
 167
 168static inline long __must_check
 169strncpy_from_user(char *dst, const char __user *src, long count)
 170{
 171        char *tmp;
 172        if (!access_ok(VERIFY_READ, src, 1))
 173                return -EFAULT;
 174        strncpy(dst, (const char __force *)src, count);
 175        for (tmp = dst; *tmp && count > 0; tmp++, count--) ;
 176        return (tmp - dst);
 177}
 178
 179/*
 180 * Get the size of a string in user space.
 181 *   src: The string to measure
 182 *     n: The maximum valid length
 183 *
 184 * Get the size of a NUL-terminated string in user space.
 185 *
 186 * Returns the size of the string INCLUDING the terminating NUL.
 187 * On exception, returns 0.
 188 * If the string is too long, returns a value greater than n.
 189 */
 190static inline long __must_check strnlen_user(const char __user *src, long n)
 191{
 192        if (!access_ok(VERIFY_READ, src, 1))
 193                return 0;
 194        return strnlen((const char __force *)src, n) + 1;
 195}
 196
 197/*
 198 * Zero Userspace
 199 */
 200
 201static inline unsigned long __must_check
 202__clear_user(void __user *to, unsigned long n)
 203{
 204        if (!access_ok(VERIFY_WRITE, to, n))
 205                return n;
 206        memset((void __force *)to, 0, n);
 207        return 0;
 208}
 209
 210#define clear_user(to, n) __clear_user(to, n)
 211
 212/* How to interpret these return values:
 213 *      CORE:      can be accessed by core load or dma memcpy
 214 *      CORE_ONLY: can only be accessed by core load
 215 *      DMA:       can only be accessed by dma memcpy
 216 *      IDMA:      can only be accessed by interprocessor dma memcpy (BF561)
 217 *      ITEST:     can be accessed by isram memcpy or dma memcpy
 218 */
 219enum {
 220        BFIN_MEM_ACCESS_CORE = 0,
 221        BFIN_MEM_ACCESS_CORE_ONLY,
 222        BFIN_MEM_ACCESS_DMA,
 223        BFIN_MEM_ACCESS_IDMA,
 224        BFIN_MEM_ACCESS_ITEST,
 225};
 226/**
 227 *      bfin_mem_access_type() - what kind of memory access is required
 228 *      @addr:   the address to check
 229 *      @size:   number of bytes needed
 230 *      @return: <0 is error, >=0 is BFIN_MEM_ACCESS_xxx enum (see above)
 231 */
 232int bfin_mem_access_type(unsigned long addr, unsigned long size);
 233
 234#endif                          /* _BLACKFIN_UACCESS_H */
 235