root/arch/nios2/include/asm/uaccess.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. __clear_user
  2. clear_user

   1 /*
   2  * User space memory access functions for Nios II
   3  *
   4  * Copyright (C) 2010-2011, Tobias Klauser <tklauser@distanz.ch>
   5  * Copyright (C) 2009, Wind River Systems Inc
   6  *   Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
   7  *
   8  * This file is subject to the terms and conditions of the GNU General Public
   9  * License.  See the file "COPYING" in the main directory of this archive
  10  * for more details.
  11  */
  12 
  13 #ifndef _ASM_NIOS2_UACCESS_H
  14 #define _ASM_NIOS2_UACCESS_H
  15 
  16 #include <linux/string.h>
  17 
  18 #include <asm/page.h>
  19 
  20 #include <asm/extable.h>
  21 
  22 /*
  23  * Segment stuff
  24  */
  25 #define MAKE_MM_SEG(s)          ((mm_segment_t) { (s) })
  26 #define USER_DS                 MAKE_MM_SEG(0x80000000UL)
  27 #define KERNEL_DS               MAKE_MM_SEG(0)
  28 
  29 
  30 #define get_fs()                (current_thread_info()->addr_limit)
  31 #define set_fs(seg)             (current_thread_info()->addr_limit = (seg))
  32 
  33 #define segment_eq(a, b)        ((a).seg == (b).seg)
  34 
  35 #define __access_ok(addr, len)                  \
  36         (((signed long)(((long)get_fs().seg) &  \
  37                 ((long)(addr) | (((long)(addr)) + (len)) | (len)))) == 0)
  38 
  39 #define access_ok(addr, len)            \
  40         likely(__access_ok((unsigned long)(addr), (unsigned long)(len)))
  41 
  42 # define __EX_TABLE_SECTION     ".section __ex_table,\"a\"\n"
  43 
  44 #define user_addr_max() (uaccess_kernel() ? ~0UL : TASK_SIZE)
  45 
  46 /*
  47  * Zero Userspace
  48  */
  49 
  50 static inline unsigned long __must_check __clear_user(void __user *to,
  51                                                       unsigned long n)
  52 {
  53         __asm__ __volatile__ (
  54                 "1:     stb     zero, 0(%1)\n"
  55                 "       addi    %0, %0, -1\n"
  56                 "       addi    %1, %1, 1\n"
  57                 "       bne     %0, zero, 1b\n"
  58                 "2:\n"
  59                 __EX_TABLE_SECTION
  60                 ".word  1b, 2b\n"
  61                 ".previous\n"
  62                 : "=r" (n), "=r" (to)
  63                 : "0" (n), "1" (to)
  64         );
  65 
  66         return n;
  67 }
  68 
  69 static inline unsigned long __must_check clear_user(void __user *to,
  70                                                     unsigned long n)
  71 {
  72         if (!access_ok(to, n))
  73                 return n;
  74         return __clear_user(to, n);
  75 }
  76 
  77 extern unsigned long
  78 raw_copy_from_user(void *to, const void __user *from, unsigned long n);
  79 extern unsigned long
  80 raw_copy_to_user(void __user *to, const void *from, unsigned long n);
  81 #define INLINE_COPY_FROM_USER
  82 #define INLINE_COPY_TO_USER
  83 
  84 extern long strncpy_from_user(char *__to, const char __user *__from,
  85                               long __len);
  86 extern __must_check long strlen_user(const char __user *str);
  87 extern __must_check long strnlen_user(const char __user *s, long n);
  88 
  89 /* Optimized macros */
  90 #define __get_user_asm(val, insn, addr, err)                            \
  91 {                                                                       \
  92         __asm__ __volatile__(                                           \
  93         "       movi    %0, %3\n"                                       \
  94         "1:   " insn " %1, 0(%2)\n"                                     \
  95         "       movi     %0, 0\n"                                       \
  96         "2:\n"                                                          \
  97         "       .section __ex_table,\"a\"\n"                            \
  98         "       .word 1b, 2b\n"                                         \
  99         "       .previous"                                              \
 100         : "=&r" (err), "=r" (val)                                       \
 101         : "r" (addr), "i" (-EFAULT));                                   \
 102 }
 103 
 104 #define __get_user_unknown(val, size, ptr, err) do {                    \
 105         err = 0;                                                        \
 106         if (__copy_from_user(&(val), ptr, size)) {                      \
 107                 err = -EFAULT;                                          \
 108         }                                                               \
 109         } while (0)
 110 
 111 #define __get_user_common(val, size, ptr, err)                          \
 112 do {                                                                    \
 113         switch (size) {                                                 \
 114         case 1:                                                         \
 115                 __get_user_asm(val, "ldbu", ptr, err);                  \
 116                 break;                                                  \
 117         case 2:                                                         \
 118                 __get_user_asm(val, "ldhu", ptr, err);                  \
 119                 break;                                                  \
 120         case 4:                                                         \
 121                 __get_user_asm(val, "ldw", ptr, err);                   \
 122                 break;                                                  \
 123         default:                                                        \
 124                 __get_user_unknown(val, size, ptr, err);                \
 125                 break;                                                  \
 126         }                                                               \
 127 } while (0)
 128 
 129 #define __get_user(x, ptr)                                              \
 130         ({                                                              \
 131         long __gu_err = -EFAULT;                                        \
 132         const __typeof__(*(ptr)) __user *__gu_ptr = (ptr);              \
 133         unsigned long __gu_val = 0;                                     \
 134         __get_user_common(__gu_val, sizeof(*(ptr)), __gu_ptr, __gu_err);\
 135         (x) = (__force __typeof__(x))__gu_val;                          \
 136         __gu_err;                                                       \
 137         })
 138 
 139 #define get_user(x, ptr)                                                \
 140 ({                                                                      \
 141         long __gu_err = -EFAULT;                                        \
 142         const __typeof__(*(ptr)) __user *__gu_ptr = (ptr);              \
 143         unsigned long __gu_val = 0;                                     \
 144         if (access_ok( __gu_ptr, sizeof(*__gu_ptr)))    \
 145                 __get_user_common(__gu_val, sizeof(*__gu_ptr),          \
 146                         __gu_ptr, __gu_err);                            \
 147         (x) = (__force __typeof__(x))__gu_val;                          \
 148         __gu_err;                                                       \
 149 })
 150 
 151 #define __put_user_asm(val, insn, ptr, err)                             \
 152 {                                                                       \
 153         __asm__ __volatile__(                                           \
 154         "       movi    %0, %3\n"                                       \
 155         "1:   " insn " %1, 0(%2)\n"                                     \
 156         "       movi     %0, 0\n"                                       \
 157         "2:\n"                                                          \
 158         "       .section __ex_table,\"a\"\n"                            \
 159         "       .word 1b, 2b\n"                                         \
 160         "       .previous\n"                                            \
 161         : "=&r" (err)                                                   \
 162         : "r" (val), "r" (ptr), "i" (-EFAULT));                         \
 163 }
 164 
 165 #define put_user(x, ptr)                                                \
 166 ({                                                                      \
 167         long __pu_err = -EFAULT;                                        \
 168         __typeof__(*(ptr)) __user *__pu_ptr = (ptr);                    \
 169         __typeof__(*(ptr)) __pu_val = (__typeof(*ptr))(x);              \
 170         if (access_ok(__pu_ptr, sizeof(*__pu_ptr))) {   \
 171                 switch (sizeof(*__pu_ptr)) {                            \
 172                 case 1:                                                 \
 173                         __put_user_asm(__pu_val, "stb", __pu_ptr, __pu_err); \
 174                         break;                                          \
 175                 case 2:                                                 \
 176                         __put_user_asm(__pu_val, "sth", __pu_ptr, __pu_err); \
 177                         break;                                          \
 178                 case 4:                                                 \
 179                         __put_user_asm(__pu_val, "stw", __pu_ptr, __pu_err); \
 180                         break;                                          \
 181                 default:                                                \
 182                         /* XXX: This looks wrong... */                  \
 183                         __pu_err = 0;                                   \
 184                         if (copy_to_user(__pu_ptr, &(__pu_val),         \
 185                                 sizeof(*__pu_ptr)))                     \
 186                                 __pu_err = -EFAULT;                     \
 187                         break;                                          \
 188                 }                                                       \
 189         }                                                               \
 190         __pu_err;                                                       \
 191 })
 192 
 193 #define __put_user(x, ptr) put_user(x, ptr)
 194 
 195 #endif /* _ASM_NIOS2_UACCESS_H */

/* [<][>][^][v][top][bottom][index][help] */