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