This stack check implementation leverages the compiler's profiling (gcc -p)
[linux-2.6.git] / arch / i386 / kernel / entry.S
1 /*
2  *  linux/arch/i386/entry.S
3  *
4  *  Copyright (C) 1991, 1992  Linus Torvalds
5  */
6
7 /*
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.
11  *
12  * NOTE: This code handles signal-recognition, which happens every time
13  * after a timer-interrupt and after each system call.
14  *
15  * I changed all the .align's to 4 (16 byte alignment), as that's faster
16  * on a 486.
17  *
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
23  *
24  *       0(%esp) - %ebx
25  *       4(%esp) - %ecx
26  *       8(%esp) - %edx
27  *       C(%esp) - %esi
28  *      10(%esp) - %edi
29  *      14(%esp) - %ebp
30  *      18(%esp) - %eax
31  *      1C(%esp) - %ds
32  *      20(%esp) - %es
33  *      24(%esp) - orig_eax
34  *      28(%esp) - %eip
35  *      2C(%esp) - %cs
36  *      30(%esp) - %eflags
37  *      34(%esp) - %oldesp
38  *      38(%esp) - %oldss
39  *
40  * "current" is in register %ebx during any slow entries.
41  */
42
43 #include <linux/config.h>
44 #include <linux/linkage.h>
45 #include <asm/thread_info.h>
46 #include <asm/asm_offsets.h>
47 #include <asm/errno.h>
48 #include <asm/segment.h>
49 #include <asm/page.h>
50 #include <asm/smp.h>
51 #include <asm/page.h>
52 #include "irq_vectors.h"
53
54 #define nr_syscalls ((syscall_table_size)/4)
55
56 EBX             = 0x00
57 ECX             = 0x04
58 EDX             = 0x08
59 ESI             = 0x0C
60 EDI             = 0x10
61 EBP             = 0x14
62 EAX             = 0x18
63 DS              = 0x1C
64 ES              = 0x20
65 ORIG_EAX        = 0x24
66 EIP             = 0x28
67 CS              = 0x2C
68 EFLAGS          = 0x30
69 OLDESP          = 0x34
70 OLDSS           = 0x38
71
72 CF_MASK         = 0x00000001
73 TF_MASK         = 0x00000100
74 IF_MASK         = 0x00000200
75 DF_MASK         = 0x00000400 
76 NT_MASK         = 0x00004000
77 VM_MASK         = 0x00020000
78
79 #ifdef CONFIG_PREEMPT
80 #define preempt_stop            cli
81 #else
82 #define preempt_stop
83 #define resume_kernel           restore_all
84 #endif
85
86 #ifdef CONFIG_X86_HIGH_ENTRY
87
88 #ifdef CONFIG_X86_SWITCH_PAGETABLES
89
90 #if defined(CONFIG_PREEMPT) && defined(CONFIG_SMP)
91 /*
92  * If task is preempted in __SWITCH_KERNELSPACE, and moved to another cpu,
93  * __switch_to repoints %esp to the appropriate virtual stack; but %ebp is
94  * left stale, so we must check whether to repeat the real stack calculation.
95  */
96 #define repeat_if_esp_changed                           \
97         xorl %esp, %ebp;                                \
98         testl $-THREAD_SIZE, %ebp;                      \
99         jnz 0b
100 #else
101 #define repeat_if_esp_changed
102 #endif
103
104 /* clobbers ebx, edx and ebp */
105
106 #define __SWITCH_KERNELSPACE                            \
107         cmpl $0xff000000, %esp;                         \
108         jb 1f;                                          \
109                                                         \
110         /*                                              \
111          * switch pagetables and load the real stack,   \
112          * keep the stack offset:                       \
113          */                                             \
114                                                         \
115         movl $swapper_pg_dir-__PAGE_OFFSET, %edx;       \
116                                                         \
117         /* GET_THREAD_INFO(%ebp) intermixed */          \
118 0:                                                      \
119         movl %esp, %ebp;                                \
120         movl %esp, %ebx;                                \
121         andl $(-THREAD_SIZE), %ebp;                             \
122         andl $(THREAD_SIZE-1), %ebx;                            \
123         orl TI_real_stack(%ebp), %ebx;                  \
124         repeat_if_esp_changed;                          \
125                                                         \
126         movl %edx, %cr3;                                \
127         movl %ebx, %esp;                                \
128 1:
129
130 #endif
131
132
133 #define __SWITCH_USERSPACE \
134         /* interrupted any of the user return paths? */ \
135                                                         \
136         movl EIP(%esp), %eax;                           \
137                                                         \
138         cmpl $int80_ret_start_marker, %eax;             \
139         jb 33f; /* nope - continue with sysexit check */\
140         cmpl $int80_ret_end_marker, %eax;               \
141         jb 22f; /* yes - switch to virtual stack */     \
142 33:                                                     \
143         cmpl $sysexit_ret_start_marker, %eax;           \
144         jb 44f; /* nope - continue with user check */   \
145         cmpl $sysexit_ret_end_marker, %eax;             \
146         jb 22f; /* yes - switch to virtual stack */     \
147         /* return to userspace? */                      \
148 44:                                                     \
149         movl EFLAGS(%esp),%ecx;                         \
150         movb CS(%esp),%cl;                              \
151         testl $(VM_MASK | 3),%ecx;                      \
152         jz 2f;                                          \
153 22:                                                     \
154         /*                                              \
155          * switch to the virtual stack, then switch to  \
156          * the userspace pagetables.                    \
157          */                                             \
158                                                         \
159         GET_THREAD_INFO(%ebp);                          \
160         movl TI_virtual_stack(%ebp), %edx;              \
161         movl TI_user_pgd(%ebp), %ecx;                   \
162                                                         \
163         movl %esp, %ebx;                                \
164         andl $(THREAD_SIZE-1), %ebx;                            \
165         orl %ebx, %edx;                                 \
166 int80_ret_start_marker:                                 \
167         movl %edx, %esp;                                \
168         movl %ecx, %cr3;                                \
169                                                         \
170         __RESTORE_ALL;                                  \
171 int80_ret_end_marker:                                   \
172 2:
173
174 #else /* !CONFIG_X86_HIGH_ENTRY */
175
176 #define __SWITCH_KERNELSPACE
177 #define __SWITCH_USERSPACE
178
179 #endif
180
181 #define __SAVE_ALL \
182         cld; \
183         pushl %es; \
184         pushl %ds; \
185         pushl %eax; \
186         pushl %ebp; \
187         pushl %edi; \
188         pushl %esi; \
189         pushl %edx; \
190         pushl %ecx; \
191         pushl %ebx; \
192         movl $(__USER_DS), %edx; \
193         movl %edx, %ds; \
194         movl %edx, %es;
195
196 #define __RESTORE_INT_REGS \
197         popl %ebx;      \
198         popl %ecx;      \
199         popl %edx;      \
200         popl %esi;      \
201         popl %edi;      \
202         popl %ebp;      \
203         popl %eax
204
205 #define __RESTORE_REGS  \
206         __RESTORE_INT_REGS; \
207 111:    popl %ds;       \
208 222:    popl %es;       \
209 .section .fixup,"ax";   \
210 444:    movl $0,(%esp); \
211         jmp 111b;       \
212 555:    movl $0,(%esp); \
213         jmp 222b;       \
214 .previous;              \
215 .section __ex_table,"a";\
216         .align 4;       \
217         .long 111b,444b;\
218         .long 222b,555b;\
219 .previous
220
221 #define __RESTORE_ALL   \
222         __RESTORE_REGS  \
223         addl $4, %esp;  \
224 333:    iret;           \
225 .section .fixup,"ax";   \
226 666:    sti;            \
227         movl $(__USER_DS), %edx; \
228         movl %edx, %ds; \
229         movl %edx, %es; \
230         pushl $11;      \
231         call do_exit;   \
232 .previous;              \
233 .section __ex_table,"a";\
234         .align 4;       \
235         .long 333b,666b;\
236 .previous
237
238 #define SAVE_ALL \
239         __SAVE_ALL;                                     \
240         __SWITCH_KERNELSPACE;
241
242 #define RESTORE_ALL                                     \
243         __SWITCH_USERSPACE;                             \
244         __RESTORE_ALL;
245
246 .section .entry.text,"ax"
247
248 ENTRY(lcall7)
249         pushfl                  # We get a different stack layout with call
250                                 # gates, which has to be cleaned up later..
251         pushl %eax
252         SAVE_ALL
253         movl %esp, %ebp
254         pushl %ebp
255         pushl $0x7
256 do_lcall:
257         movl EIP(%ebp), %eax    # due to call gates, this is eflags, not eip..
258         movl CS(%ebp), %edx     # this is eip..
259         movl EFLAGS(%ebp), %ecx # and this is cs..
260         movl %eax,EFLAGS(%ebp)  #
261         movl %edx,EIP(%ebp)     # Now we move them to their "normal" places
262         movl %ecx,CS(%ebp)      #
263         GET_THREAD_INFO_WITH_ESP(%ebp)  # GET_THREAD_INFO
264         movl TI_exec_domain(%ebp), %edx # Get the execution domain
265         call *EXEC_DOMAIN_handler(%edx) # Call the handler for the domain
266         addl $4, %esp
267         popl %eax
268         jmp resume_userspace
269
270 ENTRY(lcall27)
271         pushfl                  # We get a different stack layout with call
272                                 # gates, which has to be cleaned up later..
273         pushl %eax
274         SAVE_ALL
275         movl %esp, %ebp
276         pushl %ebp
277         pushl $0x27
278         jmp do_lcall
279
280
281 ENTRY(ret_from_fork)
282         pushl %eax
283         call schedule_tail
284         GET_THREAD_INFO(%ebp)
285         popl %eax
286         jmp syscall_exit
287
288 /*
289  * Return to user mode is not as complex as all this looks,
290  * but we want the default path for a system call return to
291  * go as quickly as possible which is why some of this is
292  * less clear than it otherwise should be.
293  */
294
295         # userspace resumption stub bypassing syscall exit tracing
296         ALIGN
297 ret_from_exception:
298         preempt_stop
299 ret_from_intr:
300         GET_THREAD_INFO(%ebp)
301         movl EFLAGS(%esp), %eax         # mix EFLAGS and CS
302         movb CS(%esp), %al
303         testl $(VM_MASK | 3), %eax
304         jz resume_kernel                # returning to kernel or vm86-space
305 ENTRY(resume_userspace)
306         cli                             # make sure we don't miss an interrupt
307                                         # setting need_resched or sigpending
308                                         # between sampling and the iret
309         movl TI_flags(%ebp), %ecx
310         andl $_TIF_WORK_MASK, %ecx      # is there any work to be done on
311                                         # int/exception return?
312         jne work_pending
313         jmp restore_all
314
315 #ifdef CONFIG_PREEMPT
316 ENTRY(resume_kernel)
317         cmpl $0,TI_preempt_count(%ebp)  # non-zero preempt_count ?
318         jnz restore_all
319 need_resched:
320         movl TI_flags(%ebp), %ecx       # need_resched set ?
321         testb $_TIF_NEED_RESCHED, %cl
322         jz restore_all
323         testl $IF_MASK,EFLAGS(%esp)     # interrupts off (exception path) ?
324         jz restore_all
325         movl $PREEMPT_ACTIVE,TI_preempt_count(%ebp)
326         sti
327         call schedule
328         movl $0,TI_preempt_count(%ebp)
329         cli
330         jmp need_resched
331 #endif
332
333 /* SYSENTER_RETURN points to after the "sysenter" instruction in
334    the vsyscall page.  See vsyscall-sysentry.S, which defines the symbol.  */
335
336         # sysenter call handler stub
337 ENTRY(sysenter_entry)
338         movl TSS_sysenter_esp0(%esp),%esp
339 sysenter_past_esp:
340         sti
341         pushl $(__USER_DS)
342         pushl %ebp
343         pushfl
344         pushl $(__USER_CS)
345         /*
346          * Push current_thread_info()->sysenter_return to the stack.
347          * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
348          * pushed above, and the word being pushed now:
349          */
350         pushl (TI_sysenter_return-THREAD_SIZE+4*4)(%esp)
351         /*
352          * No six-argument syscall is ever used with sysenter.
353          */
354         pushl %eax
355         SAVE_ALL
356         GET_THREAD_INFO(%ebp)
357         cmpl $(nr_syscalls), %eax
358         jae syscall_badsys
359
360         testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
361         jnz syscall_trace_entry
362         call *sys_call_table(,%eax,4)
363         movl %eax,EAX(%esp)
364         cli
365         movl TI_flags(%ebp), %ecx
366         testw $_TIF_ALLWORK_MASK, %cx
367         jne syscall_exit_work
368
369 #ifdef CONFIG_X86_SWITCH_PAGETABLES
370
371         GET_THREAD_INFO(%ebp)
372         movl TI_virtual_stack(%ebp), %edx
373         movl TI_user_pgd(%ebp), %ecx
374         movl %esp, %ebx
375         andl $(THREAD_SIZE-1), %ebx
376         orl %ebx, %edx
377 sysexit_ret_start_marker:
378         movl %edx, %esp
379         movl %ecx, %cr3
380         /*
381          * only ebx is not restored by the userspace sysenter vsyscall
382          * code, it assumes it to be callee-saved.
383          */
384         movl EBX(%esp), %ebx
385 #endif
386
387 /* if something modifies registers it must also disable sysexit */
388         movl EIP(%esp), %edx
389         movl OLDESP(%esp), %ecx
390         sti
391         sysexit
392 #ifdef CONFIG_X86_SWITCH_PAGETABLES
393 sysexit_ret_end_marker:
394         nop
395 #endif
396
397         # system call handler stub
398 ENTRY(system_call)
399         pushl %eax                      # save orig_eax
400         SAVE_ALL
401         GET_THREAD_INFO(%ebp)
402         cmpl $(nr_syscalls), %eax
403         jae syscall_badsys
404                                         # system call tracing in operation
405         testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
406         jnz syscall_trace_entry
407 syscall_call:
408         call *sys_call_table(,%eax,4)
409         movl %eax,EAX(%esp)             # store the return value
410 syscall_exit:
411         cli                             # make sure we don't miss an interrupt
412                                         # setting need_resched or sigpending
413                                         # between sampling and the iret
414         movl TI_flags(%ebp), %ecx
415         testw $_TIF_ALLWORK_MASK, %cx   # current->work
416         jne syscall_exit_work
417 restore_all:
418         RESTORE_ALL
419
420         # perform work that needs to be done immediately before resumption
421         ALIGN
422 work_pending:
423         testb $_TIF_NEED_RESCHED, %cl
424         jz work_notifysig
425 work_resched:
426         call schedule
427         cli                             # make sure we don't miss an interrupt
428                                         # setting need_resched or sigpending
429                                         # between sampling and the iret
430         movl TI_flags(%ebp), %ecx
431         andl $_TIF_WORK_MASK, %ecx      # is there any work to be done other
432                                         # than syscall tracing?
433         jz restore_all
434         testb $_TIF_NEED_RESCHED, %cl
435         jnz work_resched
436
437 work_notifysig:                         # deal with pending signals and
438                                         # notify-resume requests
439         testl $VM_MASK, EFLAGS(%esp)
440         movl %esp, %eax
441         jne work_notifysig_v86          # returning to kernel-space or
442                                         # vm86-space
443         xorl %edx, %edx
444         call do_notify_resume
445
446 #if CONFIG_X86_HIGH_ENTRY
447         /*
448          * Reload db7 if necessary:
449          */
450         movl TI_flags(%ebp), %ecx
451         testb $_TIF_DB7, %cl
452         jnz work_db7
453
454         jmp restore_all
455
456 work_db7:
457         movl TI_task(%ebp), %edx;
458         movl task_thread_db7(%edx), %edx;
459         movl %edx, %db7;
460 #endif
461         jmp restore_all
462
463         ALIGN
464 work_notifysig_v86:
465         pushl %ecx
466         call save_v86_state
467         popl %ecx
468         movl %eax, %esp
469         xorl %edx, %edx
470         call do_notify_resume
471         jmp restore_all
472
473         # perform syscall exit tracing
474         ALIGN
475 syscall_trace_entry:
476         movl $-ENOSYS,EAX(%esp)
477         movl %esp, %eax
478         xorl %edx,%edx
479         call do_syscall_trace
480         movl ORIG_EAX(%esp), %eax
481         cmpl $(nr_syscalls), %eax
482         jnae syscall_call
483         jmp syscall_exit
484
485         # perform syscall exit tracing
486         ALIGN
487 syscall_exit_work:
488         testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT), %cl
489         jz work_pending
490         sti                             # could let do_syscall_trace() call
491                                         # schedule() instead
492         movl %esp, %eax
493         movl $1, %edx
494         call do_syscall_trace
495         jmp resume_userspace
496
497         ALIGN
498 syscall_badsys:
499         movl $-ENOSYS,EAX(%esp)
500         jmp resume_userspace
501
502 /*
503  * Build the entry stubs and pointer table with
504  * some assembler magic.
505  */
506 .data
507 ENTRY(interrupt)
508 .previous
509
510 vector=0
511 ENTRY(irq_entries_start)
512 .rept NR_IRQS
513         ALIGN
514 1:      pushl $vector-256
515         jmp common_interrupt
516 .data
517         .long 1b
518 .previous
519 vector=vector+1
520 .endr
521
522         ALIGN
523 common_interrupt:
524         SAVE_ALL
525         call do_IRQ
526         jmp ret_from_intr
527
528 #define BUILD_INTERRUPT(name, nr)       \
529 ENTRY(name)                             \
530         pushl $nr-256;                  \
531         SAVE_ALL                        \
532         call smp_/**/name;      \
533         jmp ret_from_intr;
534
535 /* The include is where all of the SMP etc. interrupts come from */
536 #include "entry_arch.h"
537
538 ENTRY(divide_error)
539         pushl $0                        # no error code
540         pushl $do_divide_error
541         ALIGN
542 error_code:
543         pushl %ds
544         pushl %eax
545         xorl %eax, %eax
546         pushl %ebp
547         pushl %edi
548         pushl %esi
549         pushl %edx
550         decl %eax                       # eax = -1
551         pushl %ecx
552         pushl %ebx
553         cld
554         movl %es, %ecx
555         movl ORIG_EAX(%esp), %esi       # get the error code
556         movl ES(%esp), %edi             # get the function address
557         movl %eax, ORIG_EAX(%esp)
558         movl %ecx, ES(%esp)
559         pushl %esi                      # push the error code
560         movl $(__USER_DS), %edx
561         movl %edx, %ds
562         movl %edx, %es
563
564 /* clobbers edx, ebx and ebp */
565         __SWITCH_KERNELSPACE
566
567         leal 4(%esp), %edx              # prepare pt_regs
568         pushl %edx                      # push pt_regs
569
570         call *%edi
571         addl $8, %esp
572         jmp ret_from_exception
573
574 ENTRY(coprocessor_error)
575         pushl $0
576         pushl $do_coprocessor_error
577         jmp error_code
578
579 ENTRY(simd_coprocessor_error)
580         pushl $0
581         pushl $do_simd_coprocessor_error
582         jmp error_code
583
584 ENTRY(device_not_available)
585         pushl $-1                       # mark this as an int
586         SAVE_ALL
587         movl %cr0, %eax
588         testl $0x4, %eax                # EM (math emulation bit)
589         jne device_not_available_emulate
590         preempt_stop
591         call math_state_restore
592         jmp ret_from_exception
593 device_not_available_emulate:
594         pushl $0                        # temporary storage for ORIG_EIP
595         call math_emulate
596         addl $4, %esp
597         jmp ret_from_exception
598
599 /*
600  * Debug traps and NMI can happen at the one SYSENTER instruction
601  * that sets up the real kernel stack. Check here, since we can't
602  * allow the wrong stack to be used.
603  *
604  * "TSS_sysenter_esp0+12" is because the NMI/debug handler will have
605  * already pushed 3 words if it hits on the sysenter instruction:
606  * eflags, cs and eip.
607  *
608  * We just load the right stack, and push the three (known) values
609  * by hand onto the new stack - while updating the return eip past
610  * the instruction that would have done it for sysenter.
611  */
612 #define FIX_STACK(offset, ok, label)            \
613         cmpw $__KERNEL_CS,4(%esp);              \
614         jne ok;                                 \
615 label:                                          \
616         movl TSS_sysenter_esp0+offset(%esp),%esp;       \
617         pushfl;                                 \
618         pushl $__KERNEL_CS;                     \
619         pushl $sysenter_past_esp
620
621 ENTRY(debug)
622         cmpl $sysenter_entry,(%esp)
623         jne debug_stack_correct
624         FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn)
625 debug_stack_correct:
626         pushl $0
627         pushl $do_debug
628         jmp error_code
629
630 /*
631  * NMI is doubly nasty. It can happen _while_ we're handling
632  * a debug fault, and the debug fault hasn't yet been able to
633  * clear up the stack. So we first check whether we got  an
634  * NMI on the sysenter entry path, but after that we need to
635  * check whether we got an NMI on the debug path where the debug
636  * fault happened on the sysenter path.
637  */
638 ENTRY(nmi)
639         cmpl $sysenter_entry,(%esp)
640         je nmi_stack_fixup
641         pushl %eax
642         movl %esp,%eax
643         /* Do not access memory above the end of our stack page,
644          * it might not exist.
645          */
646         andl $(THREAD_SIZE-1),%eax
647         cmpl $(THREAD_SIZE-20),%eax
648         popl %eax
649         jae nmi_stack_correct
650         cmpl $sysenter_entry,12(%esp)
651         je nmi_debug_stack_check
652 nmi_stack_correct:
653         pushl %eax
654         SAVE_ALL
655         movl %esp, %edx
656         pushl $0
657         pushl %edx
658         call do_nmi
659         addl $8, %esp
660         jmp restore_all
661
662 nmi_stack_fixup:
663         FIX_STACK(12,nmi_stack_correct, 1)
664         jmp nmi_stack_correct
665 nmi_debug_stack_check:
666         cmpw $__KERNEL_CS,16(%esp)
667         jne nmi_stack_correct
668         cmpl $debug - 1,(%esp)
669         jle nmi_stack_correct
670         cmpl $debug_esp_fix_insn,(%esp)
671         jle nmi_debug_stack_fixup
672 nmi_debug_stack_fixup:
673         FIX_STACK(24,nmi_stack_correct, 1)
674         jmp nmi_stack_correct
675
676 ENTRY(int3)
677         pushl $0
678         pushl $do_int3
679         jmp error_code
680
681 ENTRY(overflow)
682         pushl $0
683         pushl $do_overflow
684         jmp error_code
685
686 ENTRY(bounds)
687         pushl $0
688         pushl $do_bounds
689         jmp error_code
690
691 ENTRY(invalid_op)
692         pushl $0
693         pushl $do_invalid_op
694         jmp error_code
695
696 ENTRY(coprocessor_segment_overrun)
697         pushl $0
698         pushl $do_coprocessor_segment_overrun
699         jmp error_code
700
701 ENTRY(invalid_TSS)
702         pushl $do_invalid_TSS
703         jmp error_code
704
705 ENTRY(segment_not_present)
706         pushl $do_segment_not_present
707         jmp error_code
708
709 ENTRY(stack_segment)
710         pushl $do_stack_segment
711         jmp error_code
712
713 ENTRY(general_protection)
714         pushl $do_general_protection
715         jmp error_code
716
717 ENTRY(alignment_check)
718         pushl $do_alignment_check
719         jmp error_code
720
721 ENTRY(page_fault)
722         pushl $do_page_fault
723         jmp error_code
724
725 #ifdef CONFIG_X86_MCE
726 ENTRY(machine_check)
727         pushl $0
728         pushl machine_check_vector
729         jmp error_code
730 #endif
731
732 ENTRY(spurious_interrupt_bug)
733         pushl $0
734         pushl $do_spurious_interrupt_bug
735         jmp error_code
736
737 #ifdef CONFIG_X86_STACK_CHECK
738 ENTRY(mcount)
739         push %eax
740         movl $(THREAD_SIZE - 1),%eax
741         andl %esp,%eax
742         cmpl $STACK_WARN,%eax /* esp reaches into STACK_WARN space */
743         jle 1f
744 2:
745         popl %eax
746         ret
747 1:
748         lock; btsl $0,stack_overflowed
749         jc 2b
750
751         # switch to overflow stack
752         movl %esp,%eax
753         movl $(stack_overflow_stack + THREAD_SIZE - 4),%esp
754         
755         pushf
756         cli
757         pushl %eax
758
759         # push eip then esp of error for stack_overflow_panic
760         pushl 4(%eax)
761         pushl %eax
762
763         # update the task pointer and cpu in the overflow stack's thread_info.
764         GET_THREAD_INFO_WITH_ESP(%eax)
765         movl TI_task(%eax),%ebx
766         movl %ebx,stack_overflow_stack+TI_task
767         movl TI_cpu(%eax),%ebx
768         movl %ebx,stack_overflow_stack+TI_cpu
769
770         call stack_overflow
771
772         # pop off call arguments
773         addl $8,%esp
774
775         popl %eax
776         popf
777         movl %eax,%esp
778         popl %eax
779         movl $0,stack_overflowed
780         ret
781 #warning stack check enabled
782 #endif
783
784 .previous
785
786 .data
787 #ifdef CONFIG_X86_STACK_CHECK
788         .globl stack_overflowed
789 stack_overflowed:
790         .long 0
791 #endif
792
793 ENTRY(sys_call_table)
794         .long sys_restart_syscall       /* 0 - old "setup()" system call, used for restarting */
795         .long sys_exit
796         .long sys_fork
797         .long sys_read
798         .long sys_write
799         .long sys_open          /* 5 */
800         .long sys_close
801         .long sys_waitpid
802         .long sys_creat
803         .long sys_link
804         .long sys_unlink        /* 10 */
805         .long sys_execve
806         .long sys_chdir
807         .long sys_time
808         .long sys_mknod
809         .long sys_chmod         /* 15 */
810         .long sys_lchown16
811         .long sys_ni_syscall    /* old break syscall holder */
812         .long sys_stat
813         .long sys_lseek
814         .long sys_getpid        /* 20 */
815         .long sys_mount
816         .long sys_oldumount
817         .long sys_setuid16
818         .long sys_getuid16
819         .long sys_stime         /* 25 */
820         .long sys_ptrace
821         .long sys_alarm
822         .long sys_fstat
823         .long sys_pause
824         .long sys_utime         /* 30 */
825         .long sys_ni_syscall    /* old stty syscall holder */
826         .long sys_ni_syscall    /* old gtty syscall holder */
827         .long sys_access
828         .long sys_nice
829         .long sys_ni_syscall    /* 35 - old ftime syscall holder */
830         .long sys_sync
831         .long sys_kill
832         .long sys_rename
833         .long sys_mkdir
834         .long sys_rmdir         /* 40 */
835         .long sys_dup
836         .long sys_pipe
837         .long sys_times
838         .long sys_ni_syscall    /* old prof syscall holder */
839         .long sys_brk           /* 45 */
840         .long sys_setgid16
841         .long sys_getgid16
842         .long sys_signal
843         .long sys_geteuid16
844         .long sys_getegid16     /* 50 */
845         .long sys_acct
846         .long sys_umount        /* recycled never used phys() */
847         .long sys_ni_syscall    /* old lock syscall holder */
848         .long sys_ioctl
849         .long sys_fcntl         /* 55 */
850         .long sys_ni_syscall    /* old mpx syscall holder */
851         .long sys_setpgid
852         .long sys_ni_syscall    /* old ulimit syscall holder */
853         .long sys_olduname
854         .long sys_umask         /* 60 */
855         .long sys_chroot
856         .long sys_ustat
857         .long sys_dup2
858         .long sys_getppid
859         .long sys_getpgrp       /* 65 */
860         .long sys_setsid
861         .long sys_sigaction
862         .long sys_sgetmask
863         .long sys_ssetmask
864         .long sys_setreuid16    /* 70 */
865         .long sys_setregid16
866         .long sys_sigsuspend
867         .long sys_sigpending
868         .long sys_sethostname
869         .long sys_setrlimit     /* 75 */
870         .long sys_old_getrlimit
871         .long sys_getrusage
872         .long sys_gettimeofday
873         .long sys_settimeofday
874         .long sys_getgroups16   /* 80 */
875         .long sys_setgroups16
876         .long old_select
877         .long sys_symlink
878         .long sys_lstat
879         .long sys_readlink      /* 85 */
880         .long sys_uselib
881         .long sys_swapon
882         .long sys_reboot
883         .long old_readdir
884         .long old_mmap          /* 90 */
885         .long sys_munmap
886         .long sys_truncate
887         .long sys_ftruncate
888         .long sys_fchmod
889         .long sys_fchown16      /* 95 */
890         .long sys_getpriority
891         .long sys_setpriority
892         .long sys_ni_syscall    /* old profil syscall holder */
893         .long sys_statfs
894         .long sys_fstatfs       /* 100 */
895         .long sys_ioperm
896         .long sys_socketcall
897         .long sys_syslog
898         .long sys_setitimer
899         .long sys_getitimer     /* 105 */
900         .long sys_newstat
901         .long sys_newlstat
902         .long sys_newfstat
903         .long sys_uname
904         .long sys_iopl          /* 110 */
905         .long sys_vhangup
906         .long sys_ni_syscall    /* old "idle" system call */
907         .long sys_vm86old
908         .long sys_wait4
909         .long sys_swapoff       /* 115 */
910         .long sys_sysinfo
911         .long sys_ipc
912         .long sys_fsync
913         .long sys_sigreturn
914         .long sys_clone         /* 120 */
915         .long sys_setdomainname
916         .long sys_newuname
917         .long sys_modify_ldt
918         .long sys_adjtimex
919         .long sys_mprotect      /* 125 */
920         .long sys_sigprocmask
921         .long sys_ni_syscall    /* old "create_module" */ 
922         .long sys_init_module
923         .long sys_delete_module
924         .long sys_ni_syscall    /* 130: old "get_kernel_syms" */
925         .long sys_quotactl
926         .long sys_getpgid
927         .long sys_fchdir
928         .long sys_bdflush
929         .long sys_sysfs         /* 135 */
930         .long sys_personality
931         .long sys_ni_syscall    /* reserved for afs_syscall */
932         .long sys_setfsuid16
933         .long sys_setfsgid16
934         .long sys_llseek        /* 140 */
935         .long sys_getdents
936         .long sys_select
937         .long sys_flock
938         .long sys_msync
939         .long sys_readv         /* 145 */
940         .long sys_writev
941         .long sys_getsid
942         .long sys_fdatasync
943         .long sys_sysctl
944         .long sys_mlock         /* 150 */
945         .long sys_munlock
946         .long sys_mlockall
947         .long sys_munlockall
948         .long sys_sched_setparam
949         .long sys_sched_getparam   /* 155 */
950         .long sys_sched_setscheduler
951         .long sys_sched_getscheduler
952         .long sys_sched_yield
953         .long sys_sched_get_priority_max
954         .long sys_sched_get_priority_min  /* 160 */
955         .long sys_sched_rr_get_interval
956         .long sys_nanosleep
957         .long sys_mremap
958         .long sys_setresuid16
959         .long sys_getresuid16   /* 165 */
960         .long sys_vm86
961         .long sys_ni_syscall    /* Old sys_query_module */
962         .long sys_poll
963         .long sys_nfsservctl
964         .long sys_setresgid16   /* 170 */
965         .long sys_getresgid16
966         .long sys_prctl
967         .long sys_rt_sigreturn
968         .long sys_rt_sigaction
969         .long sys_rt_sigprocmask        /* 175 */
970         .long sys_rt_sigpending
971         .long sys_rt_sigtimedwait
972         .long sys_rt_sigqueueinfo
973         .long sys_rt_sigsuspend
974         .long sys_pread64       /* 180 */
975         .long sys_pwrite64
976         .long sys_chown16
977         .long sys_getcwd
978         .long sys_capget
979         .long sys_capset        /* 185 */
980         .long sys_sigaltstack
981         .long sys_sendfile
982         .long sys_ni_syscall    /* reserved for streams1 */
983         .long sys_ni_syscall    /* reserved for streams2 */
984         .long sys_vfork         /* 190 */
985         .long sys_getrlimit
986         .long sys_mmap2
987         .long sys_truncate64
988         .long sys_ftruncate64
989         .long sys_stat64        /* 195 */
990         .long sys_lstat64
991         .long sys_fstat64
992         .long sys_lchown
993         .long sys_getuid
994         .long sys_getgid        /* 200 */
995         .long sys_geteuid
996         .long sys_getegid
997         .long sys_setreuid
998         .long sys_setregid
999         .long sys_getgroups     /* 205 */
1000         .long sys_setgroups
1001         .long sys_fchown
1002         .long sys_setresuid
1003         .long sys_getresuid
1004         .long sys_setresgid     /* 210 */
1005         .long sys_getresgid
1006         .long sys_chown
1007         .long sys_setuid
1008         .long sys_setgid
1009         .long sys_setfsuid      /* 215 */
1010         .long sys_setfsgid
1011         .long sys_pivot_root
1012         .long sys_mincore
1013         .long sys_madvise
1014         .long sys_getdents64    /* 220 */
1015         .long sys_fcntl64
1016 #ifdef CONFIG_TUX
1017         .long __sys_tux
1018 #else
1019 # ifdef CONFIG_TUX_MODULE
1020         .long sys_tux
1021 # else
1022         .long sys_ni_syscall
1023 # endif
1024 #endif
1025         .long sys_ni_syscall
1026         .long sys_gettid
1027         .long sys_readahead     /* 225 */
1028         .long sys_setxattr
1029         .long sys_lsetxattr
1030         .long sys_fsetxattr
1031         .long sys_getxattr
1032         .long sys_lgetxattr     /* 230 */
1033         .long sys_fgetxattr
1034         .long sys_listxattr
1035         .long sys_llistxattr
1036         .long sys_flistxattr
1037         .long sys_removexattr   /* 235 */
1038         .long sys_lremovexattr
1039         .long sys_fremovexattr
1040         .long sys_tkill
1041         .long sys_sendfile64
1042         .long sys_futex         /* 240 */
1043         .long sys_sched_setaffinity
1044         .long sys_sched_getaffinity
1045         .long sys_set_thread_area
1046         .long sys_get_thread_area
1047         .long sys_io_setup      /* 245 */
1048         .long sys_io_destroy
1049         .long sys_io_getevents
1050         .long sys_io_submit
1051         .long sys_io_cancel
1052         .long sys_fadvise64     /* 250 */
1053         .long sys_ni_syscall
1054         .long sys_exit_group
1055         .long sys_lookup_dcookie
1056         .long sys_epoll_create
1057         .long sys_epoll_ctl     /* 255 */
1058         .long sys_epoll_wait
1059         .long sys_remap_file_pages
1060         .long sys_set_tid_address
1061         .long sys_timer_create
1062         .long sys_timer_settime         /* 260 */
1063         .long sys_timer_gettime
1064         .long sys_timer_getoverrun
1065         .long sys_timer_delete
1066         .long sys_clock_settime
1067         .long sys_clock_gettime         /* 265 */
1068         .long sys_clock_getres
1069         .long sys_clock_nanosleep
1070         .long sys_statfs64
1071         .long sys_fstatfs64     
1072         .long sys_tgkill        /* 270 */
1073         .long sys_utimes
1074         .long sys_fadvise64_64
1075         .long sys_vserver
1076         .long sys_mbind
1077         .long sys_get_mempolicy
1078         .long sys_set_mempolicy
1079         .long sys_mq_open
1080         .long sys_mq_unlink
1081         .long sys_mq_timedsend
1082         .long sys_mq_timedreceive       /* 280 */
1083         .long sys_mq_notify
1084         .long sys_mq_getsetattr
1085         .long sys_ni_syscall            /* reserved for kexec */
1086         .long sys_ioprio_set
1087         .long sys_ioprio_get            /* 285 */
1088
1089 syscall_table_size=(.-sys_call_table)