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