Merge to Fedora kernel-2.6.18-1.2255_FC5-vs2.0.2.2-rc9 patched with stable patch...
[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_EMU|_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_EMU|_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         cmpl $0, %eax
549         jne resume_userspace            # ret != 0 -> running under PTRACE_SYSEMU,
550                                         # so must skip actual syscall
551         movl ORIG_EAX(%esp), %eax
552         cmpl $(nr_syscalls), %eax
553         jnae syscall_call
554         jmp syscall_exit
555
556         # perform syscall exit tracing
557         ALIGN
558 syscall_exit_work:
559         testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP), %cl
560         jz work_pending
561         TRACE_IRQS_ON
562         ENABLE_INTERRUPTS               # could let do_syscall_trace() call
563                                         # schedule() instead
564         movl %esp, %eax
565         movl $1, %edx
566         call do_syscall_trace
567         jmp resume_userspace
568         CFI_ENDPROC
569
570         RING0_INT_FRAME                 # can't unwind into user space anyway
571 syscall_fault:
572         pushl %eax                      # save orig_eax
573         CFI_ADJUST_CFA_OFFSET 4
574         SAVE_ALL
575         GET_THREAD_INFO(%ebp)
576         movl $-EFAULT,EAX(%esp)
577         jmp resume_userspace
578
579 syscall_badsys:
580         movl $-ENOSYS,EAX(%esp)
581         jmp resume_userspace
582         CFI_ENDPROC
583
584 #ifndef CONFIG_XEN
585 #define FIXUP_ESPFIX_STACK \
586         movl %esp, %eax; \
587         /* switch to 32bit stack using the pointer on top of 16bit stack */ \
588         lss %ss:CPU_16BIT_STACK_SIZE-8, %esp; \
589         /* copy data from 16bit stack to 32bit stack */ \
590         call fixup_x86_bogus_stack; \
591         /* put ESP to the proper location */ \
592         movl %eax, %esp;
593 #define UNWIND_ESPFIX_STACK \
594         pushl %eax; \
595         CFI_ADJUST_CFA_OFFSET 4; \
596         movl %ss, %eax; \
597         /* see if on 16bit stack */ \
598         cmpw $__ESPFIX_SS, %ax; \
599         je 28f; \
600 27:     popl %eax; \
601         CFI_ADJUST_CFA_OFFSET -4; \
602 .section .fixup,"ax"; \
603 28:     movl $__KERNEL_DS, %eax; \
604         movl %eax, %ds; \
605         movl %eax, %es; \
606         /* switch to 32bit stack */ \
607         FIXUP_ESPFIX_STACK; \
608         jmp 27b; \
609 .previous
610
611 /*
612  * Build the entry stubs and pointer table with
613  * some assembler magic.
614  */
615 .data
616 ENTRY(interrupt)
617 .text
618
619 vector=0
620 ENTRY(irq_entries_start)
621         RING0_INT_FRAME
622 .rept NR_IRQS
623         ALIGN
624  .if vector
625         CFI_ADJUST_CFA_OFFSET -4
626  .endif
627 1:      pushl $~(vector)
628         CFI_ADJUST_CFA_OFFSET 4
629         jmp common_interrupt
630 .data
631         .long 1b
632 .text
633 vector=vector+1
634 .endr
635
636 /*
637  * the CPU automatically disables interrupts when executing an IRQ vector,
638  * so IRQ-flags tracing has to follow that:
639  */
640         ALIGN
641 common_interrupt:
642         SAVE_ALL
643         TRACE_IRQS_OFF
644         movl %esp,%eax
645         call do_IRQ
646         jmp ret_from_intr
647         CFI_ENDPROC
648
649 #define BUILD_INTERRUPT(name, nr)       \
650 ENTRY(name)                             \
651         SAVE_ALL                        \
652         RING0_INT_FRAME;                \
653         pushl $~(nr);                   \
654         CFI_ADJUST_CFA_OFFSET 4;        \
655         SAVE_ALL;                       \
656         TRACE_IRQS_OFF                  \
657         movl %esp,%eax;                 \
658         call smp_/**/name;              \
659         jmp ret_from_intr;              \
660         CFI_ENDPROC
661
662 /* The include is where all of the SMP etc. interrupts come from */
663 #include "entry_arch.h"
664 #else
665 #define UNWIND_ESPFIX_STACK
666 #endif
667
668 ENTRY(divide_error)
669         RING0_INT_FRAME
670         pushl $0                        # no error code
671         CFI_ADJUST_CFA_OFFSET 4
672         pushl $do_divide_error
673         CFI_ADJUST_CFA_OFFSET 4
674         ALIGN
675 error_code:
676         pushl %ds
677         CFI_ADJUST_CFA_OFFSET 4
678         /*CFI_REL_OFFSET ds, 0*/
679         pushl %eax
680         CFI_ADJUST_CFA_OFFSET 4
681         CFI_REL_OFFSET eax, 0
682         xorl %eax, %eax
683         pushl %ebp
684         CFI_ADJUST_CFA_OFFSET 4
685         CFI_REL_OFFSET ebp, 0
686         pushl %edi
687         CFI_ADJUST_CFA_OFFSET 4
688         CFI_REL_OFFSET edi, 0
689         pushl %esi
690         CFI_ADJUST_CFA_OFFSET 4
691         CFI_REL_OFFSET esi, 0
692         pushl %edx
693         CFI_ADJUST_CFA_OFFSET 4
694         CFI_REL_OFFSET edx, 0
695         decl %eax                       # eax = -1
696         pushl %ecx
697         CFI_ADJUST_CFA_OFFSET 4
698         CFI_REL_OFFSET ecx, 0
699         pushl %ebx
700         CFI_ADJUST_CFA_OFFSET 4
701         CFI_REL_OFFSET ebx, 0
702         cld
703         pushl %es
704         CFI_ADJUST_CFA_OFFSET 4
705         /*CFI_REL_OFFSET es, 0*/
706         UNWIND_ESPFIX_STACK
707         popl %ecx
708         CFI_ADJUST_CFA_OFFSET -4
709         /*CFI_REGISTER es, ecx*/
710         movl ES(%esp), %edi             # get the function address
711         movl ORIG_EAX(%esp), %edx       # get the error code
712         movl %eax, ORIG_EAX(%esp)
713         movl %ecx, ES(%esp)
714         /*CFI_REL_OFFSET es, ES*/
715         movl $(__USER_DS), %ecx
716         movl %ecx, %ds
717         movl %ecx, %es
718         movl %esp,%eax                  # pt_regs pointer
719         call *%edi
720         jmp ret_from_exception
721         CFI_ENDPROC
722
723 #ifdef CONFIG_XEN
724 # A note on the "critical region" in our callback handler.
725 # We want to avoid stacking callback handlers due to events occurring
726 # during handling of the last event. To do this, we keep events disabled
727 # until we've done all processing. HOWEVER, we must enable events before
728 # popping the stack frame (can't be done atomically) and so it would still
729 # be possible to get enough handler activations to overflow the stack.
730 # Although unlikely, bugs of that kind are hard to track down, so we'd
731 # like to avoid the possibility.
732 # So, on entry to the handler we detect whether we interrupted an
733 # existing activation in its critical region -- if so, we pop the current
734 # activation and restart the handler using the previous one.
735 #
736 # The sysexit critical region is slightly different. sysexit
737 # atomically removes the entire stack frame. If we interrupt in the
738 # critical region we know that the entire frame is present and correct
739 # so we can simply throw away the new one.
740 ENTRY(hypervisor_callback)
741         RING0_INT_FRAME
742         pushl %eax
743         CFI_ADJUST_CFA_OFFSET 4
744         SAVE_ALL
745         movl EIP(%esp),%eax
746         cmpl $scrit,%eax
747         jb   11f
748         cmpl $ecrit,%eax
749         jb   critical_region_fixup
750         cmpl $sysexit_scrit,%eax
751         jb   11f
752         cmpl $sysexit_ecrit,%eax
753         ja   11f
754         # interrupted in sysexit critical
755         addl $0x34,%esp                 # Remove cs...ebx from stack frame.
756         # this popped off new frame to reuse the old one, therefore no 
757         # CFI_ADJUST_CFA_OFFSET here
758 11:     push %esp
759         CFI_ADJUST_CFA_OFFSET 4
760         call evtchn_do_upcall
761         add  $4,%esp
762         CFI_ADJUST_CFA_OFFSET -4
763         jmp  ret_from_intr
764
765         ALIGN
766 restore_all_enable_events:
767         __ENABLE_INTERRUPTS
768 scrit:  /**** START OF CRITICAL REGION ****/
769         __TEST_PENDING
770         jnz  14f                        # process more events if necessary...
771         RESTORE_REGS
772         addl $4, %esp
773         CFI_ADJUST_CFA_OFFSET -4
774 1:      iret
775 .section __ex_table,"a"
776         .align 4
777         .long 1b,iret_exc
778 .previous
779 14:     __DISABLE_INTERRUPTS
780         jmp  11b
781 ecrit:  /**** END OF CRITICAL REGION ****/
782 # [How we do the fixup]. We want to merge the current stack frame with the
783 # just-interrupted frame. How we do this depends on where in the critical
784 # region the interrupted handler was executing, and so how many saved
785 # registers are in each frame. We do this quickly using the lookup table
786 # 'critical_fixup_table'. For each byte offset in the critical region, it
787 # provides the number of bytes which have already been popped from the
788 # interrupted stack frame.
789 critical_region_fixup:
790         addl $critical_fixup_table-scrit,%eax
791         movzbl (%eax),%eax              # %eax contains num bytes popped
792         cmpb $0xff,%al                  # 0xff => vcpu_info critical region
793         jne  15f
794         GET_THREAD_INFO(%ebp)
795         xorl %eax,%eax
796 15:     mov  %esp,%esi
797         add  %eax,%esi                  # %esi points at end of src region
798         mov  %esp,%edi
799         add  $0x34,%edi                 # %edi points at end of dst region
800         mov  %eax,%ecx
801         shr  $2,%ecx                    # convert words to bytes
802         je   17f                        # skip loop if nothing to copy
803 16:     subl $4,%esi                    # pre-decrementing copy loop
804         subl $4,%edi
805         movl (%esi),%eax
806         movl %eax,(%edi)
807         loop 16b
808 17:     movl %edi,%esp                  # final %edi is top of merged stack
809         # this popped off new frame to reuse the old one, therefore no 
810         # CFI_DEF_CFA_OFFSET here
811         jmp  11b
812         CFI_ENDPROC
813
814 critical_fixup_table:
815         .byte 0xff,0xff,0xff            # testb $0xff,(%esi) = __TEST_PENDING
816         .byte 0xff,0xff                 # jnz  14f
817         .byte 0x00                      # pop  %ebx
818         .byte 0x04                      # pop  %ecx
819         .byte 0x08                      # pop  %edx
820         .byte 0x0c                      # pop  %esi
821         .byte 0x10                      # pop  %edi
822         .byte 0x14                      # pop  %ebp
823         .byte 0x18                      # pop  %eax
824         .byte 0x1c                      # pop  %ds
825         .byte 0x20                      # pop  %es
826         .byte 0x24,0x24,0x24            # add  $4,%esp
827         .byte 0x28                      # iret
828         .byte 0xff,0xff,0xff,0xff       # movb $1,1(%esi)
829         .byte 0x00,0x00                 # jmp  11b
830
831 # Hypervisor uses this for application faults while it executes.
832 # We get here for two reasons:
833 #  1. Fault while reloading DS, ES, FS or GS
834 #  2. Fault while executing IRET
835 # Category 1 we fix up by reattempting the load, and zeroing the segment
836 # register if the load fails.
837 # Category 2 we fix up by jumping to do_iret_error. We cannot use the
838 # normal Linux return path in this case because if we use the IRET hypercall
839 # to pop the stack frame we end up in an infinite loop of failsafe callbacks.
840 # We distinguish between categories by maintaining a status value in EAX.
841 ENTRY(failsafe_callback)
842         RING0_INT_FRAME
843         pushl %eax
844         CFI_ADJUST_CFA_OFFSET 4
845         movl $1,%eax
846 1:      mov 4(%esp),%ds
847 2:      mov 8(%esp),%es
848 3:      mov 12(%esp),%fs
849 4:      mov 16(%esp),%gs
850         testl %eax,%eax
851         popl %eax
852         CFI_ADJUST_CFA_OFFSET -4
853         jz 5f
854         addl $16,%esp           # EAX != 0 => Category 2 (Bad IRET)
855         CFI_ADJUST_CFA_OFFSET -16
856         jmp iret_exc
857         CFI_ADJUST_CFA_OFFSET 16
858 5:      addl $16,%esp           # EAX == 0 => Category 1 (Bad segment)
859         CFI_ADJUST_CFA_OFFSET -16
860         pushl $0
861         CFI_ADJUST_CFA_OFFSET 4
862         SAVE_ALL
863         jmp ret_from_exception
864 .section .fixup,"ax";           \
865 6:      xorl %eax,%eax;         \
866         movl %eax,4(%esp);      \
867         jmp 1b;                 \
868 7:      xorl %eax,%eax;         \
869         movl %eax,8(%esp);      \
870         jmp 2b;                 \
871 8:      xorl %eax,%eax;         \
872         movl %eax,12(%esp);     \
873         jmp 3b;                 \
874 9:      xorl %eax,%eax;         \
875         movl %eax,16(%esp);     \
876         jmp 4b;                 \
877 .previous;                      \
878 .section __ex_table,"a";        \
879         .align 4;               \
880         .long 1b,6b;            \
881         .long 2b,7b;            \
882         .long 3b,8b;            \
883         .long 4b,9b;            \
884 .previous
885         CFI_ENDPROC
886 #endif
887
888 ENTRY(coprocessor_error)
889         RING0_INT_FRAME
890         pushl $0
891         CFI_ADJUST_CFA_OFFSET 4
892         pushl $do_coprocessor_error
893         CFI_ADJUST_CFA_OFFSET 4
894         jmp error_code
895         CFI_ENDPROC
896
897 ENTRY(simd_coprocessor_error)
898         RING0_INT_FRAME
899         pushl $0
900         CFI_ADJUST_CFA_OFFSET 4
901         pushl $do_simd_coprocessor_error
902         CFI_ADJUST_CFA_OFFSET 4
903         jmp error_code
904         CFI_ENDPROC
905
906 ENTRY(device_not_available)
907         RING0_INT_FRAME
908         pushl $-1                       # mark this as an int
909         CFI_ADJUST_CFA_OFFSET 4
910         SAVE_ALL
911 #ifndef CONFIG_XEN
912         movl %cr0, %eax
913         testl $0x4, %eax                # EM (math emulation bit)
914         je device_available_emulate
915         pushl $0                        # temporary storage for ORIG_EIP
916         CFI_ADJUST_CFA_OFFSET 4
917         call math_emulate
918         addl $4, %esp
919         CFI_ADJUST_CFA_OFFSET -4
920         jmp ret_from_exception
921 device_available_emulate:
922 #endif
923         preempt_stop
924         call math_state_restore
925         jmp ret_from_exception
926         CFI_ENDPROC
927
928 #ifndef CONFIG_XEN
929 /*
930  * Debug traps and NMI can happen at the one SYSENTER instruction
931  * that sets up the real kernel stack. Check here, since we can't
932  * allow the wrong stack to be used.
933  *
934  * "SYSENTER_stack_esp0+12" is because the NMI/debug handler will have
935  * already pushed 3 words if it hits on the sysenter instruction:
936  * eflags, cs and eip.
937  *
938  * We just load the right stack, and push the three (known) values
939  * by hand onto the new stack - while updating the return eip past
940  * the instruction that would have done it for sysenter.
941  */
942 #define FIX_STACK(offset, ok, label)            \
943         cmpw $__KERNEL_CS,4(%esp);              \
944         jne ok;                                 \
945 label:                                          \
946         movl SYSENTER_stack_esp0+offset(%esp),%esp;     \
947         pushfl;                                 \
948         pushl $__KERNEL_CS;                     \
949         pushl $sysenter_past_esp
950 #endif /* CONFIG_XEN */
951
952 KPROBE_ENTRY(debug)
953         RING0_INT_FRAME
954 #ifndef CONFIG_XEN
955         cmpl $sysenter_entry,(%esp)
956         jne debug_stack_correct
957         FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn)
958 debug_stack_correct:
959 #endif /* !CONFIG_XEN */
960         pushl $-1                       # mark this as an int
961         CFI_ADJUST_CFA_OFFSET 4
962         SAVE_ALL
963         xorl %edx,%edx                  # error code 0
964         movl %esp,%eax                  # pt_regs pointer
965         call do_debug
966         jmp ret_from_exception
967         CFI_ENDPROC
968         .previous .text
969
970 #ifndef CONFIG_XEN
971 /*
972  * NMI is doubly nasty. It can happen _while_ we're handling
973  * a debug fault, and the debug fault hasn't yet been able to
974  * clear up the stack. So we first check whether we got  an
975  * NMI on the sysenter entry path, but after that we need to
976  * check whether we got an NMI on the debug path where the debug
977  * fault happened on the sysenter path.
978  */
979 ENTRY(nmi)
980         RING0_INT_FRAME
981         pushl %eax
982         CFI_ADJUST_CFA_OFFSET 4
983         movl %ss, %eax
984         cmpw $__ESPFIX_SS, %ax
985         popl %eax
986         CFI_ADJUST_CFA_OFFSET -4
987         je nmi_16bit_stack
988         cmpl $sysenter_entry,(%esp)
989         je nmi_stack_fixup
990         pushl %eax
991         CFI_ADJUST_CFA_OFFSET 4
992         movl %esp,%eax
993         /* Do not access memory above the end of our stack page,
994          * it might not exist.
995          */
996         andl $(THREAD_SIZE-1),%eax
997         cmpl $(THREAD_SIZE-20),%eax
998         popl %eax
999         CFI_ADJUST_CFA_OFFSET -4
1000         jae nmi_stack_correct
1001         cmpl $sysenter_entry,12(%esp)
1002         je nmi_debug_stack_check
1003 nmi_stack_correct:
1004         pushl %eax
1005         CFI_ADJUST_CFA_OFFSET 4
1006         SAVE_ALL
1007         xorl %edx,%edx          # zero error code
1008         movl %esp,%eax          # pt_regs pointer
1009         call do_nmi
1010         jmp restore_nocheck_notrace
1011         CFI_ENDPROC
1012
1013 nmi_stack_fixup:
1014         FIX_STACK(12,nmi_stack_correct, 1)
1015         jmp nmi_stack_correct
1016 nmi_debug_stack_check:
1017         cmpw $__KERNEL_CS,16(%esp)
1018         jne nmi_stack_correct
1019         cmpl $debug,(%esp)
1020         jb nmi_stack_correct
1021         cmpl $debug_esp_fix_insn,(%esp)
1022         ja nmi_stack_correct
1023         FIX_STACK(24,nmi_stack_correct, 1)
1024         jmp nmi_stack_correct
1025
1026 nmi_16bit_stack:
1027         RING0_INT_FRAME
1028         /* create the pointer to lss back */
1029         pushl %ss
1030         CFI_ADJUST_CFA_OFFSET 4
1031         pushl %esp
1032         CFI_ADJUST_CFA_OFFSET 4
1033         movzwl %sp, %esp
1034         addw $4, (%esp)
1035         /* copy the iret frame of 12 bytes */
1036         .rept 3
1037         pushl 16(%esp)
1038         CFI_ADJUST_CFA_OFFSET 4
1039         .endr
1040         pushl %eax
1041         CFI_ADJUST_CFA_OFFSET 4
1042         SAVE_ALL
1043         FIXUP_ESPFIX_STACK              # %eax == %esp
1044         CFI_ADJUST_CFA_OFFSET -20       # the frame has now moved
1045         xorl %edx,%edx                  # zero error code
1046         call do_nmi
1047         RESTORE_REGS
1048         lss 12+4(%esp), %esp            # back to 16bit stack
1049 1:      iret
1050         CFI_ENDPROC
1051 .section __ex_table,"a"
1052         .align 4
1053         .long 1b,iret_exc
1054 .previous
1055 #else
1056 ENTRY(nmi)
1057         RING0_INT_FRAME
1058         pushl %eax
1059         CFI_ADJUST_CFA_OFFSET 4
1060         SAVE_ALL
1061         xorl %edx,%edx          # zero error code
1062         movl %esp,%eax          # pt_regs pointer
1063         call do_nmi
1064         orl  $NMI_MASK, EFLAGS(%esp)
1065         jmp restore_all
1066         CFI_ENDPROC
1067 #endif
1068
1069 KPROBE_ENTRY(int3)
1070         RING0_INT_FRAME
1071         pushl $-1                       # mark this as an int
1072         CFI_ADJUST_CFA_OFFSET 4
1073         SAVE_ALL
1074         xorl %edx,%edx          # zero error code
1075         movl %esp,%eax          # pt_regs pointer
1076         call do_int3
1077         jmp ret_from_exception
1078         CFI_ENDPROC
1079         .previous .text
1080
1081 ENTRY(overflow)
1082         RING0_INT_FRAME
1083         pushl $0
1084         CFI_ADJUST_CFA_OFFSET 4
1085         pushl $do_overflow
1086         CFI_ADJUST_CFA_OFFSET 4
1087         jmp error_code
1088         CFI_ENDPROC
1089
1090 ENTRY(bounds)
1091         RING0_INT_FRAME
1092         pushl $0
1093         CFI_ADJUST_CFA_OFFSET 4
1094         pushl $do_bounds
1095         CFI_ADJUST_CFA_OFFSET 4
1096         jmp error_code
1097         CFI_ENDPROC
1098
1099 ENTRY(invalid_op)
1100         RING0_INT_FRAME
1101         pushl $0
1102         CFI_ADJUST_CFA_OFFSET 4
1103         pushl $do_invalid_op
1104         CFI_ADJUST_CFA_OFFSET 4
1105         jmp error_code
1106         CFI_ENDPROC
1107
1108 ENTRY(coprocessor_segment_overrun)
1109         RING0_INT_FRAME
1110         pushl $0
1111         CFI_ADJUST_CFA_OFFSET 4
1112         pushl $do_coprocessor_segment_overrun
1113         CFI_ADJUST_CFA_OFFSET 4
1114         jmp error_code
1115         CFI_ENDPROC
1116
1117 ENTRY(invalid_TSS)
1118         RING0_EC_FRAME
1119         pushl $do_invalid_TSS
1120         CFI_ADJUST_CFA_OFFSET 4
1121         jmp error_code
1122         CFI_ENDPROC
1123
1124 ENTRY(segment_not_present)
1125         RING0_EC_FRAME
1126         pushl $do_segment_not_present
1127         CFI_ADJUST_CFA_OFFSET 4
1128         jmp error_code
1129         CFI_ENDPROC
1130
1131 ENTRY(stack_segment)
1132         RING0_EC_FRAME
1133         pushl $do_stack_segment
1134         CFI_ADJUST_CFA_OFFSET 4
1135         jmp error_code
1136         CFI_ENDPROC
1137
1138 KPROBE_ENTRY(general_protection)
1139         RING0_EC_FRAME
1140         pushl $do_general_protection
1141         CFI_ADJUST_CFA_OFFSET 4
1142         jmp error_code
1143         CFI_ENDPROC
1144         .previous .text
1145
1146 ENTRY(alignment_check)
1147         RING0_EC_FRAME
1148         pushl $do_alignment_check
1149         CFI_ADJUST_CFA_OFFSET 4
1150         jmp error_code
1151         CFI_ENDPROC
1152
1153 KPROBE_ENTRY(page_fault)
1154         RING0_EC_FRAME
1155         pushl $do_page_fault
1156         CFI_ADJUST_CFA_OFFSET 4
1157         jmp error_code
1158         CFI_ENDPROC
1159         .previous .text
1160
1161 #ifdef CONFIG_X86_MCE
1162 ENTRY(machine_check)
1163         RING0_INT_FRAME
1164         pushl $0
1165         CFI_ADJUST_CFA_OFFSET 4
1166         pushl machine_check_vector
1167         CFI_ADJUST_CFA_OFFSET 4
1168         jmp error_code
1169         CFI_ENDPROC
1170 #endif
1171
1172 ENTRY(fixup_4gb_segment)
1173         RING0_INT_FRAME
1174         pushl $do_fixup_4gb_segment
1175         CFI_ADJUST_CFA_OFFSET 4
1176         jmp error_code
1177         CFI_ENDPROC
1178
1179 #ifdef CONFIG_STACK_UNWIND
1180 ENTRY(arch_unwind_init_running)
1181         CFI_STARTPROC
1182         movl    4(%esp), %edx
1183         movl    (%esp), %ecx
1184         leal    4(%esp), %eax
1185         movl    %ebx, EBX(%edx)
1186         xorl    %ebx, %ebx
1187         movl    %ebx, ECX(%edx)
1188         movl    %ebx, EDX(%edx)
1189         movl    %esi, ESI(%edx)
1190         movl    %edi, EDI(%edx)
1191         movl    %ebp, EBP(%edx)
1192         movl    %ebx, EAX(%edx)
1193         movl    $__USER_DS, DS(%edx)
1194         movl    $__USER_DS, ES(%edx)
1195         movl    %ebx, ORIG_EAX(%edx)
1196         movl    %ecx, EIP(%edx)
1197         movl    12(%esp), %ecx
1198         movl    $__KERNEL_CS, CS(%edx)
1199         movl    %ebx, EFLAGS(%edx)
1200         movl    %eax, OLDESP(%edx)
1201         movl    8(%esp), %eax
1202         movl    %ecx, 8(%esp)
1203         movl    EBX(%edx), %ebx
1204         movl    $__KERNEL_DS, OLDSS(%edx)
1205         jmpl    *%eax
1206         CFI_ENDPROC
1207 ENDPROC(arch_unwind_init_running)
1208 #endif
1209
1210 .section .rodata,"a"
1211 #include "syscall_table.S"
1212
1213 syscall_table_size=(.-sys_call_table)