linux/arch/m68k/lib/uaccess.c
<<
>>
Prefs
   1/*
   2 * This file is subject to the terms and conditions of the GNU General Public
   3 * License.  See the file COPYING in the main directory of this archive
   4 * for more details.
   5 */
   6
   7#include <linux/module.h>
   8#include <asm/uaccess.h>
   9
  10unsigned long __generic_copy_from_user(void *to, const void __user *from,
  11                                       unsigned long n)
  12{
  13        unsigned long tmp, res;
  14
  15        asm volatile ("\n"
  16                "       tst.l   %0\n"
  17                "       jeq     2f\n"
  18                "1:     "MOVES".l       (%1)+,%3\n"
  19                "       move.l  %3,(%2)+\n"
  20                "       subq.l  #1,%0\n"
  21                "       jne     1b\n"
  22                "2:     btst    #1,%5\n"
  23                "       jeq     4f\n"
  24                "3:     "MOVES".w       (%1)+,%3\n"
  25                "       move.w  %3,(%2)+\n"
  26                "4:     btst    #0,%5\n"
  27                "       jeq     6f\n"
  28                "5:     "MOVES".b       (%1)+,%3\n"
  29                "       move.b  %3,(%2)+\n"
  30                "6:\n"
  31                "       .section .fixup,\"ax\"\n"
  32                "       .even\n"
  33                "10:    move.l  %0,%3\n"
  34                "7:     clr.l   (%2)+\n"
  35                "       subq.l  #1,%3\n"
  36                "       jne     7b\n"
  37                "       lsl.l   #2,%0\n"
  38                "       btst    #1,%5\n"
  39                "       jeq     8f\n"
  40                "30:    clr.w   (%2)+\n"
  41                "       addq.l  #2,%0\n"
  42                "8:     btst    #0,%5\n"
  43                "       jeq     6b\n"
  44                "50:    clr.b   (%2)+\n"
  45                "       addq.l  #1,%0\n"
  46                "       jra     6b\n"
  47                "       .previous\n"
  48                "\n"
  49                "       .section __ex_table,\"a\"\n"
  50                "       .align  4\n"
  51                "       .long   1b,10b\n"
  52                "       .long   3b,30b\n"
  53                "       .long   5b,50b\n"
  54                "       .previous"
  55                : "=d" (res), "+a" (from), "+a" (to), "=&r" (tmp)
  56                : "0" (n / 4), "d" (n & 3));
  57
  58        return res;
  59}
  60EXPORT_SYMBOL(__generic_copy_from_user);
  61
  62unsigned long __generic_copy_to_user(void __user *to, const void *from,
  63                                     unsigned long n)
  64{
  65        unsigned long tmp, res;
  66
  67        asm volatile ("\n"
  68                "       tst.l   %0\n"
  69                "       jeq     4f\n"
  70                "1:     move.l  (%1)+,%3\n"
  71                "2:     "MOVES".l       %3,(%2)+\n"
  72                "3:     subq.l  #1,%0\n"
  73                "       jne     1b\n"
  74                "4:     btst    #1,%5\n"
  75                "       jeq     6f\n"
  76                "       move.w  (%1)+,%3\n"
  77                "5:     "MOVES".w       %3,(%2)+\n"
  78                "6:     btst    #0,%5\n"
  79                "       jeq     8f\n"
  80                "       move.b  (%1)+,%3\n"
  81                "7:     "MOVES".b  %3,(%2)+\n"
  82                "8:\n"
  83                "       .section .fixup,\"ax\"\n"
  84                "       .even\n"
  85                "20:    lsl.l   #2,%0\n"
  86                "50:    add.l   %5,%0\n"
  87                "       jra     8b\n"
  88                "       .previous\n"
  89                "\n"
  90                "       .section __ex_table,\"a\"\n"
  91                "       .align  4\n"
  92                "       .long   2b,20b\n"
  93                "       .long   3b,20b\n"
  94                "       .long   5b,50b\n"
  95                "       .long   6b,50b\n"
  96                "       .long   7b,50b\n"
  97                "       .long   8b,50b\n"
  98                "       .previous"
  99                : "=d" (res), "+a" (from), "+a" (to), "=&r" (tmp)
 100                : "0" (n / 4), "d" (n & 3));
 101
 102        return res;
 103}
 104EXPORT_SYMBOL(__generic_copy_to_user);
 105
 106/*
 107 * Copy a null terminated string from userspace.
 108 */
 109long strncpy_from_user(char *dst, const char __user *src, long count)
 110{
 111        long res;
 112        char c;
 113
 114        if (count <= 0)
 115                return count;
 116
 117        asm volatile ("\n"
 118                "1:     "MOVES".b       (%2)+,%4\n"
 119                "       move.b  %4,(%1)+\n"
 120                "       jeq     2f\n"
 121                "       subq.l  #1,%3\n"
 122                "       jne     1b\n"
 123                "2:     sub.l   %3,%0\n"
 124                "3:\n"
 125                "       .section .fixup,\"ax\"\n"
 126                "       .even\n"
 127                "10:    move.l  %5,%0\n"
 128                "       jra     3b\n"
 129                "       .previous\n"
 130                "\n"
 131                "       .section __ex_table,\"a\"\n"
 132                "       .align  4\n"
 133                "       .long   1b,10b\n"
 134                "       .previous"
 135                : "=d" (res), "+a" (dst), "+a" (src), "+r" (count), "=&d" (c)
 136                : "i" (-EFAULT), "0" (count));
 137
 138        return res;
 139}
 140EXPORT_SYMBOL(strncpy_from_user);
 141
 142/*
 143 * Return the size of a string (including the ending 0)
 144 *
 145 * Return 0 on exception, a value greater than N if too long
 146 */
 147long strnlen_user(const char __user *src, long n)
 148{
 149        char c;
 150        long res;
 151
 152        asm volatile ("\n"
 153                "1:     subq.l  #1,%1\n"
 154                "       jmi     3f\n"
 155                "2:     "MOVES".b       (%0)+,%2\n"
 156                "       tst.b   %2\n"
 157                "       jne     1b\n"
 158                "       jra     4f\n"
 159                "\n"
 160                "3:     addq.l  #1,%0\n"
 161                "4:     sub.l   %4,%0\n"
 162                "5:\n"
 163                "       .section .fixup,\"ax\"\n"
 164                "       .even\n"
 165                "20:    sub.l   %0,%0\n"
 166                "       jra     5b\n"
 167                "       .previous\n"
 168                "\n"
 169                "       .section __ex_table,\"a\"\n"
 170                "       .align  4\n"
 171                "       .long   2b,20b\n"
 172                "       .previous\n"
 173                : "=&a" (res), "+d" (n), "=&d" (c)
 174                : "0" (src), "r" (src));
 175
 176        return res;
 177}
 178EXPORT_SYMBOL(strnlen_user);
 179
 180/*
 181 * Zero Userspace
 182 */
 183
 184unsigned long __clear_user(void __user *to, unsigned long n)
 185{
 186        unsigned long res;
 187
 188        asm volatile ("\n"
 189                "       tst.l   %0\n"
 190                "       jeq     3f\n"
 191                "1:     "MOVES".l       %2,(%1)+\n"
 192                "2:     subq.l  #1,%0\n"
 193                "       jne     1b\n"
 194                "3:     btst    #1,%4\n"
 195                "       jeq     5f\n"
 196                "4:     "MOVES".w       %2,(%1)+\n"
 197                "5:     btst    #0,%4\n"
 198                "       jeq     7f\n"
 199                "6:     "MOVES".b       %2,(%1)\n"
 200                "7:\n"
 201                "       .section .fixup,\"ax\"\n"
 202                "       .even\n"
 203                "10:    lsl.l   #2,%0\n"
 204                "40:    add.l   %4,%0\n"
 205                "       jra     7b\n"
 206                "       .previous\n"
 207                "\n"
 208                "       .section __ex_table,\"a\"\n"
 209                "       .align  4\n"
 210                "       .long   1b,10b\n"
 211                "       .long   2b,10b\n"
 212                "       .long   4b,40b\n"
 213                "       .long   5b,40b\n"
 214                "       .long   6b,40b\n"
 215                "       .long   7b,40b\n"
 216                "       .previous"
 217                : "=d" (res), "+a" (to)
 218                : "r" (0), "0" (n / 4), "d" (n & 3));
 219
 220    return res;
 221}
 222EXPORT_SYMBOL(__clear_user);
 223