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/linkage.h>
45 #include <asm/thread_info.h>
46 #include <asm/errno.h>
47 #include <asm/segment.h>
50 #include "irq_vectors.h"
52 #define nr_syscalls ((syscall_table_size)/4)
78 #define preempt_stop cli
81 #define resume_kernel restore_all
95 movl $(__USER_DS), %edx; \
99 #define RESTORE_INT_REGS \
108 #define RESTORE_REGS \
112 .section .fixup,"ax"; \
118 .section __ex_table,"a";\
125 #define RESTORE_ALL \
129 .section .fixup,"ax"; \
131 movl $(__USER_DS), %edx; \
137 .section __ex_table,"a";\
146 GET_THREAD_INFO(%ebp)
151 * Return to user mode is not as complex as all this looks,
152 * but we want the default path for a system call return to
153 * go as quickly as possible which is why some of this is
154 * less clear than it otherwise should be.
157 # userspace resumption stub bypassing syscall exit tracing
162 GET_THREAD_INFO(%ebp)
163 movl EFLAGS(%esp), %eax # mix EFLAGS and CS
165 testl $(VM_MASK | 3), %eax
166 jz resume_kernel # returning to kernel or vm86-space
167 ENTRY(resume_userspace)
168 cli # make sure we don't miss an interrupt
169 # setting need_resched or sigpending
170 # between sampling and the iret
171 movl TI_flags(%ebp), %ecx
172 andl $_TIF_WORK_MASK, %ecx # is there any work to be done on
173 # int/exception return?
177 #ifdef CONFIG_PREEMPT
179 cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ?
182 movl TI_flags(%ebp), %ecx # need_resched set ?
183 testb $_TIF_NEED_RESCHED, %cl
185 testl $IF_MASK,EFLAGS(%esp) # interrupts off (exception path) ?
187 movl $PREEMPT_ACTIVE,TI_preempt_count(%ebp)
191 movl $0,TI_preempt_count(%ebp)
195 /* SYSENTER_RETURN points to after the "sysenter" instruction in
196 the vsyscall page. See vsyscall-sysentry.S, which defines the symbol. */
198 # sysenter call handler stub
199 ENTRY(sysenter_entry)
200 movl TSS_sysenter_esp0(%esp),%esp
208 * Push current_thread_info()->sysenter_return to the stack.
209 * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
210 * pushed above, and the word being pushed now:
212 pushl (TI_sysenter_return-THREAD_SIZE+4*4)(%esp)
214 * Load the potential sixth argument from user stack.
215 * Careful about security.
217 cmpl $__PAGE_OFFSET-3,%ebp
220 .section __ex_table,"a"
222 .long 1b,syscall_fault
227 GET_THREAD_INFO(%ebp)
229 testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
230 jnz syscall_trace_entry
231 cmpl $(nr_syscalls), %eax
233 call *sys_call_table(,%eax,4)
236 movl TI_flags(%ebp), %ecx
237 testw $_TIF_ALLWORK_MASK, %cx
238 jne syscall_exit_work
239 /* if something modifies registers it must also disable sysexit */
241 movl OLDESP(%esp), %ecx
247 # system call handler stub
249 pushl %eax # save orig_eax
251 GET_THREAD_INFO(%ebp)
252 # system call tracing in operation
253 testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
254 jnz syscall_trace_entry
255 cmpl $(nr_syscalls), %eax
258 call *sys_call_table(,%eax,4)
259 movl %eax,EAX(%esp) # store the return value
261 cli # make sure we don't miss an interrupt
262 # setting need_resched or sigpending
263 # between sampling and the iret
264 movl TI_flags(%ebp), %ecx
265 testw $_TIF_ALLWORK_MASK, %cx # current->work
266 jne syscall_exit_work
270 # perform work that needs to be done immediately before resumption
273 testb $_TIF_NEED_RESCHED, %cl
277 cli # make sure we don't miss an interrupt
278 # setting need_resched or sigpending
279 # between sampling and the iret
280 movl TI_flags(%ebp), %ecx
281 andl $_TIF_WORK_MASK, %ecx # is there any work to be done other
282 # than syscall tracing?
284 testb $_TIF_NEED_RESCHED, %cl
287 work_notifysig: # deal with pending signals and
288 # notify-resume requests
289 testl $VM_MASK, EFLAGS(%esp)
291 jne work_notifysig_v86 # returning to kernel-space or
294 call do_notify_resume
299 pushl %ecx # save ti_flags for do_notify_resume
300 call save_v86_state # %eax contains pt_regs pointer
304 call do_notify_resume
307 # perform syscall exit tracing
310 movl $-ENOSYS,EAX(%esp)
313 call do_syscall_trace
314 movl ORIG_EAX(%esp), %eax
315 cmpl $(nr_syscalls), %eax
319 # perform syscall exit tracing
322 testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP), %cl
324 sti # could let do_syscall_trace() call
328 call do_syscall_trace
333 pushl %eax # save orig_eax
335 GET_THREAD_INFO(%ebp)
336 movl $-EFAULT,EAX(%esp)
341 movl $-ENOSYS,EAX(%esp)
345 * Build the entry stubs and pointer table with
346 * some assembler magic.
353 ENTRY(irq_entries_start)
371 #define BUILD_INTERRUPT(name, nr) \
379 /* The include is where all of the SMP etc. interrupts come from */
380 #include "entry_arch.h"
383 pushl $0 # no error code
384 pushl $do_divide_error
399 movl ES(%esp), %edi # get the function address
400 movl ORIG_EAX(%esp), %edx # get the error code
401 movl %eax, ORIG_EAX(%esp)
403 movl $(__USER_DS), %ecx
406 movl %esp,%eax # pt_regs pointer
408 jmp ret_from_exception
410 ENTRY(coprocessor_error)
412 pushl $do_coprocessor_error
415 ENTRY(simd_coprocessor_error)
417 pushl $do_simd_coprocessor_error
420 ENTRY(device_not_available)
421 pushl $-1 # mark this as an int
424 testl $0x4, %eax # EM (math emulation bit)
425 jne device_not_available_emulate
427 call math_state_restore
428 jmp ret_from_exception
429 device_not_available_emulate:
430 pushl $0 # temporary storage for ORIG_EIP
433 jmp ret_from_exception
436 * Debug traps and NMI can happen at the one SYSENTER instruction
437 * that sets up the real kernel stack. Check here, since we can't
438 * allow the wrong stack to be used.
440 * "TSS_sysenter_esp0+12" is because the NMI/debug handler will have
441 * already pushed 3 words if it hits on the sysenter instruction:
442 * eflags, cs and eip.
444 * We just load the right stack, and push the three (known) values
445 * by hand onto the new stack - while updating the return eip past
446 * the instruction that would have done it for sysenter.
448 #define FIX_STACK(offset, ok, label) \
449 cmpw $__KERNEL_CS,4(%esp); \
452 movl TSS_sysenter_esp0+offset(%esp),%esp; \
454 pushl $__KERNEL_CS; \
455 pushl $sysenter_past_esp
458 cmpl $sysenter_entry,(%esp)
459 jne debug_stack_correct
460 FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn)
462 pushl $-1 # mark this as an int
464 xorl %edx,%edx # error code 0
465 movl %esp,%eax # pt_regs pointer
469 jmp ret_from_exception
472 * NMI is doubly nasty. It can happen _while_ we're handling
473 * a debug fault, and the debug fault hasn't yet been able to
474 * clear up the stack. So we first check whether we got an
475 * NMI on the sysenter entry path, but after that we need to
476 * check whether we got an NMI on the debug path where the debug
477 * fault happened on the sysenter path.
480 cmpl $sysenter_entry,(%esp)
484 /* Do not access memory above the end of our stack page,
485 * it might not exist.
487 andl $(THREAD_SIZE-1),%eax
488 cmpl $(THREAD_SIZE-20),%eax
490 jae nmi_stack_correct
491 cmpl $sysenter_entry,12(%esp)
492 je nmi_debug_stack_check
496 xorl %edx,%edx # zero error code
497 movl %esp,%eax # pt_regs pointer
502 FIX_STACK(12,nmi_stack_correct, 1)
503 jmp nmi_stack_correct
504 nmi_debug_stack_check:
505 cmpw $__KERNEL_CS,16(%esp)
506 jne nmi_stack_correct
507 cmpl $debug - 1,(%esp)
508 jle nmi_stack_correct
509 cmpl $debug_esp_fix_insn,(%esp)
510 jle nmi_debug_stack_fixup
511 nmi_debug_stack_fixup:
512 FIX_STACK(24,nmi_stack_correct, 1)
513 jmp nmi_stack_correct
516 pushl $-1 # mark this as an int
518 xorl %edx,%edx # zero error code
519 movl %esp,%eax # pt_regs pointer
523 jmp ret_from_exception
540 ENTRY(coprocessor_segment_overrun)
542 pushl $do_coprocessor_segment_overrun
546 pushl $do_invalid_TSS
549 ENTRY(segment_not_present)
550 pushl $do_segment_not_present
554 pushl $do_stack_segment
557 ENTRY(general_protection)
558 pushl $do_general_protection
561 ENTRY(alignment_check)
562 pushl $do_alignment_check
569 #ifdef CONFIG_X86_MCE
572 pushl machine_check_vector
576 ENTRY(spurious_interrupt_bug)
578 pushl $do_spurious_interrupt_bug
582 ENTRY(sys_call_table)
583 .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
588 .long sys_open /* 5 */
593 .long sys_unlink /* 10 */
598 .long sys_chmod /* 15 */
600 .long sys_ni_syscall /* old break syscall holder */
603 .long sys_getpid /* 20 */
608 .long sys_stime /* 25 */
613 .long sys_utime /* 30 */
614 .long sys_ni_syscall /* old stty syscall holder */
615 .long sys_ni_syscall /* old gtty syscall holder */
618 .long sys_ni_syscall /* 35 - old ftime syscall holder */
623 .long sys_rmdir /* 40 */
627 .long sys_ni_syscall /* old prof syscall holder */
628 .long sys_brk /* 45 */
633 .long sys_getegid16 /* 50 */
635 .long sys_umount /* recycled never used phys() */
636 .long sys_ni_syscall /* old lock syscall holder */
638 .long sys_fcntl /* 55 */
639 .long sys_ni_syscall /* old mpx syscall holder */
641 .long sys_ni_syscall /* old ulimit syscall holder */
643 .long sys_umask /* 60 */
648 .long sys_getpgrp /* 65 */
653 .long sys_setreuid16 /* 70 */
657 .long sys_sethostname
658 .long sys_setrlimit /* 75 */
659 .long sys_old_getrlimit
661 .long sys_gettimeofday
662 .long sys_settimeofday
663 .long sys_getgroups16 /* 80 */
664 .long sys_setgroups16
668 .long sys_readlink /* 85 */
673 .long old_mmap /* 90 */
678 .long sys_fchown16 /* 95 */
679 .long sys_getpriority
680 .long sys_setpriority
681 .long sys_ni_syscall /* old profil syscall holder */
683 .long sys_fstatfs /* 100 */
688 .long sys_getitimer /* 105 */
693 .long sys_iopl /* 110 */
695 .long sys_ni_syscall /* old "idle" system call */
698 .long sys_swapoff /* 115 */
703 .long sys_clone /* 120 */
704 .long sys_setdomainname
708 .long sys_mprotect /* 125 */
709 .long sys_sigprocmask
710 .long sys_ni_syscall /* old "create_module" */
711 .long sys_init_module
712 .long sys_delete_module
713 .long sys_ni_syscall /* 130: old "get_kernel_syms" */
718 .long sys_sysfs /* 135 */
719 .long sys_personality
720 .long sys_ni_syscall /* reserved for afs_syscall */
723 .long sys_llseek /* 140 */
728 .long sys_readv /* 145 */
733 .long sys_mlock /* 150 */
737 .long sys_sched_setparam
738 .long sys_sched_getparam /* 155 */
739 .long sys_sched_setscheduler
740 .long sys_sched_getscheduler
741 .long sys_sched_yield
742 .long sys_sched_get_priority_max
743 .long sys_sched_get_priority_min /* 160 */
744 .long sys_sched_rr_get_interval
747 .long sys_setresuid16
748 .long sys_getresuid16 /* 165 */
750 .long sys_ni_syscall /* Old sys_query_module */
753 .long sys_setresgid16 /* 170 */
754 .long sys_getresgid16
756 .long sys_rt_sigreturn
757 .long sys_rt_sigaction
758 .long sys_rt_sigprocmask /* 175 */
759 .long sys_rt_sigpending
760 .long sys_rt_sigtimedwait
761 .long sys_rt_sigqueueinfo
762 .long sys_rt_sigsuspend
763 .long sys_pread64 /* 180 */
768 .long sys_capset /* 185 */
769 .long sys_sigaltstack
771 .long sys_ni_syscall /* reserved for streams1 */
772 .long sys_ni_syscall /* reserved for streams2 */
773 .long sys_vfork /* 190 */
777 .long sys_ftruncate64
778 .long sys_stat64 /* 195 */
783 .long sys_getgid /* 200 */
788 .long sys_getgroups /* 205 */
793 .long sys_setresgid /* 210 */
798 .long sys_setfsuid /* 215 */
803 .long sys_getdents64 /* 220 */
808 # ifdef CONFIG_TUX_MODULE
816 .long sys_readahead /* 225 */
821 .long sys_lgetxattr /* 230 */
826 .long sys_removexattr /* 235 */
827 .long sys_lremovexattr
828 .long sys_fremovexattr
831 .long sys_futex /* 240 */
832 .long sys_sched_setaffinity
833 .long sys_sched_getaffinity
834 .long sys_set_thread_area
835 .long sys_get_thread_area
836 .long sys_io_setup /* 245 */
838 .long sys_io_getevents
841 .long sys_fadvise64 /* 250 */
844 .long sys_lookup_dcookie
845 .long sys_epoll_create
846 .long sys_epoll_ctl /* 255 */
848 .long sys_remap_file_pages
849 .long sys_set_tid_address
850 .long sys_timer_create
851 .long sys_timer_settime /* 260 */
852 .long sys_timer_gettime
853 .long sys_timer_getoverrun
854 .long sys_timer_delete
855 .long sys_clock_settime
856 .long sys_clock_gettime /* 265 */
857 .long sys_clock_getres
858 .long sys_clock_nanosleep
861 .long sys_tgkill /* 270 */
863 .long sys_fadvise64_64
866 .long sys_get_mempolicy
867 .long sys_set_mempolicy
870 .long sys_mq_timedsend
871 .long sys_mq_timedreceive /* 280 */
873 .long sys_mq_getsetattr
874 .long sys_ni_syscall /* reserved for kexec */
876 .long sys_ni_syscall /* 285 */ /* available */
878 .long sys_request_key
881 syscall_table_size=(.-sys_call_table)