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