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 #define __ASSEMBLY__
44 #include <linux/sys.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 .globl _system_call,_lcall7
87 .globl _device_not_available, _coprocessor_error
88 .globl _divide_error,_debug,_nmi,_int3,_overflow,_bounds,_invalid_op
89 .globl _double_fault,_coprocessor_segment_overrun
90 .globl _invalid_TSS,_segment_not_present,_stack_segment
91 .globl _general_protection,_reserved
92 .globl _alignment_check,_page_fault
93 .globl ret_from_sys_call, _sys_call_table
94
95 #define SAVE_ALL \
96 cld; \
97 push %gs; \
98 push %fs; \
99 push %es; \
100 push %ds; \
101 pushl %eax; \
102 pushl %ebp; \
103 pushl %edi; \
104 pushl %esi; \
105 pushl %edx; \
106 pushl %ecx; \
107 pushl %ebx; \
108 movl $(KERNEL_DS),%edx; \
109 mov %dx,%ds; \
110 mov %dx,%es; \
111 movl $(USER_DS),%edx; \
112 mov %dx,%fs;
113
114 #define RESTORE_ALL \
115 cmpw $(KERNEL_CS),CS(%esp); \
116 je 1f; \
117 movl _current,%eax; \
118 movl dbgreg7(%eax),%ebx; \
119 movl %ebx,%db7; \
120 1: popl %ebx; \
121 popl %ecx; \
122 popl %edx; \
123 popl %esi; \
124 popl %edi; \
125 popl %ebp; \
126 popl %eax; \
127 pop %ds; \
128 pop %es; \
129 pop %fs; \
130 pop %gs; \
131 addl $4,%esp; \
132 iret
133
134 .align 4
135 _lcall7:
136 pushfl # We get a different stack layout with call gates,
137 pushl %eax # which has to be cleaned up later..
138 SAVE_ALL
139 movl EIP(%esp),%eax # due to call gates, this is eflags, not eip..
140 movl CS(%esp),%edx # this is eip..
141 movl EFLAGS(%esp),%ecx # and this is cs..
142 movl %eax,EFLAGS(%esp) #
143 movl %edx,EIP(%esp) # Now we move them to their "normal" places
144 movl %ecx,CS(%esp) #
145 movl %esp,%eax
146 movl _current,%edx
147 pushl %eax
148 movl exec_domain(%edx),%edx # Get the execution domain
149 movl 4(%edx),%edx # Get the lcall7 handler for the domain
150 call *%edx
151 popl %eax
152 jmp ret_from_sys_call
153
154 .align 4
155 handle_bottom_half:
156 pushfl
157 incl _intr_count
158 sti
159 call _do_bottom_half
160 popfl
161 decl _intr_count
162 jmp 9f
163 .align 4
164 reschedule:
165 pushl $ret_from_sys_call
166 jmp _schedule
167 .align 4
168 _system_call:
169 pushl %eax # save orig_eax
170 SAVE_ALL
171 movl $-ENOSYS,EAX(%esp)
172 cmpl $(NR_syscalls),%eax
173 jae ret_from_sys_call
174 movl _sys_call_table(,%eax,4),%eax
175 testl %eax,%eax
176 je ret_from_sys_call
177 movl _current,%ebx
178 andl $~CF_MASK,EFLAGS(%esp) # clear carry - assume no errors
179 movl $0,errno(%ebx)
180 movl %db6,%edx
181 movl %edx,dbgreg6(%ebx) # save current hardware debugging status
182 testb $0x20,flags(%ebx) # PF_TRACESYS
183 jne 1f
184 call *%eax
185 movl %eax,EAX(%esp) # save the return value
186 movl errno(%ebx),%edx
187 negl %edx
188 je ret_from_sys_call
189 movl %edx,EAX(%esp)
190 orl $(CF_MASK),EFLAGS(%esp) # set carry to indicate error
191 jmp ret_from_sys_call
192 .align 4
193 1: call _syscall_trace
194 movl ORIG_EAX(%esp),%eax
195 call _sys_call_table(,%eax,4)
196 movl %eax,EAX(%esp) # save the return value
197 movl _current,%eax
198 movl errno(%eax),%edx
199 negl %edx
200 je 1f
201 movl %edx,EAX(%esp)
202 orl $(CF_MASK),EFLAGS(%esp) # set carry to indicate error
203 1: call _syscall_trace
204
205 .align 4,0x90
206 ret_from_sys_call:
207 cmpl $0,_intr_count
208 jne 2f
209 9: movl _bh_mask,%eax
210 andl _bh_active,%eax
211 jne handle_bottom_half
212 movl EFLAGS(%esp),%eax # check VM86 flag: CS/SS are
213 testl $(VM_MASK),%eax # different then
214 jne 1f
215 cmpw $(KERNEL_CS),CS(%esp) # was old code segment supervisor ?
216 je 2f
217 1: sti
218 orl $(IF_MASK),%eax # these just try to make sure
219 andl $~NT_MASK,%eax # the program doesn't do anything
220 movl %eax,EFLAGS(%esp) # stupid
221 cmpl $0,_need_resched
222 jne reschedule
223 movl _current,%eax
224 cmpl _task,%eax # task[0] cannot have signals
225 je 2f
226 cmpl $0,state(%eax) # state
227 jne reschedule
228 cmpl $0,counter(%eax) # counter
229 je reschedule
230 movl blocked(%eax),%ecx
231 movl %ecx,%ebx # save blocked in %ebx for signal handling
232 notl %ecx
233 andl signal(%eax),%ecx
234 jne signal_return
235 2: RESTORE_ALL
236 .align 4
237 signal_return:
238 movl %esp,%ecx
239 pushl %ecx
240 testl $(VM_MASK),EFLAGS(%ecx)
241 jne v86_signal_return
242 pushl %ebx
243 call _do_signal
244 popl %ebx
245 popl %ebx
246 RESTORE_ALL
247 .align 4
248 v86_signal_return:
249 call _save_v86_state
250 movl %eax,%esp
251 pushl %eax
252 pushl %ebx
253 call _do_signal
254 popl %ebx
255 popl %ebx
256 RESTORE_ALL
257
258 .align 4
259 _divide_error:
260 pushl $0 # no error code
261 pushl $_do_divide_error
262 .align 4,0x90
263 error_code:
264 push %fs
265 push %es
266 push %ds
267 pushl %eax
268 pushl %ebp
269 pushl %edi
270 pushl %esi
271 pushl %edx
272 pushl %ecx
273 pushl %ebx
274 movl $0,%eax
275 movl %eax,%db7 # disable hardware debugging...
276 cld
277 movl $-1, %eax
278 xchgl %eax, ORIG_EAX(%esp) # orig_eax (get the error code. )
279 xorl %ebx,%ebx # zero ebx
280 mov %gs,%bx # get the lower order bits of gs
281 xchgl %ebx, GS(%esp) # get the address and save gs.
282 pushl %eax # push the error code
283 lea 4(%esp),%edx
284 pushl %edx
285 movl $(KERNEL_DS),%edx
286 mov %dx,%ds
287 mov %dx,%es
288 movl $(USER_DS),%edx
289 mov %dx,%fs
290 pushl %eax
291 movl _current,%eax
292 movl %db6,%edx
293 movl %edx,dbgreg6(%eax) # save current hardware debugging status
294 popl %eax
295 call *%ebx
296 addl $8,%esp
297 jmp ret_from_sys_call
298
299 .align 4
300 _coprocessor_error:
301 pushl $0
302 pushl $_do_coprocessor_error
303 jmp error_code
304
305 .align 4
306 _device_not_available:
307 pushl $-1 # mark this as an int
308 SAVE_ALL
309 pushl $ret_from_sys_call
310 movl %cr0,%eax
311 testl $0x4,%eax # EM (math emulation bit)
312 je _math_state_restore
313 pushl $0 # temporary storage for ORIG_EIP
314 call _math_emulate
315 addl $4,%esp
316 ret
317
318 .align 4
319 _debug:
320 pushl $0
321 pushl $_do_debug
322 jmp error_code
323
324 .align 4
325 _nmi:
326 pushl $0
327 pushl $_do_nmi
328 jmp error_code
329
330 .align 4
331 _int3:
332 pushl $0
333 pushl $_do_int3
334 jmp error_code
335
336 .align 4
337 _overflow:
338 pushl $0
339 pushl $_do_overflow
340 jmp error_code
341
342 .align 4
343 _bounds:
344 pushl $0
345 pushl $_do_bounds
346 jmp error_code
347
348 .align 4
349 _invalid_op:
350 pushl $0
351 pushl $_do_invalid_op
352 jmp error_code
353
354 .align 4
355 _coprocessor_segment_overrun:
356 pushl $0
357 pushl $_do_coprocessor_segment_overrun
358 jmp error_code
359
360 .align 4
361 _reserved:
362 pushl $0
363 pushl $_do_reserved
364 jmp error_code
365
366 .align 4
367 _double_fault:
368 pushl $_do_double_fault
369 jmp error_code
370
371 .align 4
372 _invalid_TSS:
373 pushl $_do_invalid_TSS
374 jmp error_code
375
376 .align 4
377 _segment_not_present:
378 pushl $_do_segment_not_present
379 jmp error_code
380
381 .align 4
382 _stack_segment:
383 pushl $_do_stack_segment
384 jmp error_code
385
386 .align 4
387 _general_protection:
388 pushl $_do_general_protection
389 jmp error_code
390
391 .align 4
392 _alignment_check:
393 pushl $_do_alignment_check
394 jmp error_code
395
396 .align 4
397 _page_fault:
398 pushl $_do_page_fault
399 jmp error_code
400
401 .data
402 .align 4
403 _sys_call_table:
404 .long _sys_setup
405 .long _sys_exit
406 .long _sys_fork
407 .long _sys_read
408 .long _sys_write
409 .long _sys_open
410 .long _sys_close
411 .long _sys_waitpid
412 .long _sys_creat
413 .long _sys_link
414 .long _sys_unlink
415 .long _sys_execve
416 .long _sys_chdir
417 .long _sys_time
418 .long _sys_mknod
419 .long _sys_chmod
420 .long _sys_chown
421 .long _sys_break
422 .long _sys_stat
423 .long _sys_lseek
424 .long _sys_getpid
425 .long _sys_mount
426 .long _sys_umount
427 .long _sys_setuid
428 .long _sys_getuid
429 .long _sys_stime
430 .long _sys_ptrace
431 .long _sys_alarm
432 .long _sys_fstat
433 .long _sys_pause
434 .long _sys_utime
435 .long _sys_stty
436 .long _sys_gtty
437 .long _sys_access
438 .long _sys_nice
439 .long _sys_ftime
440 .long _sys_sync
441 .long _sys_kill
442 .long _sys_rename
443 .long _sys_mkdir
444 .long _sys_rmdir
445 .long _sys_dup
446 .long _sys_pipe
447 .long _sys_times
448 .long _sys_prof
449 .long _sys_brk
450 .long _sys_setgid
451 .long _sys_getgid
452 .long _sys_signal
453 .long _sys_geteuid
454 .long _sys_getegid
455 .long _sys_acct
456 .long _sys_phys
457 .long _sys_lock
458 .long _sys_ioctl
459 .long _sys_fcntl
460 .long _sys_mpx
461 .long _sys_setpgid
462 .long _sys_ulimit
463 .long _sys_olduname
464 .long _sys_umask
465 .long _sys_chroot
466 .long _sys_ustat
467 .long _sys_dup2
468 .long _sys_getppid
469 .long _sys_getpgrp
470 .long _sys_setsid
471 .long _sys_sigaction
472 .long _sys_sgetmask
473 .long _sys_ssetmask
474 .long _sys_setreuid
475 .long _sys_setregid
476 .long _sys_sigsuspend
477 .long _sys_sigpending
478 .long _sys_sethostname
479 .long _sys_setrlimit
480 .long _sys_getrlimit
481 .long _sys_getrusage
482 .long _sys_gettimeofday
483 .long _sys_settimeofday
484 .long _sys_getgroups
485 .long _sys_setgroups
486 .long _sys_select
487 .long _sys_symlink
488 .long _sys_lstat
489 .long _sys_readlink
490 .long _sys_uselib
491 .long _sys_swapon
492 .long _sys_reboot
493 .long _sys_readdir
494 .long _sys_mmap
495 .long _sys_munmap
496 .long _sys_truncate
497 .long _sys_ftruncate
498 .long _sys_fchmod
499 .long _sys_fchown
500 .long _sys_getpriority
501 .long _sys_setpriority
502 .long _sys_profil
503 .long _sys_statfs
504 .long _sys_fstatfs
505 .long _sys_ioperm
506 .long _sys_socketcall
507 .long _sys_syslog
508 .long _sys_setitimer
509 .long _sys_getitimer
510 .long _sys_newstat
511 .long _sys_newlstat
512 .long _sys_newfstat
513 .long _sys_uname
514 .long _sys_iopl
515 .long _sys_vhangup
516 .long _sys_idle
517 .long _sys_vm86
518 .long _sys_wait4
519 .long _sys_swapoff
520 .long _sys_sysinfo
521 .long _sys_ipc
522 .long _sys_fsync
523 .long _sys_sigreturn
524 .long _sys_clone
525 .long _sys_setdomainname
526 .long _sys_newuname
527 .long _sys_modify_ldt
528 .long _sys_adjtimex
529 .long _sys_mprotect
530 .long _sys_sigprocmask
531 .long _sys_create_module
532 .long _sys_init_module
533 .long _sys_delete_module
534 .long _sys_get_kernel_syms
535 .long _sys_quotactl
536 .long _sys_getpgid
537 .long _sys_fchdir
538 .long _sys_bdflush
539 .long _sys_sysfs
540 .long _sys_personality
541 .long 0
542 .long _sys_setfsuid
543 .long _sys_setfsgid
544 .long _sys_llseek
545 .space (NR_syscalls-140)*4