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 :"iq" ((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 :"=q" (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_byte(*(const char *) from, (char *) to);
155 return;
156 case 2:
157 put_user_word(*(const short *) from, (short *) to);
158 return;
159 case 3:
160 put_user_word(*(const short *) from, (short *) to);
161 put_user_byte(*(2+(const char *) from), 2+(char *) to);
162 return;
163 case 4:
164 put_user_long(*(const int *) from, (int *) to);
165 return;
166 }
167 #define COMMON(x) \
168 __asm__("cld\n\t" \
169 "push %%es\n\t" \
170 "push %%fs\n\t" \
171 "pop %%es\n\t" \
172 "rep ; movsl\n\t" \
173 x \
174 "pop %%es" \
175 : \
176 :"c" (n/4),"D" ((long) to),"S" ((long) from) \
177 :"cx","di","si")
178
179 switch (n % 4) {
180 case 0:
181 COMMON("");
182 return;
183 case 1:
184 COMMON("movsb\n\t");
185 return;
186 case 2:
187 COMMON("movsw\n\t");
188 return;
189 case 3:
190 COMMON("movsw\n\tmovsb\n\t");
191 return;
192 }
193 #undef COMMON
194 }
195
196 static inline void __generic_memcpy_fromfs(void * to, const void * from, unsigned long n)
197 {
198 __asm__("cld\n\t"
199 "testb $1,%%cl\n\t"
200 "je 1f\n\t"
201 "fs ; movsb\n"
202 "1:\ttestb $2,%%cl\n\t"
203 "je 2f\n\t"
204 "fs ; movsw\n"
205 "2:\tshrl $2,%%ecx\n\t"
206 "rep ; fs ; movsl"
207 :
208 :"c" (n),"D" ((long) to),"S" ((long) from)
209 :"cx","di","si","memory");
210 }
211
212 static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n)
213 {
214 switch (n) {
215 case 0:
216 return;
217 case 1:
218 *(char *)to = get_user_byte((const char *) from);
219 return;
220 case 2:
221 *(short *)to = get_user_word((const short *) from);
222 return;
223 case 3:
224 *(short *) to = get_user_word((const short *) from);
225 *((char *) to + 2) = get_user_byte(2+(const char *) from);
226 return;
227 case 4:
228 *(int *) to = get_user_long((const int *) from);
229 return;
230 }
231 #define COMMON(x) \
232 __asm__("cld\n\t" \
233 "rep ; fs ; movsl\n\t" \
234 x \
235 : \
236 :"c" (n/4),"D" ((long) to),"S" ((long) from) \
237 :"cx","di","si","memory")
238
239 switch (n % 4) {
240 case 0:
241 COMMON("");
242 return;
243 case 1:
244 COMMON("fs ; movsb");
245 return;
246 case 2:
247 COMMON("fs ; movsw");
248 return;
249 case 3:
250 COMMON("fs ; movsw\n\tfs ; movsb");
251 return;
252 }
253 #undef COMMON
254 }
255
256 #define memcpy_fromfs(to, from, n) \
257 (__builtin_constant_p(n) ? \
258 __constant_memcpy_fromfs((to),(from),(n)) : \
259 __generic_memcpy_fromfs((to),(from),(n)))
260
261 #define memcpy_tofs(to, from, n) \
262 (__builtin_constant_p(n) ? \
263 __constant_memcpy_tofs((to),(from),(n)) : \
264 __generic_memcpy_tofs((to),(from),(n)))
265
266
267
268
269
270
271
272
273 static inline unsigned long get_fs(void)
274 {
275 unsigned long _v;
276 __asm__("mov %%fs,%w0":"=r" (_v):"0" (0));
277 return _v;
278 }
279
280 static inline unsigned long get_ds(void)
281 {
282 unsigned long _v;
283 __asm__("mov %%ds,%w0":"=r" (_v):"0" (0));
284 return _v;
285 }
286
287 static inline void set_fs(unsigned long val)
288 {
289 __asm__ __volatile__("mov %w0,%%fs": :"r" (val));
290 }
291
292 #endif
293
294 #endif