2 * linux/arch/i386/entry.S
4 * Copyright (C) 1991, 1992 Linus Torvalds
8 * entry.S contains the system-call and fault low-level handling routines.
9 * This also contains the timer-interrupt handler, as well as all interrupts
10 * and faults that can result in a task-switch.
12 * NOTE: This code handles signal-recognition, which happens every time
13 * after a timer-interrupt and after each system call.
15 * I changed all the .align's to 4 (16 byte alignment), as that's faster
18 * Stack layout in 'ret_from_system_call':
19 * ptrace needs to have all regs on the stack.
20 * if the order here is changed, it needs to be
21 * updated in fork.c:copy_process, signal.c:do_signal,
22 * ptrace.c and ptrace.h
40 * "current" is in register %ebx during any slow entries.
43 #include <linux/config.h>
44 #include <linux/sys.h>
45 #include <linux/linkage.h>
46 #include <asm/thread_info.h>
47 #include <asm/errno.h>
48 #include <asm/segment.h>
50 #include "irq_vectors.h"
76 #define preempt_stop cli
79 #define resume_kernel restore_all
93 movl $(__KERNEL_DS), %edx; \
109 .section .fixup,"ax"; \
121 .section __ex_table,"a";\
129 pushfl # We get a different stack layout with call
130 # gates, which has to be cleaned up later..
133 movl EIP(%esp), %eax # due to call gates, this is eflags, not eip..
134 movl CS(%esp), %edx # this is eip..
135 movl EFLAGS(%esp), %ecx # and this is cs..
136 movl %eax,EFLAGS(%esp) #
137 movl %edx,EIP(%esp) # Now we move them to their "normal" places
141 # Call gates don't clear TF and NT in eflags like
142 # traps do, so we need to do it ourselves.
143 # %eax already contains eflags (but it may have
144 # DF set, clear that also)
146 andl $~(DF_MASK | TF_MASK | NT_MASK),%eax
152 andl $-8192, %ebx # GET_THREAD_INFO
153 movl TI_EXEC_DOMAIN(%ebx), %edx # Get the execution domain
154 movl 4(%edx), %edx # Get the lcall7 handler for the domain
162 pushfl # We get a different stack layout with call
163 # gates, which has to be cleaned up later..
166 movl EIP(%esp), %eax # due to call gates, this is eflags, not eip..
167 movl CS(%esp), %edx # this is eip..
168 movl EFLAGS(%esp), %ecx # and this is cs..
169 movl %eax,EFLAGS(%esp) #
170 movl %edx,EIP(%esp) # Now we move them to their "normal" places
174 # Call gates don't clear TF and NT in eflags like
175 # traps do, so we need to do it ourselves.
176 # %eax already contains eflags (but it may have
177 # DF set, clear that also)
179 andl $~(DF_MASK | TF_MASK | NT_MASK),%eax
185 andl $-8192, %ebx # GET_THREAD_INFO
186 movl TI_EXEC_DOMAIN(%ebx), %edx # Get the execution domain
187 movl 4(%edx), %edx # Get the lcall7 handler for the domain
196 #if CONFIG_SMP || CONFIG_PREEMPT
197 # NOTE: this function takes a parameter but it's unused on x86.
200 GET_THREAD_INFO(%ebx)
204 * Return to user mode is not as complex as all this looks,
205 * but we want the default path for a system call return to
206 * go as quickly as possible which is why some of this is
207 * less clear than it otherwise should be.
210 # userspace resumption stub bypassing syscall exit tracing
215 GET_THREAD_INFO(%ebx)
216 movl EFLAGS(%esp), %eax # mix EFLAGS and CS
218 testl $(VM_MASK | 3), %eax
219 jz resume_kernel # returning to kernel or vm86-space
220 ENTRY(resume_userspace)
221 cli # make sure we don't miss an interrupt
222 # setting need_resched or sigpending
223 # between sampling and the iret
224 movl TI_FLAGS(%ebx), %ecx
225 andl $_TIF_WORK_MASK, %ecx # is there any work to be done on
226 # int/exception return?
230 #ifdef CONFIG_PREEMPT
232 cmpl $0,TI_PRE_COUNT(%ebx) # non-zero preempt_count ?
235 movl TI_FLAGS(%ebx), %ecx # need_resched set ?
236 testb $_TIF_NEED_RESCHED, %cl
238 testl $IF_MASK,EFLAGS(%esp) # interrupts off (execption path) ?
240 movl $PREEMPT_ACTIVE,TI_PRE_COUNT(%ebx)
243 movl $0,TI_PRE_COUNT(%ebx)
248 # system call handler stub
251 pushl %eax # save orig_eax
253 GET_THREAD_INFO(%ebx)
254 cmpl $(NR_syscalls), %eax
256 # system call tracing in operation
257 testb $_TIF_SYSCALL_TRACE,TI_FLAGS(%ebx)
258 jnz syscall_trace_entry
260 call *sys_call_table(,%eax,4)
261 movl %eax,EAX(%esp) # store the return value
263 cli # make sure we don't miss an interrupt
264 # setting need_resched or sigpending
265 # between sampling and the iret
266 movl TI_FLAGS(%ebx), %ecx
267 testw $_TIF_ALLWORK_MASK, %cx # current->work
268 jne syscall_exit_work
272 # perform work that needs to be done immediately before resumption
275 testb $_TIF_NEED_RESCHED, %cl
279 cli # make sure we don't miss an interrupt
280 # setting need_resched or sigpending
281 # between sampling and the iret
282 movl TI_FLAGS(%ebx), %ecx
283 andl $_TIF_WORK_MASK, %ecx # is there any work to be done other
284 # than syscall tracing?
286 testb $_TIF_NEED_RESCHED, %cl
289 work_notifysig: # deal with pending signals and
290 # notify-resume requests
291 testl $VM_MASK, EFLAGS(%esp)
293 jne work_notifysig_v86 # returning to kernel-space or
296 call do_notify_resume
306 call do_notify_resume
309 # perform syscall exit tracing
312 movl $-ENOSYS,EAX(%esp)
315 call do_syscall_trace
316 movl ORIG_EAX(%esp), %eax
317 cmpl $(NR_syscalls), %eax
321 # perform syscall exit tracing
324 testb $_TIF_SYSCALL_TRACE, %cl
326 sti # could let do_syscall_trace() call
330 call do_syscall_trace
335 movl $-ENOSYS,EAX(%esp)
339 * Build the entry stubs and pointer table with
340 * some assembler magic.
347 ENTRY(irq_entries_start)
364 #define BUILD_INTERRUPT(name, nr) \
371 /* The include is where all of the SMP etc. interrupts come from */
372 #include "entry_arch.h"
375 pushl $0 # no error code
376 pushl $do_divide_error
391 movl ORIG_EAX(%esp), %esi # get the error code
392 movl ES(%esp), %edi # get the function address
393 movl %eax, ORIG_EAX(%esp)
396 pushl %esi # push the error code
397 pushl %edx # push the pt_regs pointer
398 movl $(__KERNEL_DS), %edx
403 jmp ret_from_exception
405 ENTRY(coprocessor_error)
407 pushl $do_coprocessor_error
410 ENTRY(simd_coprocessor_error)
412 pushl $do_simd_coprocessor_error
415 ENTRY(device_not_available)
416 pushl $-1 # mark this as an int
419 testl $0x4, %eax # EM (math emulation bit)
420 jne device_not_available_emulate
422 call math_state_restore
423 jmp ret_from_exception
424 device_not_available_emulate:
425 pushl $0 # temporary storage for ORIG_EIP
428 jmp ret_from_exception
465 ENTRY(coprocessor_segment_overrun)
467 pushl $do_coprocessor_segment_overrun
471 pushl $do_double_fault
475 pushl $do_invalid_TSS
478 ENTRY(segment_not_present)
479 pushl $do_segment_not_present
483 pushl $do_stack_segment
486 ENTRY(general_protection)
487 pushl $do_general_protection
490 ENTRY(alignment_check)
491 pushl $do_alignment_check
498 #ifdef CONFIG_X86_MCE
501 pushl $do_machine_check
505 ENTRY(spurious_interrupt_bug)
507 pushl $do_spurious_interrupt_bug
511 ENTRY(sys_call_table)
512 .long sys_ni_syscall /* 0 - old "setup()" system call*/
517 .long sys_open /* 5 */
522 .long sys_unlink /* 10 */
527 .long sys_chmod /* 15 */
529 .long sys_ni_syscall /* old break syscall holder */
532 .long sys_getpid /* 20 */
537 .long sys_stime /* 25 */
542 .long sys_utime /* 30 */
543 .long sys_ni_syscall /* old stty syscall holder */
544 .long sys_ni_syscall /* old gtty syscall holder */
547 .long sys_ni_syscall /* 35 - old ftime syscall holder */
552 .long sys_rmdir /* 40 */
556 .long sys_ni_syscall /* old prof syscall holder */
557 .long sys_brk /* 45 */
562 .long sys_getegid16 /* 50 */
564 .long sys_umount /* recycled never used phys() */
565 .long sys_ni_syscall /* old lock syscall holder */
567 .long sys_fcntl /* 55 */
568 .long sys_ni_syscall /* old mpx syscall holder */
570 .long sys_ni_syscall /* old ulimit syscall holder */
572 .long sys_umask /* 60 */
577 .long sys_getpgrp /* 65 */
582 .long sys_setreuid16 /* 70 */
586 .long sys_sethostname
587 .long sys_setrlimit /* 75 */
588 .long sys_old_getrlimit
590 .long sys_gettimeofday
591 .long sys_settimeofday
592 .long sys_getgroups16 /* 80 */
593 .long sys_setgroups16
597 .long sys_readlink /* 85 */
602 .long old_mmap /* 90 */
607 .long sys_fchown16 /* 95 */
608 .long sys_getpriority
609 .long sys_setpriority
610 .long sys_ni_syscall /* old profil syscall holder */
612 .long sys_fstatfs /* 100 */
617 .long sys_getitimer /* 105 */
622 .long sys_iopl /* 110 */
624 .long sys_ni_syscall /* old "idle" system call */
627 .long sys_swapoff /* 115 */
632 .long sys_clone /* 120 */
633 .long sys_setdomainname
637 .long sys_mprotect /* 125 */
638 .long sys_sigprocmask
639 .long sys_ni_syscall /* old "create_module" */
640 .long sys_init_module
641 .long sys_delete_module
642 .long sys_ni_syscall /* 130: old "get_kernel_syms" */
647 .long sys_sysfs /* 135 */
648 .long sys_personality
649 .long sys_ni_syscall /* reserved for afs_syscall */
652 .long sys_llseek /* 140 */
657 .long sys_readv /* 145 */
662 .long sys_mlock /* 150 */
666 .long sys_sched_setparam
667 .long sys_sched_getparam /* 155 */
668 .long sys_sched_setscheduler
669 .long sys_sched_getscheduler
670 .long sys_sched_yield
671 .long sys_sched_get_priority_max
672 .long sys_sched_get_priority_min /* 160 */
673 .long sys_sched_rr_get_interval
676 .long sys_setresuid16
677 .long sys_getresuid16 /* 165 */
679 .long sys_ni_syscall /* Old sys_query_module */
682 .long sys_setresgid16 /* 170 */
683 .long sys_getresgid16
685 .long sys_rt_sigreturn
686 .long sys_rt_sigaction
687 .long sys_rt_sigprocmask /* 175 */
688 .long sys_rt_sigpending
689 .long sys_rt_sigtimedwait
690 .long sys_rt_sigqueueinfo
691 .long sys_rt_sigsuspend
692 .long sys_pread64 /* 180 */
697 .long sys_capset /* 185 */
698 .long sys_sigaltstack
700 .long sys_ni_syscall /* reserved for streams1 */
701 .long sys_ni_syscall /* reserved for streams2 */
702 .long sys_vfork /* 190 */
706 .long sys_ftruncate64
707 .long sys_stat64 /* 195 */
712 .long sys_getgid /* 200 */
717 .long sys_getgroups /* 205 */
722 .long sys_setresgid /* 210 */
727 .long sys_setfsuid /* 215 */
732 .long sys_getdents64 /* 220 */
734 .long sys_ni_syscall /* reserved for TUX */
735 .long sys_security /* reserved for Security */
737 .long sys_readahead /* 225 */
742 .long sys_lgetxattr /* 230 */
747 .long sys_removexattr /* 235 */
748 .long sys_lremovexattr
749 .long sys_fremovexattr
752 .long sys_futex /* 240 */
753 .long sys_sched_setaffinity
754 .long sys_sched_getaffinity
755 .long sys_set_thread_area
756 .long sys_get_thread_area
757 .long sys_io_setup /* 245 */
759 .long sys_io_getevents
762 .long sys_alloc_hugepages /* 250 */
763 .long sys_free_hugepages
765 .long sys_lookup_dcookie
766 .long sys_epoll_create
767 .long sys_epoll_ctl /* 255 */
769 .long sys_remap_file_pages
770 .long sys_set_tid_address
773 .rept NR_syscalls-(.-sys_call_table)/4