Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / arch / i386 / kernel / entry-xen.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/linkage.h>
44 #include <asm/thread_info.h>
45 #include <asm/irqflags.h>
46 #include <asm/errno.h>
47 #include <asm/segment.h>
48 #include <asm/smp.h>
49 #include <asm/page.h>
50 #include <asm/desc.h>
51 #include <asm/dwarf2.h>
52 #include "irq_vectors.h"
53 #include <xen/interface/xen.h>
54
55 #define nr_syscalls ((syscall_table_size)/4)
56
57 EBX             = 0x00
58 ECX             = 0x04
59 EDX             = 0x08
60 ESI             = 0x0C
61 EDI             = 0x10
62 EBP             = 0x14
63 EAX             = 0x18
64 DS              = 0x1C
65 ES              = 0x20
66 ORIG_EAX        = 0x24
67 EIP             = 0x28
68 CS              = 0x2C
69 EFLAGS          = 0x30
70 OLDESP          = 0x34
71 OLDSS           = 0x38
72
73 CF_MASK         = 0x00000001
74 TF_MASK         = 0x00000100
75 IF_MASK         = 0x00000200
76 DF_MASK         = 0x00000400 
77 NT_MASK         = 0x00004000
78 VM_MASK         = 0x00020000
79 /* Pseudo-eflags. */
80 NMI_MASK        = 0x80000000
81
82 #ifndef CONFIG_XEN
83 #define DISABLE_INTERRUPTS      cli
84 #define ENABLE_INTERRUPTS       sti
85 #else
86 /* Offsets into shared_info_t. */
87 #define evtchn_upcall_pending           /* 0 */
88 #define evtchn_upcall_mask              1
89
90 #define sizeof_vcpu_shift               6
91
92 #ifdef CONFIG_SMP
93 #define GET_VCPU_INFO           movl TI_cpu(%ebp),%esi                  ; \
94                                 shl  $sizeof_vcpu_shift,%esi            ; \
95                                 addl HYPERVISOR_shared_info,%esi
96 #else
97 #define GET_VCPU_INFO           movl HYPERVISOR_shared_info,%esi
98 #endif
99
100 #define __DISABLE_INTERRUPTS    movb $1,evtchn_upcall_mask(%esi)
101 #define __ENABLE_INTERRUPTS     movb $0,evtchn_upcall_mask(%esi)
102 #define DISABLE_INTERRUPTS      GET_VCPU_INFO                           ; \
103                                 __DISABLE_INTERRUPTS
104 #define ENABLE_INTERRUPTS       GET_VCPU_INFO                           ; \
105                                 __ENABLE_INTERRUPTS
106 #define __TEST_PENDING          testb $0xFF,evtchn_upcall_pending(%esi)
107 #endif
108
109 #ifdef CONFIG_PREEMPT
110 #define preempt_stop            cli; TRACE_IRQS_OFF
111 #else
112 #define preempt_stop
113 #define resume_kernel           restore_nocheck
114 #endif
115
116 .macro TRACE_IRQS_IRET
117 #ifdef CONFIG_TRACE_IRQFLAGS
118         testl $IF_MASK,EFLAGS(%esp)     # interrupts off?
119         jz 1f
120         TRACE_IRQS_ON
121 1:
122 #endif
123 .endm
124
125 #ifdef CONFIG_VM86
126 #define resume_userspace_sig    check_userspace
127 #else
128 #define resume_userspace_sig    resume_userspace
129 #endif
130
131 #define SAVE_ALL \
132         cld; \
133         pushl %es; \
134         CFI_ADJUST_CFA_OFFSET 4;\
135         /*CFI_REL_OFFSET es, 0;*/\
136         pushl %ds; \
137         CFI_ADJUST_CFA_OFFSET 4;\
138         /*CFI_REL_OFFSET ds, 0;*/\
139         pushl %eax; \
140         CFI_ADJUST_CFA_OFFSET 4;\
141         CFI_REL_OFFSET eax, 0;\
142         pushl %ebp; \
143         CFI_ADJUST_CFA_OFFSET 4;\
144         CFI_REL_OFFSET ebp, 0;\
145         pushl %edi; \
146         CFI_ADJUST_CFA_OFFSET 4;\
147         CFI_REL_OFFSET edi, 0;\
148         pushl %esi; \
149         CFI_ADJUST_CFA_OFFSET 4;\
150         CFI_REL_OFFSET esi, 0;\
151         pushl %edx; \
152         CFI_ADJUST_CFA_OFFSET 4;\
153         CFI_REL_OFFSET edx, 0;\
154         pushl %ecx; \
155         CFI_ADJUST_CFA_OFFSET 4;\
156         CFI_REL_OFFSET ecx, 0;\
157         pushl %ebx; \
158         CFI_ADJUST_CFA_OFFSET 4;\
159         CFI_REL_OFFSET ebx, 0;\
160         movl $(__USER_DS), %edx; \
161         movl %edx, %ds; \
162         movl %edx, %es;
163
164 #define RESTORE_INT_REGS \
165         popl %ebx;      \
166         CFI_ADJUST_CFA_OFFSET -4;\
167         CFI_RESTORE ebx;\
168         popl %ecx;      \
169         CFI_ADJUST_CFA_OFFSET -4;\
170         CFI_RESTORE ecx;\
171         popl %edx;      \
172         CFI_ADJUST_CFA_OFFSET -4;\
173         CFI_RESTORE edx;\
174         popl %esi;      \
175         CFI_ADJUST_CFA_OFFSET -4;\
176         CFI_RESTORE esi;\
177         popl %edi;      \
178         CFI_ADJUST_CFA_OFFSET -4;\
179         CFI_RESTORE edi;\
180         popl %ebp;      \
181         CFI_ADJUST_CFA_OFFSET -4;\
182         CFI_RESTORE ebp;\
183         popl %eax;      \
184         CFI_ADJUST_CFA_OFFSET -4;\
185         CFI_RESTORE eax
186
187 #define RESTORE_REGS    \
188         RESTORE_INT_REGS; \
189 1:      popl %ds;       \
190         CFI_ADJUST_CFA_OFFSET -4;\
191         /*CFI_RESTORE ds;*/\
192 2:      popl %es;       \
193         CFI_ADJUST_CFA_OFFSET -4;\
194         /*CFI_RESTORE es;*/\
195 .section .fixup,"ax";   \
196 3:      movl $0,(%esp); \
197         jmp 1b;         \
198 4:      movl $0,(%esp); \
199         jmp 2b;         \
200 .previous;              \
201 .section __ex_table,"a";\
202         .align 4;       \
203         .long 1b,3b;    \
204         .long 2b,4b;    \
205 .previous
206
207 #define RING0_INT_FRAME \
208         CFI_STARTPROC simple;\
209         CFI_DEF_CFA esp, 3*4;\
210         /*CFI_OFFSET cs, -2*4;*/\
211         CFI_OFFSET eip, -3*4
212
213 #define RING0_EC_FRAME \
214         CFI_STARTPROC simple;\
215         CFI_DEF_CFA esp, 4*4;\
216         /*CFI_OFFSET cs, -2*4;*/\
217         CFI_OFFSET eip, -3*4
218
219 #define RING0_PTREGS_FRAME \
220         CFI_STARTPROC simple;\
221         CFI_DEF_CFA esp, OLDESP-EBX;\
222         /*CFI_OFFSET cs, CS-OLDESP;*/\
223         CFI_OFFSET eip, EIP-OLDESP;\
224         /*CFI_OFFSET es, ES-OLDESP;*/\
225         /*CFI_OFFSET ds, DS-OLDESP;*/\
226         CFI_OFFSET eax, EAX-OLDESP;\
227         CFI_OFFSET ebp, EBP-OLDESP;\
228         CFI_OFFSET edi, EDI-OLDESP;\
229         CFI_OFFSET esi, ESI-OLDESP;\
230         CFI_OFFSET edx, EDX-OLDESP;\
231         CFI_OFFSET ecx, ECX-OLDESP;\
232         CFI_OFFSET ebx, EBX-OLDESP
233
234 ENTRY(ret_from_fork)
235         CFI_STARTPROC
236         pushl %eax
237         CFI_ADJUST_CFA_OFFSET 4
238         call schedule_tail
239         GET_THREAD_INFO(%ebp)
240         popl %eax
241         CFI_ADJUST_CFA_OFFSET -4
242         pushl $0x0202                   # Reset kernel eflags
243         CFI_ADJUST_CFA_OFFSET 4
244         popfl
245         CFI_ADJUST_CFA_OFFSET -4
246         jmp syscall_exit
247         CFI_ENDPROC
248
249 /*
250  * Return to user mode is not as complex as all this looks,
251  * but we want the default path for a system call return to
252  * go as quickly as possible which is why some of this is
253  * less clear than it otherwise should be.
254  */
255
256         # userspace resumption stub bypassing syscall exit tracing
257         ALIGN
258         RING0_PTREGS_FRAME
259 ret_from_exception:
260         preempt_stop
261 ret_from_intr:
262         GET_THREAD_INFO(%ebp)
263 check_userspace:
264         movl EFLAGS(%esp), %eax         # mix EFLAGS and CS
265         movb CS(%esp), %al
266         testl $(VM_MASK | 2), %eax
267         jz resume_kernel
268 ENTRY(resume_userspace)
269         DISABLE_INTERRUPTS              # make sure we don't miss an interrupt
270                                         # setting need_resched or sigpending
271                                         # between sampling and the iret
272         movl TI_flags(%ebp), %ecx
273         andl $_TIF_WORK_MASK, %ecx      # is there any work to be done on
274                                         # int/exception return?
275         jne work_pending
276         jmp restore_all
277
278 #ifdef CONFIG_PREEMPT
279 ENTRY(resume_kernel)
280         cli
281         cmpl $0,TI_preempt_count(%ebp)  # non-zero preempt_count ?
282         jnz restore_nocheck
283 need_resched:
284         movl TI_flags(%ebp), %ecx       # need_resched set ?
285         testb $_TIF_NEED_RESCHED, %cl
286         jz restore_all
287         testl $IF_MASK,EFLAGS(%esp)     # interrupts off (exception path) ?
288         jz restore_all
289         call preempt_schedule_irq
290         jmp need_resched
291 #endif
292         CFI_ENDPROC
293
294 /* SYSENTER_RETURN points to after the "sysenter" instruction in
295    the vsyscall page.  See vsyscall-sysentry.S, which defines the symbol.  */
296
297         # sysenter call handler stub
298 ENTRY(sysenter_entry)
299         CFI_STARTPROC simple
300         CFI_DEF_CFA esp, 0
301         CFI_REGISTER esp, ebp
302         movl SYSENTER_stack_esp0(%esp),%esp
303 sysenter_past_esp:
304         /*
305          * No need to follow this irqs on/off section: the syscall
306          * disabled irqs and here we enable it straight after entry:
307          */
308         sti
309         pushl $(__USER_DS)
310         CFI_ADJUST_CFA_OFFSET 4
311         /*CFI_REL_OFFSET ss, 0*/
312         pushl %ebp
313         CFI_ADJUST_CFA_OFFSET 4
314         CFI_REL_OFFSET esp, 0
315         pushfl
316         CFI_ADJUST_CFA_OFFSET 4
317         pushl $(__USER_CS)
318         CFI_ADJUST_CFA_OFFSET 4
319         /*CFI_REL_OFFSET cs, 0*/
320         /*
321          * Push current_thread_info()->sysenter_return to the stack.
322          * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
323          * pushed above; +8 corresponds to copy_thread's esp0 setting.
324          */
325         pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
326         CFI_ADJUST_CFA_OFFSET 4
327         CFI_REL_OFFSET eip, 0
328
329 /*
330  * Load the potential sixth argument from user stack.
331  * Careful about security.
332  */
333         cmpl $__PAGE_OFFSET-3,%ebp
334         jae syscall_fault
335 1:      movl (%ebp),%ebp
336 .section __ex_table,"a"
337         .align 4
338         .long 1b,syscall_fault
339 .previous
340
341         pushl %eax
342         CFI_ADJUST_CFA_OFFSET 4
343         SAVE_ALL
344         GET_THREAD_INFO(%ebp)
345
346         /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
347         testw $(_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
348         jnz syscall_trace_entry
349         cmpl $(nr_syscalls), %eax
350         jae syscall_badsys
351         call *sys_call_table(,%eax,4)
352         movl %eax,EAX(%esp)
353         DISABLE_INTERRUPTS
354         TRACE_IRQS_OFF
355         movl TI_flags(%ebp), %ecx
356         testw $_TIF_ALLWORK_MASK, %cx
357         jne syscall_exit_work
358 /* if something modifies registers it must also disable sysexit */
359         movl EIP(%esp), %edx
360         movl OLDESP(%esp), %ecx
361         xorl %ebp,%ebp
362         TRACE_IRQS_ON
363 #ifdef CONFIG_XEN
364         __ENABLE_INTERRUPTS
365 sysexit_scrit:  /**** START OF SYSEXIT CRITICAL REGION ****/
366         __TEST_PENDING
367         jnz  14f                        # process more events if necessary...
368         movl ESI(%esp), %esi
369         sysexit
370 14:     __DISABLE_INTERRUPTS
371 sysexit_ecrit:  /**** END OF SYSEXIT CRITICAL REGION ****/
372         push %esp
373         CFI_ADJUST_CFA_OFFSET 4
374         call evtchn_do_upcall
375         add  $4,%esp
376         CFI_ADJUST_CFA_OFFSET -4
377         jmp  ret_from_intr
378 #else
379         sti
380         sysexit
381 #endif /* !CONFIG_XEN */
382         CFI_ENDPROC
383
384
385         # system call handler stub
386 ENTRY(system_call)
387         RING0_INT_FRAME                 # can't unwind into user space anyway
388         pushl %eax                      # save orig_eax
389         CFI_ADJUST_CFA_OFFSET 4
390         SAVE_ALL
391         GET_THREAD_INFO(%ebp)
392         testl $TF_MASK,EFLAGS(%esp)
393         jz no_singlestep
394         orl $_TIF_SINGLESTEP,TI_flags(%ebp)
395 no_singlestep:
396                                         # system call tracing in operation / emulation
397         /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
398         testw $(_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
399         jnz syscall_trace_entry
400         cmpl $(nr_syscalls), %eax
401         jae syscall_badsys
402 syscall_call:
403         call *sys_call_table(,%eax,4)
404         movl %eax,EAX(%esp)             # store the return value
405 syscall_exit:
406         DISABLE_INTERRUPTS              # make sure we don't miss an interrupt
407                                         # setting need_resched or sigpending
408                                         # between sampling and the iret
409         TRACE_IRQS_OFF
410         movl TI_flags(%ebp), %ecx
411         testw $_TIF_ALLWORK_MASK, %cx   # current->work
412         jne syscall_exit_work
413
414 restore_all:
415 #ifndef CONFIG_XEN
416         movl EFLAGS(%esp), %eax         # mix EFLAGS, SS and CS
417         # Warning: OLDSS(%esp) contains the wrong/random values if we
418         # are returning to the kernel.
419         # See comments in process.c:copy_thread() for details.
420         movb OLDSS(%esp), %ah
421         movb CS(%esp), %al
422         andl $(VM_MASK | (4 << 8) | 3), %eax
423         cmpl $((4 << 8) | 3), %eax
424         je ldt_ss                       # returning to user-space with LDT SS
425 restore_nocheck:
426 #else
427 restore_nocheck:
428         movl EFLAGS(%esp), %eax
429         testl $(VM_MASK|NMI_MASK), %eax
430         jnz hypervisor_iret
431         shr $9, %eax                    # EAX[0] == IRET_EFLAGS.IF
432         GET_VCPU_INFO
433         andb evtchn_upcall_mask(%esi),%al
434         andb $1,%al                     # EAX[0] == IRET_EFLAGS.IF & event_mask
435         jnz restore_all_enable_events   #        != 0 => enable event delivery
436 #endif
437         TRACE_IRQS_IRET
438         CFI_REMEMBER_STATE
439 restore_nocheck_notrace:
440         RESTORE_REGS
441         addl $4, %esp
442         CFI_ADJUST_CFA_OFFSET -4
443 1:      iret
444 .section .fixup,"ax"
445 iret_exc:
446 #ifndef CONFIG_XEN
447         TRACE_IRQS_ON
448         sti
449 #endif
450         pushl $0                        # no error code
451         pushl $do_iret_error
452         jmp error_code
453 .previous
454 .section __ex_table,"a"
455         .align 4
456         .long 1b,iret_exc
457 .previous
458
459         CFI_RESTORE_STATE
460 #ifndef CONFIG_XEN
461 ldt_ss:
462         larl OLDSS(%esp), %eax
463         jnz restore_nocheck
464         testl $0x00400000, %eax         # returning to 32bit stack?
465         jnz restore_nocheck             # allright, normal return
466         /* If returning to userspace with 16bit stack,
467          * try to fix the higher word of ESP, as the CPU
468          * won't restore it.
469          * This is an "official" bug of all the x86-compatible
470          * CPUs, which we can try to work around to make
471          * dosemu and wine happy. */
472         subl $8, %esp           # reserve space for switch16 pointer
473         CFI_ADJUST_CFA_OFFSET 8
474         cli
475         TRACE_IRQS_OFF
476         movl %esp, %eax
477         /* Set up the 16bit stack frame with switch32 pointer on top,
478          * and a switch16 pointer on top of the current frame. */
479         call setup_x86_bogus_stack
480         CFI_ADJUST_CFA_OFFSET -8        # frame has moved
481         TRACE_IRQS_IRET
482         RESTORE_REGS
483         lss 20+4(%esp), %esp    # switch to 16bit stack
484 1:      iret
485 .section __ex_table,"a"
486         .align 4
487         .long 1b,iret_exc
488 .previous
489 #else
490 hypervisor_iret:
491         andl $~NMI_MASK, EFLAGS(%esp)
492         RESTORE_REGS
493         addl $4, %esp
494         jmp  hypercall_page + (__HYPERVISOR_iret * 32)
495 #endif
496         CFI_ENDPROC
497
498         # perform work that needs to be done immediately before resumption
499         ALIGN
500         RING0_PTREGS_FRAME              # can't unwind into user space anyway
501 work_pending:
502         testb $_TIF_NEED_RESCHED, %cl
503         jz work_notifysig
504 work_resched:
505         call schedule
506         DISABLE_INTERRUPTS              # make sure we don't miss an interrupt
507                                         # setting need_resched or sigpending
508                                         # between sampling and the iret
509         TRACE_IRQS_OFF
510         movl TI_flags(%ebp), %ecx
511         andl $_TIF_WORK_MASK, %ecx      # is there any work to be done other
512                                         # than syscall tracing?
513         jz restore_all
514         testb $_TIF_NEED_RESCHED, %cl
515         jnz work_resched
516
517 work_notifysig:                         # deal with pending signals and
518                                         # notify-resume requests
519         testl $VM_MASK, EFLAGS(%esp)
520         movl %esp, %eax
521         jne work_notifysig_v86          # returning to kernel-space or
522                                         # vm86-space
523         xorl %edx, %edx
524         call do_notify_resume
525         jmp resume_userspace_sig
526
527         ALIGN
528 work_notifysig_v86:
529 #ifdef CONFIG_VM86
530         pushl %ecx                      # save ti_flags for do_notify_resume
531         CFI_ADJUST_CFA_OFFSET 4
532         call save_v86_state             # %eax contains pt_regs pointer
533         popl %ecx
534         CFI_ADJUST_CFA_OFFSET -4
535         movl %eax, %esp
536         xorl %edx, %edx
537         call do_notify_resume
538         jmp resume_userspace_sig
539 #endif
540
541         # perform syscall exit tracing
542         ALIGN
543 syscall_trace_entry:
544         movl $-ENOSYS,EAX(%esp)
545         movl %esp, %eax
546         xorl %edx,%edx
547         call do_syscall_trace
548         movl ORIG_EAX(%esp), %eax
549         cmpl $(nr_syscalls), %eax
550         jnae syscall_call
551         jmp syscall_exit
552
553         # perform syscall exit tracing
554         ALIGN
555 syscall_exit_work:
556         testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP), %cl
557         jz work_pending
558         TRACE_IRQS_ON
559         ENABLE_INTERRUPTS               # could let do_syscall_trace() call
560                                         # schedule() instead
561         movl %esp, %eax
562         movl $1, %edx
563         call do_syscall_trace
564         jmp resume_userspace
565         CFI_ENDPROC
566
567         RING0_INT_FRAME                 # can't unwind into user space anyway
568 syscall_fault:
569         pushl %eax                      # save orig_eax
570         CFI_ADJUST_CFA_OFFSET 4
571         SAVE_ALL
572         GET_THREAD_INFO(%ebp)
573         movl $-EFAULT,EAX(%esp)
574         jmp resume_userspace
575
576 syscall_badsys:
577         movl $-ENOSYS,EAX(%esp)
578         jmp resume_userspace
579         CFI_ENDPROC
580
581 #ifndef CONFIG_XEN
582 #define FIXUP_ESPFIX_STACK \
583         movl %esp, %eax; \
584         /* switch to 32bit stack using the pointer on top of 16bit stack */ \
585         lss %ss:CPU_16BIT_STACK_SIZE-8, %esp; \
586         /* copy data from 16bit stack to 32bit stack */ \
587         call fixup_x86_bogus_stack; \
588         /* put ESP to the proper location */ \
589         movl %eax, %esp;
590 #define UNWIND_ESPFIX_STACK \
591         pushl %eax; \
592         CFI_ADJUST_CFA_OFFSET 4; \
593         movl %ss, %eax; \
594         /* see if on 16bit stack */ \
595         cmpw $__ESPFIX_SS, %ax; \
596         je 28f; \
597 27:     popl %eax; \
598         CFI_ADJUST_CFA_OFFSET -4; \
599 .section .fixup,"ax"; \
600 28:     movl $__KERNEL_DS, %eax; \
601         movl %eax, %ds; \
602         movl %eax, %es; \
603         /* switch to 32bit stack */ \
604         FIXUP_ESPFIX_STACK; \
605         jmp 27b; \
606 .previous
607
608 /*
609  * Build the entry stubs and pointer table with
610  * some assembler magic.
611  */
612 .data
613 ENTRY(interrupt)
614 .text
615
616 vector=0
617 ENTRY(irq_entries_start)
618         RING0_INT_FRAME
619 .rept NR_IRQS
620         ALIGN
621  .if vector
622         CFI_ADJUST_CFA_OFFSET -4
623  .endif
624 1:      pushl $~(vector)
625         CFI_ADJUST_CFA_OFFSET 4
626         jmp common_interrupt
627 .data
628         .long 1b
629 .text
630 vector=vector+1
631 .endr
632
633 /*
634  * the CPU automatically disables interrupts when executing an IRQ vector,
635  * so IRQ-flags tracing has to follow that:
636  */
637         ALIGN
638 common_interrupt:
639         SAVE_ALL
640         TRACE_IRQS_OFF
641         movl %esp,%eax
642         call do_IRQ
643         jmp ret_from_intr
644         CFI_ENDPROC
645
646 #define BUILD_INTERRUPT(name, nr)       \
647 ENTRY(name)                             \
648         SAVE_ALL                        \
649         RING0_INT_FRAME;                \
650         pushl $~(nr);                   \
651         CFI_ADJUST_CFA_OFFSET 4;        \
652         SAVE_ALL;                       \
653         TRACE_IRQS_OFF                  \
654         movl %esp,%eax;                 \
655         call smp_/**/name;              \
656         jmp ret_from_intr;              \
657         CFI_ENDPROC
658
659 /* The include is where all of the SMP etc. interrupts come from */
660 #include "entry_arch.h"
661 #else
662 #define UNWIND_ESPFIX_STACK
663 #endif
664
665 ENTRY(divide_error)
666         RING0_INT_FRAME
667         pushl $0                        # no error code
668         CFI_ADJUST_CFA_OFFSET 4
669         pushl $do_divide_error
670         CFI_ADJUST_CFA_OFFSET 4
671         ALIGN
672 error_code:
673         pushl %ds
674         CFI_ADJUST_CFA_OFFSET 4
675         /*CFI_REL_OFFSET ds, 0*/
676         pushl %eax
677         CFI_ADJUST_CFA_OFFSET 4
678         CFI_REL_OFFSET eax, 0
679         xorl %eax, %eax
680         pushl %ebp
681         CFI_ADJUST_CFA_OFFSET 4
682         CFI_REL_OFFSET ebp, 0
683         pushl %edi
684         CFI_ADJUST_CFA_OFFSET 4
685         CFI_REL_OFFSET edi, 0
686         pushl %esi
687         CFI_ADJUST_CFA_OFFSET 4
688         CFI_REL_OFFSET esi, 0
689         pushl %edx
690         CFI_ADJUST_CFA_OFFSET 4
691         CFI_REL_OFFSET edx, 0
692         decl %eax                       # eax = -1
693         pushl %ecx
694         CFI_ADJUST_CFA_OFFSET 4
695         CFI_REL_OFFSET ecx, 0
696         pushl %ebx
697         CFI_ADJUST_CFA_OFFSET 4
698         CFI_REL_OFFSET ebx, 0
699         cld
700         pushl %es
701         CFI_ADJUST_CFA_OFFSET 4
702         /*CFI_REL_OFFSET es, 0*/
703         UNWIND_ESPFIX_STACK
704         popl %ecx
705         CFI_ADJUST_CFA_OFFSET -4
706         /*CFI_REGISTER es, ecx*/
707         movl ES(%esp), %edi             # get the function address
708         movl ORIG_EAX(%esp), %edx       # get the error code
709         movl %eax, ORIG_EAX(%esp)
710         movl %ecx, ES(%esp)
711         /*CFI_REL_OFFSET es, ES*/
712         movl $(__USER_DS), %ecx
713         movl %ecx, %ds
714         movl %ecx, %es
715         movl %esp,%eax                  # pt_regs pointer
716         call *%edi
717         jmp ret_from_exception
718         CFI_ENDPROC
719
720 #ifdef CONFIG_XEN
721 # A note on the "critical region" in our callback handler.
722 # We want to avoid stacking callback handlers due to events occurring
723 # during handling of the last event. To do this, we keep events disabled
724 # until we've done all processing. HOWEVER, we must enable events before
725 # popping the stack frame (can't be done atomically) and so it would still
726 # be possible to get enough handler activations to overflow the stack.
727 # Although unlikely, bugs of that kind are hard to track down, so we'd
728 # like to avoid the possibility.
729 # So, on entry to the handler we detect whether we interrupted an
730 # existing activation in its critical region -- if so, we pop the current
731 # activation and restart the handler using the previous one.
732 #
733 # The sysexit critical region is slightly different. sysexit
734 # atomically removes the entire stack frame. If we interrupt in the
735 # critical region we know that the entire frame is present and correct
736 # so we can simply throw away the new one.
737 ENTRY(hypervisor_callback)
738         RING0_INT_FRAME
739         pushl %eax
740         CFI_ADJUST_CFA_OFFSET 4
741         SAVE_ALL
742         movl EIP(%esp),%eax
743         cmpl $scrit,%eax
744         jb   11f
745         cmpl $ecrit,%eax
746         jb   critical_region_fixup
747         cmpl $sysexit_scrit,%eax
748         jb   11f
749         cmpl $sysexit_ecrit,%eax
750         ja   11f
751         # interrupted in sysexit critical
752         addl $0x34,%esp                 # Remove cs...ebx from stack frame.
753         # this popped off new frame to reuse the old one, therefore no 
754         # CFI_ADJUST_CFA_OFFSET here
755 11:     push %esp
756         CFI_ADJUST_CFA_OFFSET 4
757         call evtchn_do_upcall
758         add  $4,%esp
759         CFI_ADJUST_CFA_OFFSET -4
760         jmp  ret_from_intr
761
762         ALIGN
763 restore_all_enable_events:
764         __ENABLE_INTERRUPTS
765 scrit:  /**** START OF CRITICAL REGION ****/
766         __TEST_PENDING
767         jnz  14f                        # process more events if necessary...
768         RESTORE_REGS
769         addl $4, %esp
770         CFI_ADJUST_CFA_OFFSET -4
771 1:      iret
772 .section __ex_table,"a"
773         .align 4
774         .long 1b,iret_exc
775 .previous
776 14:     __DISABLE_INTERRUPTS
777         jmp  11b
778 ecrit:  /**** END OF CRITICAL REGION ****/
779 # [How we do the fixup]. We want to merge the current stack frame with the
780 # just-interrupted frame. How we do this depends on where in the critical
781 # region the interrupted handler was executing, and so how many saved
782 # registers are in each frame. We do this quickly using the lookup table
783 # 'critical_fixup_table'. For each byte offset in the critical region, it
784 # provides the number of bytes which have already been popped from the
785 # interrupted stack frame.
786 critical_region_fixup:
787         addl $critical_fixup_table-scrit,%eax
788         movzbl (%eax),%eax              # %eax contains num bytes popped
789         cmpb $0xff,%al                  # 0xff => vcpu_info critical region
790         jne  15f
791         GET_THREAD_INFO(%ebp)
792         xorl %eax,%eax
793 15:     mov  %esp,%esi
794         add  %eax,%esi                  # %esi points at end of src region
795         mov  %esp,%edi
796         add  $0x34,%edi                 # %edi points at end of dst region
797         mov  %eax,%ecx
798         shr  $2,%ecx                    # convert words to bytes
799         je   17f                        # skip loop if nothing to copy
800 16:     subl $4,%esi                    # pre-decrementing copy loop
801         subl $4,%edi
802         movl (%esi),%eax
803         movl %eax,(%edi)
804         loop 16b
805 17:     movl %edi,%esp                  # final %edi is top of merged stack
806         # this popped off new frame to reuse the old one, therefore no 
807         # CFI_DEF_CFA_OFFSET here
808         jmp  11b
809         CFI_ENDPROC
810
811 critical_fixup_table:
812         .byte 0xff,0xff,0xff            # testb $0xff,(%esi) = __TEST_PENDING
813         .byte 0xff,0xff                 # jnz  14f
814         .byte 0x00                      # pop  %ebx
815         .byte 0x04                      # pop  %ecx
816         .byte 0x08                      # pop  %edx
817         .byte 0x0c                      # pop  %esi
818         .byte 0x10                      # pop  %edi
819         .byte 0x14                      # pop  %ebp
820         .byte 0x18                      # pop  %eax
821         .byte 0x1c                      # pop  %ds
822         .byte 0x20                      # pop  %es
823         .byte 0x24,0x24,0x24            # add  $4,%esp
824         .byte 0x28                      # iret
825         .byte 0xff,0xff,0xff,0xff       # movb $1,1(%esi)
826         .byte 0x00,0x00                 # jmp  11b
827
828 # Hypervisor uses this for application faults while it executes.
829 # We get here for two reasons:
830 #  1. Fault while reloading DS, ES, FS or GS
831 #  2. Fault while executing IRET
832 # Category 1 we fix up by reattempting the load, and zeroing the segment
833 # register if the load fails.
834 # Category 2 we fix up by jumping to do_iret_error. We cannot use the
835 # normal Linux return path in this case because if we use the IRET hypercall
836 # to pop the stack frame we end up in an infinite loop of failsafe callbacks.
837 # We distinguish between categories by maintaining a status value in EAX.
838 ENTRY(failsafe_callback)
839         RING0_INT_FRAME
840         pushl %eax
841         CFI_ADJUST_CFA_OFFSET 4
842         movl $1,%eax
843 1:      mov 4(%esp),%ds
844 2:      mov 8(%esp),%es
845 3:      mov 12(%esp),%fs
846 4:      mov 16(%esp),%gs
847         testl %eax,%eax
848         popl %eax
849         CFI_ADJUST_CFA_OFFSET -4
850         jz 5f
851         addl $16,%esp           # EAX != 0 => Category 2 (Bad IRET)
852         CFI_ADJUST_CFA_OFFSET -16
853         jmp iret_exc
854         CFI_ADJUST_CFA_OFFSET 16
855 5:      addl $16,%esp           # EAX == 0 => Category 1 (Bad segment)
856         CFI_ADJUST_CFA_OFFSET -16
857         pushl $0
858         CFI_ADJUST_CFA_OFFSET 4
859         SAVE_ALL
860         jmp ret_from_exception
861 .section .fixup,"ax";           \
862 6:      xorl %eax,%eax;         \
863         movl %eax,4(%esp);      \
864         jmp 1b;                 \
865 7:      xorl %eax,%eax;         \
866         movl %eax,8(%esp);      \
867         jmp 2b;                 \
868 8:      xorl %eax,%eax;         \
869         movl %eax,12(%esp);     \
870         jmp 3b;                 \
871 9:      xorl %eax,%eax;         \
872         movl %eax,16(%esp);     \
873         jmp 4b;                 \
874 .previous;                      \
875 .section __ex_table,"a";        \
876         .align 4;               \
877         .long 1b,6b;            \
878         .long 2b,7b;            \
879         .long 3b,8b;            \
880         .long 4b,9b;            \
881 .previous
882         CFI_ENDPROC
883 #endif
884
885 ENTRY(coprocessor_error)
886         RING0_INT_FRAME
887         pushl $0
888         CFI_ADJUST_CFA_OFFSET 4
889         pushl $do_coprocessor_error
890         CFI_ADJUST_CFA_OFFSET 4
891         jmp error_code
892         CFI_ENDPROC
893
894 ENTRY(simd_coprocessor_error)
895         RING0_INT_FRAME
896         pushl $0
897         CFI_ADJUST_CFA_OFFSET 4
898         pushl $do_simd_coprocessor_error
899         CFI_ADJUST_CFA_OFFSET 4
900         jmp error_code
901         CFI_ENDPROC
902
903 ENTRY(device_not_available)
904         RING0_INT_FRAME
905         pushl $-1                       # mark this as an int
906         CFI_ADJUST_CFA_OFFSET 4
907         SAVE_ALL
908 #ifndef CONFIG_XEN
909         movl %cr0, %eax
910         testl $0x4, %eax                # EM (math emulation bit)
911         je device_available_emulate
912         pushl $0                        # temporary storage for ORIG_EIP
913         CFI_ADJUST_CFA_OFFSET 4
914         call math_emulate
915         addl $4, %esp
916         CFI_ADJUST_CFA_OFFSET -4
917         jmp ret_from_exception
918 device_available_emulate:
919 #endif
920         preempt_stop
921         call math_state_restore
922         jmp ret_from_exception
923         CFI_ENDPROC
924
925 #ifndef CONFIG_XEN
926 /*
927  * Debug traps and NMI can happen at the one SYSENTER instruction
928  * that sets up the real kernel stack. Check here, since we can't
929  * allow the wrong stack to be used.
930  *
931  * "SYSENTER_stack_esp0+12" is because the NMI/debug handler will have
932  * already pushed 3 words if it hits on the sysenter instruction:
933  * eflags, cs and eip.
934  *
935  * We just load the right stack, and push the three (known) values
936  * by hand onto the new stack - while updating the return eip past
937  * the instruction that would have done it for sysenter.
938  */
939 #define FIX_STACK(offset, ok, label)            \
940         cmpw $__KERNEL_CS,4(%esp);              \
941         jne ok;                                 \
942 label:                                          \
943         movl SYSENTER_stack_esp0+offset(%esp),%esp;     \
944         pushfl;                                 \
945         pushl $__KERNEL_CS;                     \
946         pushl $sysenter_past_esp
947 #endif /* CONFIG_XEN */
948
949 KPROBE_ENTRY(debug)
950         RING0_INT_FRAME
951 #ifndef CONFIG_XEN
952         cmpl $sysenter_entry,(%esp)
953         jne debug_stack_correct
954         FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn)
955 debug_stack_correct:
956 #endif /* !CONFIG_XEN */
957         pushl $-1                       # mark this as an int
958         CFI_ADJUST_CFA_OFFSET 4
959         SAVE_ALL
960         xorl %edx,%edx                  # error code 0
961         movl %esp,%eax                  # pt_regs pointer
962         call do_debug
963         jmp ret_from_exception
964         CFI_ENDPROC
965         .previous .text
966
967 #ifndef CONFIG_XEN
968 /*
969  * NMI is doubly nasty. It can happen _while_ we're handling
970  * a debug fault, and the debug fault hasn't yet been able to
971  * clear up the stack. So we first check whether we got  an
972  * NMI on the sysenter entry path, but after that we need to
973  * check whether we got an NMI on the debug path where the debug
974  * fault happened on the sysenter path.
975  */
976 ENTRY(nmi)
977         RING0_INT_FRAME
978         pushl %eax
979         CFI_ADJUST_CFA_OFFSET 4
980         movl %ss, %eax
981         cmpw $__ESPFIX_SS, %ax
982         popl %eax
983         CFI_ADJUST_CFA_OFFSET -4
984         je nmi_16bit_stack
985         cmpl $sysenter_entry,(%esp)
986         je nmi_stack_fixup
987         pushl %eax
988         CFI_ADJUST_CFA_OFFSET 4
989         movl %esp,%eax
990         /* Do not access memory above the end of our stack page,
991          * it might not exist.
992          */
993         andl $(THREAD_SIZE-1),%eax
994         cmpl $(THREAD_SIZE-20),%eax
995         popl %eax
996         CFI_ADJUST_CFA_OFFSET -4
997         jae nmi_stack_correct
998         cmpl $sysenter_entry,12(%esp)
999         je nmi_debug_stack_check
1000 nmi_stack_correct:
1001         pushl %eax
1002         CFI_ADJUST_CFA_OFFSET 4
1003         SAVE_ALL
1004         xorl %edx,%edx          # zero error code
1005         movl %esp,%eax          # pt_regs pointer
1006         call do_nmi
1007         jmp restore_nocheck_notrace
1008         CFI_ENDPROC
1009
1010 nmi_stack_fixup:
1011         FIX_STACK(12,nmi_stack_correct, 1)
1012         jmp nmi_stack_correct
1013 nmi_debug_stack_check:
1014         cmpw $__KERNEL_CS,16(%esp)
1015         jne nmi_stack_correct
1016         cmpl $debug,(%esp)
1017         jb nmi_stack_correct
1018         cmpl $debug_esp_fix_insn,(%esp)
1019         ja nmi_stack_correct
1020         FIX_STACK(24,nmi_stack_correct, 1)
1021         jmp nmi_stack_correct
1022
1023 nmi_16bit_stack:
1024         RING0_INT_FRAME
1025         /* create the pointer to lss back */
1026         pushl %ss
1027         CFI_ADJUST_CFA_OFFSET 4
1028         pushl %esp
1029         CFI_ADJUST_CFA_OFFSET 4
1030         movzwl %sp, %esp
1031         addw $4, (%esp)
1032         /* copy the iret frame of 12 bytes */
1033         .rept 3
1034         pushl 16(%esp)
1035         CFI_ADJUST_CFA_OFFSET 4
1036         .endr
1037         pushl %eax
1038         CFI_ADJUST_CFA_OFFSET 4
1039         SAVE_ALL
1040         FIXUP_ESPFIX_STACK              # %eax == %esp
1041         CFI_ADJUST_CFA_OFFSET -20       # the frame has now moved
1042         xorl %edx,%edx                  # zero error code
1043         call do_nmi
1044         RESTORE_REGS
1045         lss 12+4(%esp), %esp            # back to 16bit stack
1046 1:      iret
1047         CFI_ENDPROC
1048 .section __ex_table,"a"
1049         .align 4
1050         .long 1b,iret_exc
1051 .previous
1052 #else
1053 ENTRY(nmi)
1054         RING0_INT_FRAME
1055         pushl %eax
1056         CFI_ADJUST_CFA_OFFSET 4
1057         SAVE_ALL
1058         xorl %edx,%edx          # zero error code
1059         movl %esp,%eax          # pt_regs pointer
1060         call do_nmi
1061         orl  $NMI_MASK, EFLAGS(%esp)
1062         jmp restore_all
1063         CFI_ENDPROC
1064 #endif
1065
1066 KPROBE_ENTRY(int3)
1067         RING0_INT_FRAME
1068         pushl $-1                       # mark this as an int
1069         CFI_ADJUST_CFA_OFFSET 4
1070         SAVE_ALL
1071         xorl %edx,%edx          # zero error code
1072         movl %esp,%eax          # pt_regs pointer
1073         call do_int3
1074         jmp ret_from_exception
1075         CFI_ENDPROC
1076         .previous .text
1077
1078 ENTRY(overflow)
1079         RING0_INT_FRAME
1080         pushl $0
1081         CFI_ADJUST_CFA_OFFSET 4
1082         pushl $do_overflow
1083         CFI_ADJUST_CFA_OFFSET 4
1084         jmp error_code
1085         CFI_ENDPROC
1086
1087 ENTRY(bounds)
1088         RING0_INT_FRAME
1089         pushl $0
1090         CFI_ADJUST_CFA_OFFSET 4
1091         pushl $do_bounds
1092         CFI_ADJUST_CFA_OFFSET 4
1093         jmp error_code
1094         CFI_ENDPROC
1095
1096 ENTRY(invalid_op)
1097         RING0_INT_FRAME
1098         pushl $0
1099         CFI_ADJUST_CFA_OFFSET 4
1100         pushl $do_invalid_op
1101         CFI_ADJUST_CFA_OFFSET 4
1102         jmp error_code
1103         CFI_ENDPROC
1104
1105 ENTRY(coprocessor_segment_overrun)
1106         RING0_INT_FRAME
1107         pushl $0
1108         CFI_ADJUST_CFA_OFFSET 4
1109         pushl $do_coprocessor_segment_overrun
1110         CFI_ADJUST_CFA_OFFSET 4
1111         jmp error_code
1112         CFI_ENDPROC
1113
1114 ENTRY(invalid_TSS)
1115         RING0_EC_FRAME
1116         pushl $do_invalid_TSS
1117         CFI_ADJUST_CFA_OFFSET 4
1118         jmp error_code
1119         CFI_ENDPROC
1120
1121 ENTRY(segment_not_present)
1122         RING0_EC_FRAME
1123         pushl $do_segment_not_present
1124         CFI_ADJUST_CFA_OFFSET 4
1125         jmp error_code
1126         CFI_ENDPROC
1127
1128 ENTRY(stack_segment)
1129         RING0_EC_FRAME
1130         pushl $do_stack_segment
1131         CFI_ADJUST_CFA_OFFSET 4
1132         jmp error_code
1133         CFI_ENDPROC
1134
1135 KPROBE_ENTRY(general_protection)
1136         RING0_EC_FRAME
1137         pushl $do_general_protection
1138         CFI_ADJUST_CFA_OFFSET 4
1139         jmp error_code
1140         CFI_ENDPROC
1141         .previous .text
1142
1143 ENTRY(alignment_check)
1144         RING0_EC_FRAME
1145         pushl $do_alignment_check
1146         CFI_ADJUST_CFA_OFFSET 4
1147         jmp error_code
1148         CFI_ENDPROC
1149
1150 KPROBE_ENTRY(page_fault)
1151         RING0_EC_FRAME
1152         pushl $do_page_fault
1153         CFI_ADJUST_CFA_OFFSET 4
1154         jmp error_code
1155         CFI_ENDPROC
1156         .previous .text
1157
1158 #ifdef CONFIG_X86_MCE
1159 ENTRY(machine_check)
1160         RING0_INT_FRAME
1161         pushl $0
1162         CFI_ADJUST_CFA_OFFSET 4
1163         pushl machine_check_vector
1164         CFI_ADJUST_CFA_OFFSET 4
1165         jmp error_code
1166         CFI_ENDPROC
1167 #endif
1168
1169 ENTRY(fixup_4gb_segment)
1170         RING0_INT_FRAME
1171         pushl $do_fixup_4gb_segment
1172         CFI_ADJUST_CFA_OFFSET 4
1173         jmp error_code
1174         CFI_ENDPROC
1175
1176 #ifdef CONFIG_STACK_UNWIND
1177 ENTRY(arch_unwind_init_running)
1178         CFI_STARTPROC
1179         movl    4(%esp), %edx
1180         movl    (%esp), %ecx
1181         leal    4(%esp), %eax
1182         movl    %ebx, EBX(%edx)
1183         xorl    %ebx, %ebx
1184         movl    %ebx, ECX(%edx)
1185         movl    %ebx, EDX(%edx)
1186         movl    %esi, ESI(%edx)
1187         movl    %edi, EDI(%edx)
1188         movl    %ebp, EBP(%edx)
1189         movl    %ebx, EAX(%edx)
1190         movl    $__USER_DS, DS(%edx)
1191         movl    $__USER_DS, ES(%edx)
1192         movl    %ebx, ORIG_EAX(%edx)
1193         movl    %ecx, EIP(%edx)
1194         movl    12(%esp), %ecx
1195         movl    $__KERNEL_CS, CS(%edx)
1196         movl    %ebx, EFLAGS(%edx)
1197         movl    %eax, OLDESP(%edx)
1198         movl    8(%esp), %eax
1199         movl    %ecx, 8(%esp)
1200         movl    EBX(%edx), %ebx
1201         movl    $__KERNEL_DS, OLDSS(%edx)
1202         jmpl    *%eax
1203         CFI_ENDPROC
1204 ENDPROC(arch_unwind_init_running)
1205 #endif
1206
1207 .section .rodata,"a"
1208 #include "syscall_table.S"
1209
1210 syscall_table_size=(.-sys_call_table)