1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 #include <linux/sys.h>
44 #include <linux/linkage.h>
45 #include <asm/segment.h>
46
47 EBX = 0x00
48 ECX = 0x04
49 EDX = 0x08
50 ESI = 0x0C
51 EDI = 0x10
52 EBP = 0x14
53 EAX = 0x18
54 DS = 0x1C
55 ES = 0x20
56 FS = 0x24
57 GS = 0x28
58 ORIG_EAX = 0x2C
59 EIP = 0x30
60 CS = 0x34
61 EFLAGS = 0x38
62 OLDESP = 0x3C
63 OLDSS = 0x40
64
65 CF_MASK = 0x00000001
66 IF_MASK = 0x00000200
67 NT_MASK = 0x00004000
68 VM_MASK = 0x00020000
69
70
71
72
73 state = 0
74 counter = 4
75 priority = 8
76 signal = 12
77 blocked = 16
78 flags = 20
79 errno = 24
80 dbgreg6 = 52
81 dbgreg7 = 56
82 exec_domain = 60
83
84 ENOSYS = 38
85
86 #define SAVE_ALL \
87 cld; \
88 push %gs; \
89 push %fs; \
90 push %es; \
91 push %ds; \
92 pushl %eax; \
93 pushl %ebp; \
94 pushl %edi; \
95 pushl %esi; \
96 pushl %edx; \
97 pushl %ecx; \
98 pushl %ebx; \
99 movl $(KERNEL_DS),%edx; \
100 mov %dx,%ds; \
101 mov %dx,%es; \
102 movl $(USER_DS),%edx; \
103 mov %dx,%fs;
104
105 #define RESTORE_ALL \
106 cmpw $(KERNEL_CS),CS(%esp); \
107 je 1f; \
108 movl SYMBOL_NAME(current),%eax; \
109 movl dbgreg7(%eax),%ebx; \
110 movl %ebx,%db7; \
111 1: popl %ebx; \
112 popl %ecx; \
113 popl %edx; \
114 popl %esi; \
115 popl %edi; \
116 popl %ebp; \
117 popl %eax; \
118 pop %ds; \
119 pop %es; \
120 pop %fs; \
121 pop %gs; \
122 addl $4,%esp; \
123 iret
124
125 ENTRY(lcall7)
126 pushfl # We get a different stack layout with call gates,
127 pushl %eax # which has to be cleaned up later..
128 SAVE_ALL
129 movl EIP(%esp),%eax # due to call gates, this is eflags, not eip..
130 movl CS(%esp),%edx # this is eip..
131 movl EFLAGS(%esp),%ecx # and this is cs..
132 movl %eax,EFLAGS(%esp) #
133 movl %edx,EIP(%esp) # Now we move them to their "normal" places
134 movl %ecx,CS(%esp) #
135 movl %esp,%eax
136 movl SYMBOL_NAME(current),%edx
137 pushl %eax
138 movl exec_domain(%edx),%edx # Get the execution domain
139 movl 4(%edx),%edx # Get the lcall7 handler for the domain
140 call *%edx
141 popl %eax
142 jmp ret_from_sys_call
143
144 ALIGN
145 handle_bottom_half:
146 pushfl
147 incl SYMBOL_NAME(intr_count)
148 sti
149 call SYMBOL_NAME(do_bottom_half)
150 popfl
151 decl SYMBOL_NAME(intr_count)
152 jmp 9f
153 ALIGN
154 reschedule:
155 pushl $ret_from_sys_call
156 jmp SYMBOL_NAME(schedule)
157
158 ENTRY(system_call)
159 pushl %eax # save orig_eax
160 SAVE_ALL
161 movl $-ENOSYS,EAX(%esp)
162 cmpl $(NR_syscalls),%eax
163 jae ret_from_sys_call
164 movl SYMBOL_NAME(sys_call_table)(,%eax,4),%eax
165 testl %eax,%eax
166 je ret_from_sys_call
167 movl SYMBOL_NAME(current),%ebx
168 andl $~CF_MASK,EFLAGS(%esp) # clear carry - assume no errors
169 movl $0,errno(%ebx)
170 movl %db6,%edx
171 movl %edx,dbgreg6(%ebx) # save current hardware debugging status
172 testb $0x20,flags(%ebx) # PF_TRACESYS
173 jne 1f
174 call *%eax
175 movl %eax,EAX(%esp) # save the return value
176 movl errno(%ebx),%edx
177 negl %edx
178 je ret_from_sys_call
179 movl %edx,EAX(%esp)
180 orl $(CF_MASK),EFLAGS(%esp) # set carry to indicate error
181 jmp ret_from_sys_call
182 ALIGN
183 1: call SYMBOL_NAME(syscall_trace)
184 movl ORIG_EAX(%esp),%eax
185 call SYMBOL_NAME(sys_call_table)(,%eax,4)
186 movl %eax,EAX(%esp) # save the return value
187 movl SYMBOL_NAME(current),%eax
188 movl errno(%eax),%edx
189 negl %edx
190 je 1f
191 movl %edx,EAX(%esp)
192 orl $(CF_MASK),EFLAGS(%esp) # set carry to indicate error
193 1: call SYMBOL_NAME(syscall_trace)
194
195 ALIGN
196 .globl ret_from_sys_call
197 ret_from_sys_call:
198 cmpl $0,SYMBOL_NAME(intr_count)
199 jne 2f
200 9: movl SYMBOL_NAME(bh_mask),%eax
201 andl SYMBOL_NAME(bh_active),%eax
202 jne handle_bottom_half
203 movl EFLAGS(%esp),%eax # check VM86 flag: CS/SS are
204 testl $(VM_MASK),%eax # different then
205 jne 1f
206 cmpw $(KERNEL_CS),CS(%esp) # was old code segment supervisor ?
207 je 2f
208 1: sti
209 orl $(IF_MASK),%eax # these just try to make sure
210 andl $~NT_MASK,%eax # the program doesn't do anything
211 movl %eax,EFLAGS(%esp) # stupid
212 cmpl $0,SYMBOL_NAME(need_resched)
213 jne reschedule
214 movl SYMBOL_NAME(current),%eax
215 cmpl SYMBOL_NAME(task),%eax # task[0] cannot have signals
216 je 2f
217 cmpl $0,state(%eax) # state
218 jne reschedule
219 cmpl $0,counter(%eax) # counter
220 je reschedule
221 movl blocked(%eax),%ecx
222 movl %ecx,%ebx # save blocked in %ebx for signal handling
223 notl %ecx
224 andl signal(%eax),%ecx
225 jne signal_return
226 2: RESTORE_ALL
227 ALIGN
228 signal_return:
229 movl %esp,%ecx
230 pushl %ecx
231 testl $(VM_MASK),EFLAGS(%ecx)
232 jne v86_signal_return
233 pushl %ebx
234 call SYMBOL_NAME(do_signal)
235 popl %ebx
236 popl %ebx
237 RESTORE_ALL
238 ALIGN
239 v86_signal_return:
240 call SYMBOL_NAME(save_v86_state)
241 movl %eax,%esp
242 pushl %eax
243 pushl %ebx
244 call SYMBOL_NAME(do_signal)
245 popl %ebx
246 popl %ebx
247 RESTORE_ALL
248
249 ENTRY(divide_error)
250 pushl $0 # no error code
251 pushl $ SYMBOL_NAME(do_divide_error)
252 ALIGN
253 error_code:
254 push %fs
255 push %es
256 push %ds
257 pushl %eax
258 pushl %ebp
259 pushl %edi
260 pushl %esi
261 pushl %edx
262 pushl %ecx
263 pushl %ebx
264 movl $0,%eax
265 movl %eax,%db7 # disable hardware debugging...
266 cld
267 movl $-1, %eax
268 xchgl %eax, ORIG_EAX(%esp) # orig_eax (get the error code. )
269 xorl %ebx,%ebx # zero ebx
270 mov %gs,%bx # get the lower order bits of gs
271 xchgl %ebx, GS(%esp) # get the address and save gs.
272 pushl %eax # push the error code
273 lea 4(%esp),%edx
274 pushl %edx
275 movl $(KERNEL_DS),%edx
276 mov %dx,%ds
277 mov %dx,%es
278 movl $(USER_DS),%edx
279 mov %dx,%fs
280 pushl %eax
281 movl SYMBOL_NAME(current),%eax
282 movl %db6,%edx
283 movl %edx,dbgreg6(%eax) # save current hardware debugging status
284 popl %eax
285 call *%ebx
286 addl $8,%esp
287 jmp ret_from_sys_call
288
289 ENTRY(coprocessor_error)
290 pushl $0
291 pushl $ SYMBOL_NAME(do_coprocessor_error)
292 jmp error_code
293
294 ENTRY(device_not_available)
295 pushl $-1 # mark this as an int
296 SAVE_ALL
297 pushl $ret_from_sys_call
298 movl %cr0,%eax
299 testl $0x4,%eax # EM (math emulation bit)
300 je SYMBOL_NAME(math_state_restore)
301 pushl $0 # temporary storage for ORIG_EIP
302 call SYMBOL_NAME(math_emulate)
303 addl $4,%esp
304 ret
305
306 ENTRY(debug)
307 pushl $0
308 pushl $ SYMBOL_NAME(do_debug)
309 jmp error_code
310
311 ENTRY(nmi)
312 pushl $0
313 pushl $ SYMBOL_NAME(do_nmi)
314 jmp error_code
315
316 ENTRY(int3)
317 pushl $0
318 pushl $ SYMBOL_NAME(do_int3)
319 jmp error_code
320
321 ENTRY(overflow)
322 pushl $0
323 pushl $ SYMBOL_NAME(do_overflow)
324 jmp error_code
325
326 ENTRY(bounds)
327 pushl $0
328 pushl $ SYMBOL_NAME(do_bounds)
329 jmp error_code
330
331 ENTRY(invalid_op)
332 pushl $0
333 pushl $ SYMBOL_NAME(do_invalid_op)
334 jmp error_code
335
336 ENTRY(coprocessor_segment_overrun)
337 pushl $0
338 pushl $ SYMBOL_NAME(do_coprocessor_segment_overrun)
339 jmp error_code
340
341 ENTRY(reserved)
342 pushl $0
343 pushl $ SYMBOL_NAME(do_reserved)
344 jmp error_code
345
346 ENTRY(double_fault)
347 pushl $ SYMBOL_NAME(do_double_fault)
348 jmp error_code
349
350 ENTRY(invalid_TSS)
351 pushl $ SYMBOL_NAME(do_invalid_TSS)
352 jmp error_code
353
354 ENTRY(segment_not_present)
355 pushl $ SYMBOL_NAME(do_segment_not_present)
356 jmp error_code
357
358 ENTRY(stack_segment)
359 pushl $ SYMBOL_NAME(do_stack_segment)
360 jmp error_code
361
362 ENTRY(general_protection)
363 pushl $ SYMBOL_NAME(do_general_protection)
364 jmp error_code
365
366 ENTRY(alignment_check)
367 pushl $ SYMBOL_NAME(do_alignment_check)
368 jmp error_code
369
370 ENTRY(page_fault)
371 pushl $ SYMBOL_NAME(do_page_fault)
372 jmp error_code
373
374 .data
375 ENTRY(sys_call_table)
376 .long SYMBOL_NAME(sys_setup)
377 .long SYMBOL_NAME(sys_exit)
378 .long SYMBOL_NAME(sys_fork)
379 .long SYMBOL_NAME(sys_read)
380 .long SYMBOL_NAME(sys_write)
381 .long SYMBOL_NAME(sys_open)
382 .long SYMBOL_NAME(sys_close)
383 .long SYMBOL_NAME(sys_waitpid)
384 .long SYMBOL_NAME(sys_creat)
385 .long SYMBOL_NAME(sys_link)
386 .long SYMBOL_NAME(sys_unlink)
387 .long SYMBOL_NAME(sys_execve)
388 .long SYMBOL_NAME(sys_chdir)
389 .long SYMBOL_NAME(sys_time)
390 .long SYMBOL_NAME(sys_mknod)
391 .long SYMBOL_NAME(sys_chmod)
392 .long SYMBOL_NAME(sys_chown)
393 .long SYMBOL_NAME(sys_break)
394 .long SYMBOL_NAME(sys_stat)
395 .long SYMBOL_NAME(sys_lseek)
396 .long SYMBOL_NAME(sys_getpid)
397 .long SYMBOL_NAME(sys_mount)
398 .long SYMBOL_NAME(sys_umount)
399 .long SYMBOL_NAME(sys_setuid)
400 .long SYMBOL_NAME(sys_getuid)
401 .long SYMBOL_NAME(sys_stime)
402 .long SYMBOL_NAME(sys_ptrace)
403 .long SYMBOL_NAME(sys_alarm)
404 .long SYMBOL_NAME(sys_fstat)
405 .long SYMBOL_NAME(sys_pause)
406 .long SYMBOL_NAME(sys_utime)
407 .long SYMBOL_NAME(sys_stty)
408 .long SYMBOL_NAME(sys_gtty)
409 .long SYMBOL_NAME(sys_access)
410 .long SYMBOL_NAME(sys_nice)
411 .long SYMBOL_NAME(sys_ftime)
412 .long SYMBOL_NAME(sys_sync)
413 .long SYMBOL_NAME(sys_kill)
414 .long SYMBOL_NAME(sys_rename)
415 .long SYMBOL_NAME(sys_mkdir)
416 .long SYMBOL_NAME(sys_rmdir)
417 .long SYMBOL_NAME(sys_dup)
418 .long SYMBOL_NAME(sys_pipe)
419 .long SYMBOL_NAME(sys_times)
420 .long SYMBOL_NAME(sys_prof)
421 .long SYMBOL_NAME(sys_brk)
422 .long SYMBOL_NAME(sys_setgid)
423 .long SYMBOL_NAME(sys_getgid)
424 .long SYMBOL_NAME(sys_signal)
425 .long SYMBOL_NAME(sys_geteuid)
426 .long SYMBOL_NAME(sys_getegid)
427 .long SYMBOL_NAME(sys_acct)
428 .long SYMBOL_NAME(sys_phys)
429 .long SYMBOL_NAME(sys_lock)
430 .long SYMBOL_NAME(sys_ioctl)
431 .long SYMBOL_NAME(sys_fcntl)
432 .long SYMBOL_NAME(sys_mpx)
433 .long SYMBOL_NAME(sys_setpgid)
434 .long SYMBOL_NAME(sys_ulimit)
435 .long SYMBOL_NAME(sys_olduname)
436 .long SYMBOL_NAME(sys_umask)
437 .long SYMBOL_NAME(sys_chroot)
438 .long SYMBOL_NAME(sys_ustat)
439 .long SYMBOL_NAME(sys_dup2)
440 .long SYMBOL_NAME(sys_getppid)
441 .long SYMBOL_NAME(sys_getpgrp)
442 .long SYMBOL_NAME(sys_setsid)
443 .long SYMBOL_NAME(sys_sigaction)
444 .long SYMBOL_NAME(sys_sgetmask)
445 .long SYMBOL_NAME(sys_ssetmask)
446 .long SYMBOL_NAME(sys_setreuid)
447 .long SYMBOL_NAME(sys_setregid)
448 .long SYMBOL_NAME(sys_sigsuspend)
449 .long SYMBOL_NAME(sys_sigpending)
450 .long SYMBOL_NAME(sys_sethostname)
451 .long SYMBOL_NAME(sys_setrlimit)
452 .long SYMBOL_NAME(sys_getrlimit)
453 .long SYMBOL_NAME(sys_getrusage)
454 .long SYMBOL_NAME(sys_gettimeofday)
455 .long SYMBOL_NAME(sys_settimeofday)
456 .long SYMBOL_NAME(sys_getgroups)
457 .long SYMBOL_NAME(sys_setgroups)
458 .long SYMBOL_NAME(old_select)
459 .long SYMBOL_NAME(sys_symlink)
460 .long SYMBOL_NAME(sys_lstat)
461 .long SYMBOL_NAME(sys_readlink)
462 .long SYMBOL_NAME(sys_uselib)
463 .long SYMBOL_NAME(sys_swapon)
464 .long SYMBOL_NAME(sys_reboot)
465 .long SYMBOL_NAME(old_readdir)
466 .long SYMBOL_NAME(old_mmap)
467 .long SYMBOL_NAME(sys_munmap)
468 .long SYMBOL_NAME(sys_truncate)
469 .long SYMBOL_NAME(sys_ftruncate)
470 .long SYMBOL_NAME(sys_fchmod)
471 .long SYMBOL_NAME(sys_fchown)
472 .long SYMBOL_NAME(sys_getpriority)
473 .long SYMBOL_NAME(sys_setpriority)
474 .long SYMBOL_NAME(sys_profil)
475 .long SYMBOL_NAME(sys_statfs)
476 .long SYMBOL_NAME(sys_fstatfs)
477 .long SYMBOL_NAME(sys_ioperm)
478 .long SYMBOL_NAME(sys_socketcall)
479 .long SYMBOL_NAME(sys_syslog)
480 .long SYMBOL_NAME(sys_setitimer)
481 .long SYMBOL_NAME(sys_getitimer)
482 .long SYMBOL_NAME(sys_newstat)
483 .long SYMBOL_NAME(sys_newlstat)
484 .long SYMBOL_NAME(sys_newfstat)
485 .long SYMBOL_NAME(sys_uname)
486 .long SYMBOL_NAME(sys_iopl)
487 .long SYMBOL_NAME(sys_vhangup)
488 .long SYMBOL_NAME(sys_idle)
489 .long SYMBOL_NAME(sys_vm86)
490 .long SYMBOL_NAME(sys_wait4)
491 .long SYMBOL_NAME(sys_swapoff)
492 .long SYMBOL_NAME(sys_sysinfo)
493 .long SYMBOL_NAME(sys_ipc)
494 .long SYMBOL_NAME(sys_fsync)
495 .long SYMBOL_NAME(sys_sigreturn)
496 .long SYMBOL_NAME(sys_clone)
497 .long SYMBOL_NAME(sys_setdomainname)
498 .long SYMBOL_NAME(sys_newuname)
499 .long SYMBOL_NAME(sys_modify_ldt)
500 .long SYMBOL_NAME(sys_adjtimex)
501 .long SYMBOL_NAME(sys_mprotect)
502 .long SYMBOL_NAME(sys_sigprocmask)
503 .long SYMBOL_NAME(sys_create_module)
504 .long SYMBOL_NAME(sys_init_module)
505 .long SYMBOL_NAME(sys_delete_module)
506 .long SYMBOL_NAME(sys_get_kernel_syms)
507 .long SYMBOL_NAME(sys_quotactl)
508 .long SYMBOL_NAME(sys_getpgid)
509 .long SYMBOL_NAME(sys_fchdir)
510 .long SYMBOL_NAME(sys_bdflush)
511 .long SYMBOL_NAME(sys_sysfs)
512 .long SYMBOL_NAME(sys_personality)
513 .long 0
514 .long SYMBOL_NAME(sys_setfsuid)
515 .long SYMBOL_NAME(sys_setfsgid)
516 .long SYMBOL_NAME(sys_llseek)
517 .long SYMBOL_NAME(sys_getdents)
518 .long SYMBOL_NAME(sys_select)
519 .long SYMBOL_NAME(sys_flock)
520 .space (NR_syscalls-143)*4