This source file includes following definitions.
- __put_user
- __get_user
- get_user_byte
- get_user_word
- get_user_long
- put_user_byte
- put_user_word
- put_user_long
- __generic_memcpy_tofs
- __constant_memcpy_tofs
- __generic_memcpy_fromfs
- __constant_memcpy_fromfs
- get_fs
- get_ds
- set_fs
1 #ifndef _ASM_SEGMENT_H
2 #define _ASM_SEGMENT_H
3
4 #define KERNEL_CS 0x10
5 #define KERNEL_DS 0x18
6
7 #define USER_CS 0x23
8 #define USER_DS 0x2B
9
10 #ifndef __ASSEMBLY__
11
12
13
14
15
16
17 #define put_user(x,ptr) __put_user((unsigned long)(x),(ptr),sizeof(*(ptr)))
18 #define get_user(ptr) __get_user((ptr),sizeof(*(ptr)))
19
20
21
22
23
24
25 extern int bad_user_access_length(void);
26
27
28
29
30
31 struct __segment_dummy { unsigned long a[100]; };
32 #define __sd(x) ((struct __segment_dummy *) (x))
33
34 static inline void __put_user(unsigned long x, void * y, int size)
35 {
36 switch (size) {
37 case 1:
38 __asm__ ("movb %b1,%%fs:%0"
39 :"=m" (*__sd(y))
40 :"iq" ((unsigned char) x), "m" (*__sd(y)));
41 break;
42 case 2:
43 __asm__ ("movw %w1,%%fs:%0"
44 :"=m" (*__sd(y))
45 :"ir" ((unsigned short) x), "m" (*__sd(y)));
46 break;
47 case 4:
48 __asm__ ("movl %1,%%fs:%0"
49 :"=m" (*__sd(y))
50 :"ir" (x), "m" (*__sd(y)));
51 break;
52 default:
53 bad_user_access_length();
54 }
55 }
56
57 static inline unsigned long __get_user(const void * y, int size)
58 {
59 unsigned long result;
60
61 switch (size) {
62 case 1:
63 __asm__ ("movb %%fs:%1,%b0"
64 :"=q" (result)
65 :"m" (*__sd(y)));
66 return (unsigned char) result;
67 case 2:
68 __asm__ ("movw %%fs:%1,%w0"
69 :"=r" (result)
70 :"m" (*__sd(y)));
71 return (unsigned short) result;
72 case 4:
73 __asm__ ("movl %%fs:%1,%0"
74 :"=r" (result)
75 :"m" (*__sd(y)));
76 return result;
77 default:
78 return bad_user_access_length();
79 }
80 }
81
82
83
84
85
86 static inline unsigned char get_user_byte(const char * addr)
87 {
88 return __get_user(addr,1);
89 }
90
91 #define get_fs_byte(addr) get_user_byte((char *)(addr))
92
93 static inline unsigned short get_user_word(const short *addr)
94 {
95 return __get_user(addr, 2);
96 }
97
98 #define get_fs_word(addr) get_user_word((short *)(addr))
99
100 static inline unsigned long get_user_long(const int *addr)
101 {
102 return __get_user(addr, 4);
103 }
104
105 #define get_fs_long(addr) get_user_long((int *)(addr))
106
107 static inline void put_user_byte(char val,char *addr)
108 {
109 __put_user(val, addr, 1);
110 }
111
112 #define put_fs_byte(x,addr) put_user_byte((x),(char *)(addr))
113
114 static inline void put_user_word(short val,short * addr)
115 {
116 __put_user(val, addr, 2);
117 }
118
119 #define put_fs_word(x,addr) put_user_word((x),(short *)(addr))
120
121 static inline void put_user_long(unsigned long val,int * addr)
122 {
123 __put_user(val, addr, 4);
124 }
125
126 #define put_fs_long(x,addr) put_user_long((x),(int *)(addr))
127
128 static inline void __generic_memcpy_tofs(void * to, const void * from, unsigned long n)
129 {
130 __asm__("cld\n\t"
131 "push %%es\n\t"
132 "push %%fs\n\t"
133 "pop %%es\n\t"
134 "testb $1,%%cl\n\t"
135 "je 1f\n\t"
136 "movsb\n"
137 "1:\ttestb $2,%%cl\n\t"
138 "je 2f\n\t"
139 "movsw\n"
140 "2:\tshrl $2,%%ecx\n\t"
141 "rep ; movsl\n\t"
142 "pop %%es"
143 :
144 :"c" (n),"D" ((long) to),"S" ((long) from)
145 :"cx","di","si");
146 }
147
148 static inline void __constant_memcpy_tofs(void * to, const void * from, unsigned long n)
149 {
150 switch (n) {
151 case 0:
152 return;
153 case 1:
154 __put_user(*(const char *) from, (char *) to, 1);
155 return;
156 case 2:
157 __put_user(*(const short *) from, (short *) to, 2);
158 return;
159 case 3:
160 __put_user(*(const short *) from, (short *) to, 2);
161 __put_user(*(2+(const char *) from), 2+(char *) to, 1);
162 return;
163 case 4:
164 __put_user(*(const int *) from, (int *) to, 4);
165 return;
166 case 8:
167 __put_user(*(const int *) from, (int *) to, 4);
168 __put_user(*(1+(const int *) from), 1+(int *) to, 4);
169 return;
170 case 12:
171 __put_user(*(const int *) from, (int *) to, 4);
172 __put_user(*(1+(const int *) from), 1+(int *) to, 4);
173 __put_user(*(2+(const int *) from), 2+(int *) to, 4);
174 return;
175 case 16:
176 __put_user(*(const int *) from, (int *) to, 4);
177 __put_user(*(1+(const int *) from), 1+(int *) to, 4);
178 __put_user(*(2+(const int *) from), 2+(int *) to, 4);
179 __put_user(*(3+(const int *) from), 3+(int *) to, 4);
180 return;
181 }
182 #define COMMON(x) \
183 __asm__("cld\n\t" \
184 "push %%es\n\t" \
185 "push %%fs\n\t" \
186 "pop %%es\n\t" \
187 "rep ; movsl\n\t" \
188 x \
189 "pop %%es" \
190 : \
191 :"c" (n/4),"D" ((long) to),"S" ((long) from) \
192 :"cx","di","si")
193
194 switch (n % 4) {
195 case 0:
196 COMMON("");
197 return;
198 case 1:
199 COMMON("movsb\n\t");
200 return;
201 case 2:
202 COMMON("movsw\n\t");
203 return;
204 case 3:
205 COMMON("movsw\n\tmovsb\n\t");
206 return;
207 }
208 #undef COMMON
209 }
210
211 static inline void __generic_memcpy_fromfs(void * to, const void * from, unsigned long n)
212 {
213 __asm__("cld\n\t"
214 "testb $1,%%cl\n\t"
215 "je 1f\n\t"
216 "fs ; movsb\n"
217 "1:\ttestb $2,%%cl\n\t"
218 "je 2f\n\t"
219 "fs ; movsw\n"
220 "2:\tshrl $2,%%ecx\n\t"
221 "rep ; fs ; movsl"
222 :
223 :"c" (n),"D" ((long) to),"S" ((long) from)
224 :"cx","di","si","memory");
225 }
226
227 static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n)
228 {
229 switch (n) {
230 case 0:
231 return;
232 case 1:
233 *(char *)to = __get_user((const char *) from, 1);
234 return;
235 case 2:
236 *(short *)to = __get_user((const short *) from, 2);
237 return;
238 case 3:
239 *(short *) to = __get_user((const short *) from, 2);
240 *((char *) to + 2) = __get_user(2+(const char *) from, 1);
241 return;
242 case 4:
243 *(int *) to = __get_user((const int *) from, 4);
244 return;
245 case 8:
246 *(int *) to = __get_user((const int *) from, 4);
247 *(1+(int *) to) = __get_user(1+(const int *) from, 4);
248 return;
249 case 12:
250 *(int *) to = __get_user((const int *) from, 4);
251 *(1+(int *) to) = __get_user(1+(const int *) from, 4);
252 *(2+(int *) to) = __get_user(2+(const int *) from, 4);
253 return;
254 case 16:
255 *(int *) to = __get_user((const int *) from, 4);
256 *(1+(int *) to) = __get_user(1+(const int *) from, 4);
257 *(2+(int *) to) = __get_user(2+(const int *) from, 4);
258 *(3+(int *) to) = __get_user(3+(const int *) from, 4);
259 return;
260 }
261 #define COMMON(x) \
262 __asm__("cld\n\t" \
263 "rep ; fs ; movsl\n\t" \
264 x \
265 : \
266 :"c" (n/4),"D" ((long) to),"S" ((long) from) \
267 :"cx","di","si","memory")
268
269 switch (n % 4) {
270 case 0:
271 COMMON("");
272 return;
273 case 1:
274 COMMON("fs ; movsb");
275 return;
276 case 2:
277 COMMON("fs ; movsw");
278 return;
279 case 3:
280 COMMON("fs ; movsw\n\tfs ; movsb");
281 return;
282 }
283 #undef COMMON
284 }
285
286 #define memcpy_fromfs(to, from, n) \
287 (__builtin_constant_p(n) ? \
288 __constant_memcpy_fromfs((to),(from),(n)) : \
289 __generic_memcpy_fromfs((to),(from),(n)))
290
291 #define memcpy_tofs(to, from, n) \
292 (__builtin_constant_p(n) ? \
293 __constant_memcpy_tofs((to),(from),(n)) : \
294 __generic_memcpy_tofs((to),(from),(n)))
295
296
297
298
299
300
301
302
303 static inline unsigned long get_fs(void)
304 {
305 unsigned long _v;
306 __asm__("mov %%fs,%w0":"=r" (_v):"0" (0));
307 return _v;
308 }
309
310 static inline unsigned long get_ds(void)
311 {
312 unsigned long _v;
313 __asm__("mov %%ds,%w0":"=r" (_v):"0" (0));
314 return _v;
315 }
316
317 static inline void set_fs(unsigned long val)
318 {
319 __asm__ __volatile__("mov %w0,%%fs": :"r" (val));
320 }
321
322 #endif
323
324 #endif