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