1 /* SPDX-License-Identifier: GPL-2.0 */
2
3 #ifndef __ASM_CSKY_UACCESS_H
4 #define __ASM_CSKY_UACCESS_H
5
6 #define user_addr_max() \
7 (uaccess_kernel() ? KERNEL_DS.seg : get_fs().seg)
8
__access_ok(unsigned long addr,unsigned long size)9 static inline int __access_ok(unsigned long addr, unsigned long size)
10 {
11 unsigned long limit = current_thread_info()->addr_limit.seg;
12
13 return ((addr < limit) && ((addr + size) < limit));
14 }
15 #define __access_ok __access_ok
16
17 /*
18 * __put_user_fn
19 */
20 extern int __put_user_bad(void);
21
22 #define __put_user_asm_b(x, ptr, err) \
23 do { \
24 int errcode; \
25 __asm__ __volatile__( \
26 "1: stb %1, (%2,0) \n" \
27 " br 3f \n" \
28 "2: mov %0, %3 \n" \
29 " br 3f \n" \
30 ".section __ex_table, \"a\" \n" \
31 ".align 2 \n" \
32 ".long 1b,2b \n" \
33 ".previous \n" \
34 "3: \n" \
35 : "=r"(err), "=r"(x), "=r"(ptr), "=r"(errcode) \
36 : "0"(err), "1"(x), "2"(ptr), "3"(-EFAULT) \
37 : "memory"); \
38 } while (0)
39
40 #define __put_user_asm_h(x, ptr, err) \
41 do { \
42 int errcode; \
43 __asm__ __volatile__( \
44 "1: sth %1, (%2,0) \n" \
45 " br 3f \n" \
46 "2: mov %0, %3 \n" \
47 " br 3f \n" \
48 ".section __ex_table, \"a\" \n" \
49 ".align 2 \n" \
50 ".long 1b,2b \n" \
51 ".previous \n" \
52 "3: \n" \
53 : "=r"(err), "=r"(x), "=r"(ptr), "=r"(errcode) \
54 : "0"(err), "1"(x), "2"(ptr), "3"(-EFAULT) \
55 : "memory"); \
56 } while (0)
57
58 #define __put_user_asm_w(x, ptr, err) \
59 do { \
60 int errcode; \
61 __asm__ __volatile__( \
62 "1: stw %1, (%2,0) \n" \
63 " br 3f \n" \
64 "2: mov %0, %3 \n" \
65 " br 3f \n" \
66 ".section __ex_table,\"a\" \n" \
67 ".align 2 \n" \
68 ".long 1b, 2b \n" \
69 ".previous \n" \
70 "3: \n" \
71 : "=r"(err), "=r"(x), "=r"(ptr), "=r"(errcode) \
72 : "0"(err), "1"(x), "2"(ptr), "3"(-EFAULT) \
73 : "memory"); \
74 } while (0)
75
76 #define __put_user_asm_64(x, ptr, err) \
77 do { \
78 int tmp; \
79 int errcode; \
80 \
81 __asm__ __volatile__( \
82 " ldw %3, (%1, 0) \n" \
83 "1: stw %3, (%2, 0) \n" \
84 " ldw %3, (%1, 4) \n" \
85 "2: stw %3, (%2, 4) \n" \
86 " br 4f \n" \
87 "3: mov %0, %4 \n" \
88 " br 4f \n" \
89 ".section __ex_table, \"a\" \n" \
90 ".align 2 \n" \
91 ".long 1b, 3b \n" \
92 ".long 2b, 3b \n" \
93 ".previous \n" \
94 "4: \n" \
95 : "=r"(err), "=r"(x), "=r"(ptr), \
96 "=r"(tmp), "=r"(errcode) \
97 : "0"(err), "1"(x), "2"(ptr), "3"(0), \
98 "4"(-EFAULT) \
99 : "memory"); \
100 } while (0)
101
__put_user_fn(size_t size,void __user * ptr,void * x)102 static inline int __put_user_fn(size_t size, void __user *ptr, void *x)
103 {
104 int retval = 0;
105 u32 tmp;
106
107 switch (size) {
108 case 1:
109 tmp = *(u8 *)x;
110 __put_user_asm_b(tmp, ptr, retval);
111 break;
112 case 2:
113 tmp = *(u16 *)x;
114 __put_user_asm_h(tmp, ptr, retval);
115 break;
116 case 4:
117 tmp = *(u32 *)x;
118 __put_user_asm_w(tmp, ptr, retval);
119 break;
120 case 8:
121 __put_user_asm_64(x, (u64 *)ptr, retval);
122 break;
123 }
124
125 return retval;
126 }
127 #define __put_user_fn __put_user_fn
128
129 /*
130 * __get_user_fn
131 */
132 extern int __get_user_bad(void);
133
134 #define __get_user_asm_common(x, ptr, ins, err) \
135 do { \
136 int errcode; \
137 __asm__ __volatile__( \
138 "1: " ins " %1, (%4, 0) \n" \
139 " br 3f \n" \
140 "2: mov %0, %2 \n" \
141 " movi %1, 0 \n" \
142 " br 3f \n" \
143 ".section __ex_table,\"a\" \n" \
144 ".align 2 \n" \
145 ".long 1b, 2b \n" \
146 ".previous \n" \
147 "3: \n" \
148 : "=r"(err), "=r"(x), "=r"(errcode) \
149 : "0"(0), "r"(ptr), "2"(-EFAULT) \
150 : "memory"); \
151 } while (0)
152
153 #define __get_user_asm_64(x, ptr, err) \
154 do { \
155 int tmp; \
156 int errcode; \
157 \
158 __asm__ __volatile__( \
159 "1: ldw %3, (%2, 0) \n" \
160 " stw %3, (%1, 0) \n" \
161 "2: ldw %3, (%2, 4) \n" \
162 " stw %3, (%1, 4) \n" \
163 " br 4f \n" \
164 "3: mov %0, %4 \n" \
165 " br 4f \n" \
166 ".section __ex_table, \"a\" \n" \
167 ".align 2 \n" \
168 ".long 1b, 3b \n" \
169 ".long 2b, 3b \n" \
170 ".previous \n" \
171 "4: \n" \
172 : "=r"(err), "=r"(x), "=r"(ptr), \
173 "=r"(tmp), "=r"(errcode) \
174 : "0"(err), "1"(x), "2"(ptr), "3"(0), \
175 "4"(-EFAULT) \
176 : "memory"); \
177 } while (0)
178
__get_user_fn(size_t size,const void __user * ptr,void * x)179 static inline int __get_user_fn(size_t size, const void __user *ptr, void *x)
180 {
181 int retval;
182 u32 tmp;
183
184 switch (size) {
185 case 1:
186 __get_user_asm_common(tmp, ptr, "ldb", retval);
187 *(u8 *)x = (u8)tmp;
188 break;
189 case 2:
190 __get_user_asm_common(tmp, ptr, "ldh", retval);
191 *(u16 *)x = (u16)tmp;
192 break;
193 case 4:
194 __get_user_asm_common(tmp, ptr, "ldw", retval);
195 *(u32 *)x = (u32)tmp;
196 break;
197 case 8:
198 __get_user_asm_64(x, ptr, retval);
199 break;
200 }
201
202 return retval;
203 }
204 #define __get_user_fn __get_user_fn
205
206 unsigned long raw_copy_from_user(void *to, const void *from, unsigned long n);
207 unsigned long raw_copy_to_user(void *to, const void *from, unsigned long n);
208
209 unsigned long __clear_user(void __user *to, unsigned long n);
210 #define __clear_user __clear_user
211
212 #include <asm/segment.h>
213 #include <asm-generic/uaccess.h>
214
215 #endif /* __ASM_CSKY_UACCESS_H */
216