GNU Linux-libre 4.14.290-gnu1
[releases.git] / arch / mn10300 / lib / usercopy.c
1 /* MN10300 Userspace accessor functions
2  *
3  * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
4  * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
5  * Written by David Howells (dhowells@redhat.com)
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public Licence
9  * as published by the Free Software Foundation; either version
10  * 2 of the Licence, or (at your option) any later version.
11  */
12 #include <linux/uaccess.h>
13
14 /*
15  * Copy a null terminated string from userspace.
16  */
17 #define __do_strncpy_from_user(dst, src, count, res)            \
18 do {                                                            \
19         int w;                                                  \
20         asm volatile(                                           \
21                 "       mov     %1,%0\n"                        \
22                 "       cmp     0,%1\n"                         \
23                 "       beq     2f\n"                           \
24                 "0:\n"                                          \
25                 "       movbu   (%5),%2\n"                      \
26                 "1:\n"                                          \
27                 "       movbu   %2,(%6)\n"                      \
28                 "       inc     %5\n"                           \
29                 "       inc     %6\n"                           \
30                 "       cmp     0,%2\n"                         \
31                 "       beq     2f\n"                           \
32                 "       add     -1,%1\n"                        \
33                 "       bne     0b\n"                           \
34                 "2:\n"                                          \
35                 "       sub     %1,%0\n"                        \
36                 "3:\n"                                          \
37                 "       .section .fixup,\"ax\"\n"               \
38                 "4:\n"                                          \
39                 "       mov     %3,%0\n"                        \
40                 "       jmp     3b\n"                           \
41                 "       .previous\n"                            \
42                 "       .section __ex_table,\"a\"\n"            \
43                 "       .balign 4\n"                            \
44                 "       .long 0b,4b\n"                          \
45                 "       .long 1b,4b\n"                          \
46                 "       .previous"                              \
47                 :"=&r"(res), "=r"(count), "=&r"(w)              \
48                 :"i"(-EFAULT), "1"(count), "a"(src), "a"(dst)   \
49                 : "memory", "cc");                                      \
50 } while (0)
51
52 long
53 strncpy_from_user(char *dst, const char *src, long count)
54 {
55         long res = -EFAULT;
56         if (access_ok(VERIFY_READ, src, 1))
57                 __do_strncpy_from_user(dst, src, count, res);
58         return res;
59 }
60
61
62 /*
63  * Clear a userspace memory
64  */
65 #define __do_clear_user(addr, size)             \
66 do {                                            \
67         int w;                                  \
68         asm volatile(                           \
69                 "       cmp 0,%0\n"             \
70                 "       beq 1f\n"               \
71                 "       clr %1\n"               \
72                 "0:     movbu %1,(%3,%2)\n"     \
73                 "       inc %3\n"               \
74                 "       cmp %0,%3\n"            \
75                 "       bne 0b\n"               \
76                 "1:\n"                          \
77                 "       sub %3,%0\n"            \
78                 "2:\n"                          \
79                 ".section .fixup,\"ax\"\n"      \
80                 "3:     jmp 2b\n"               \
81                 ".previous\n"                   \
82                 ".section __ex_table,\"a\"\n"   \
83                 "       .balign 4\n"            \
84                 "       .long 0b,3b\n"          \
85                 ".previous\n"                   \
86                 : "+r"(size), "=&r"(w)          \
87                 : "a"(addr), "d"(0)             \
88                 : "memory", "cc");              \
89 } while (0)
90
91 unsigned long
92 __clear_user(void *to, unsigned long n)
93 {
94         __do_clear_user(to, n);
95         return n;
96 }
97
98 unsigned long
99 clear_user(void *to, unsigned long n)
100 {
101         if (access_ok(VERIFY_WRITE, to, n))
102                 __do_clear_user(to, n);
103         return n;
104 }
105
106 /*
107  * Return the size of a string (including the ending 0)
108  *
109  * Return 0 on exception, a value greater than N if too long
110  */
111 long strnlen_user(const char *s, long n)
112 {
113         unsigned long res, w;
114
115         if (!__addr_ok(s))
116                 return 0;
117
118         if (n < 0 || n + (u_long) s > current_thread_info()->addr_limit.seg)
119                 n = current_thread_info()->addr_limit.seg - (u_long)s;
120
121         asm volatile(
122                 "0:     cmp %4,%0\n"
123                 "       beq 2f\n"
124                 "1:     movbu (%0,%3),%1\n"
125                 "       inc %0\n"
126                 "       cmp 0,%1\n"
127                 "       beq 3f\n"
128                 "       bra 0b\n"
129                 "2:     clr %0\n"
130                 "3:\n"
131                 ".section .fixup,\"ax\"\n"
132                 "4:     jmp 2b\n"
133                 ".previous\n"
134                 ".section __ex_table,\"a\"\n"
135                 "       .balign 4\n"
136                 "       .long 1b,4b\n"
137                 ".previous\n"
138                 :"=d"(res), "=&r"(w)
139                 :"0"(0), "a"(s), "r"(n)
140                 : "memory", "cc");
141         return res;
142 }