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