[PATCH] i386: espfix cleanup
[pandora-kernel.git] / arch / i386 / kernel / entry.S
1 /*
2  *  linux/arch/i386/entry.S
3  *
4  *  Copyright (C) 1991, 1992  Linus Torvalds
5  */
6
7 /*
8  * entry.S contains the system-call and fault low-level handling routines.
9  * This also contains the timer-interrupt handler, as well as all interrupts
10  * and faults that can result in a task-switch.
11  *
12  * NOTE: This code handles signal-recognition, which happens every time
13  * after a timer-interrupt and after each system call.
14  *
15  * I changed all the .align's to 4 (16 byte alignment), as that's faster
16  * on a 486.
17  *
18  * Stack layout in 'ret_from_system_call':
19  *      ptrace needs to have all regs on the stack.
20  *      if the order here is changed, it needs to be
21  *      updated in fork.c:copy_process, signal.c:do_signal,
22  *      ptrace.c and ptrace.h
23  *
24  *       0(%esp) - %ebx
25  *       4(%esp) - %ecx
26  *       8(%esp) - %edx
27  *       C(%esp) - %esi
28  *      10(%esp) - %edi
29  *      14(%esp) - %ebp
30  *      18(%esp) - %eax
31  *      1C(%esp) - %ds
32  *      20(%esp) - %es
33  *      24(%esp) - orig_eax
34  *      28(%esp) - %eip
35  *      2C(%esp) - %cs
36  *      30(%esp) - %eflags
37  *      34(%esp) - %oldesp
38  *      38(%esp) - %oldss
39  *
40  * "current" is in register %ebx during any slow entries.
41  */
42
43 #include <linux/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/percpu.h>
52 #include <asm/dwarf2.h>
53 #include "irq_vectors.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
80 /* These are replaces for paravirtualization */
81 #define DISABLE_INTERRUPTS              cli
82 #define ENABLE_INTERRUPTS               sti
83 #define ENABLE_INTERRUPTS_SYSEXIT       sti; sysexit
84 #define INTERRUPT_RETURN                iret
85 #define GET_CR0_INTO_EAX                movl %cr0, %eax
86
87 #ifdef CONFIG_PREEMPT
88 #define preempt_stop            DISABLE_INTERRUPTS; TRACE_IRQS_OFF
89 #else
90 #define preempt_stop
91 #define resume_kernel           restore_nocheck
92 #endif
93
94 .macro TRACE_IRQS_IRET
95 #ifdef CONFIG_TRACE_IRQFLAGS
96         testl $IF_MASK,EFLAGS(%esp)     # interrupts off?
97         jz 1f
98         TRACE_IRQS_ON
99 1:
100 #endif
101 .endm
102
103 #ifdef CONFIG_VM86
104 #define resume_userspace_sig    check_userspace
105 #else
106 #define resume_userspace_sig    resume_userspace
107 #endif
108
109 #define SAVE_ALL \
110         cld; \
111         pushl %es; \
112         CFI_ADJUST_CFA_OFFSET 4;\
113         /*CFI_REL_OFFSET es, 0;*/\
114         pushl %ds; \
115         CFI_ADJUST_CFA_OFFSET 4;\
116         /*CFI_REL_OFFSET ds, 0;*/\
117         pushl %eax; \
118         CFI_ADJUST_CFA_OFFSET 4;\
119         CFI_REL_OFFSET eax, 0;\
120         pushl %ebp; \
121         CFI_ADJUST_CFA_OFFSET 4;\
122         CFI_REL_OFFSET ebp, 0;\
123         pushl %edi; \
124         CFI_ADJUST_CFA_OFFSET 4;\
125         CFI_REL_OFFSET edi, 0;\
126         pushl %esi; \
127         CFI_ADJUST_CFA_OFFSET 4;\
128         CFI_REL_OFFSET esi, 0;\
129         pushl %edx; \
130         CFI_ADJUST_CFA_OFFSET 4;\
131         CFI_REL_OFFSET edx, 0;\
132         pushl %ecx; \
133         CFI_ADJUST_CFA_OFFSET 4;\
134         CFI_REL_OFFSET ecx, 0;\
135         pushl %ebx; \
136         CFI_ADJUST_CFA_OFFSET 4;\
137         CFI_REL_OFFSET ebx, 0;\
138         movl $(__USER_DS), %edx; \
139         movl %edx, %ds; \
140         movl %edx, %es;
141
142 #define RESTORE_INT_REGS \
143         popl %ebx;      \
144         CFI_ADJUST_CFA_OFFSET -4;\
145         CFI_RESTORE ebx;\
146         popl %ecx;      \
147         CFI_ADJUST_CFA_OFFSET -4;\
148         CFI_RESTORE ecx;\
149         popl %edx;      \
150         CFI_ADJUST_CFA_OFFSET -4;\
151         CFI_RESTORE edx;\
152         popl %esi;      \
153         CFI_ADJUST_CFA_OFFSET -4;\
154         CFI_RESTORE esi;\
155         popl %edi;      \
156         CFI_ADJUST_CFA_OFFSET -4;\
157         CFI_RESTORE edi;\
158         popl %ebp;      \
159         CFI_ADJUST_CFA_OFFSET -4;\
160         CFI_RESTORE ebp;\
161         popl %eax;      \
162         CFI_ADJUST_CFA_OFFSET -4;\
163         CFI_RESTORE eax
164
165 #define RESTORE_REGS    \
166         RESTORE_INT_REGS; \
167 1:      popl %ds;       \
168         CFI_ADJUST_CFA_OFFSET -4;\
169         /*CFI_RESTORE ds;*/\
170 2:      popl %es;       \
171         CFI_ADJUST_CFA_OFFSET -4;\
172         /*CFI_RESTORE es;*/\
173 .section .fixup,"ax";   \
174 3:      movl $0,(%esp); \
175         jmp 1b;         \
176 4:      movl $0,(%esp); \
177         jmp 2b;         \
178 .previous;              \
179 .section __ex_table,"a";\
180         .align 4;       \
181         .long 1b,3b;    \
182         .long 2b,4b;    \
183 .previous
184
185 #define RING0_INT_FRAME \
186         CFI_STARTPROC simple;\
187         CFI_SIGNAL_FRAME;\
188         CFI_DEF_CFA esp, 3*4;\
189         /*CFI_OFFSET cs, -2*4;*/\
190         CFI_OFFSET eip, -3*4
191
192 #define RING0_EC_FRAME \
193         CFI_STARTPROC simple;\
194         CFI_SIGNAL_FRAME;\
195         CFI_DEF_CFA esp, 4*4;\
196         /*CFI_OFFSET cs, -2*4;*/\
197         CFI_OFFSET eip, -3*4
198
199 #define RING0_PTREGS_FRAME \
200         CFI_STARTPROC simple;\
201         CFI_SIGNAL_FRAME;\
202         CFI_DEF_CFA esp, OLDESP-EBX;\
203         /*CFI_OFFSET cs, CS-OLDESP;*/\
204         CFI_OFFSET eip, EIP-OLDESP;\
205         /*CFI_OFFSET es, ES-OLDESP;*/\
206         /*CFI_OFFSET ds, DS-OLDESP;*/\
207         CFI_OFFSET eax, EAX-OLDESP;\
208         CFI_OFFSET ebp, EBP-OLDESP;\
209         CFI_OFFSET edi, EDI-OLDESP;\
210         CFI_OFFSET esi, ESI-OLDESP;\
211         CFI_OFFSET edx, EDX-OLDESP;\
212         CFI_OFFSET ecx, ECX-OLDESP;\
213         CFI_OFFSET ebx, EBX-OLDESP
214
215 ENTRY(ret_from_fork)
216         CFI_STARTPROC
217         pushl %eax
218         CFI_ADJUST_CFA_OFFSET 4
219         call schedule_tail
220         GET_THREAD_INFO(%ebp)
221         popl %eax
222         CFI_ADJUST_CFA_OFFSET -4
223         pushl $0x0202                   # Reset kernel eflags
224         CFI_ADJUST_CFA_OFFSET 4
225         popfl
226         CFI_ADJUST_CFA_OFFSET -4
227         jmp syscall_exit
228         CFI_ENDPROC
229
230 /*
231  * Return to user mode is not as complex as all this looks,
232  * but we want the default path for a system call return to
233  * go as quickly as possible which is why some of this is
234  * less clear than it otherwise should be.
235  */
236
237         # userspace resumption stub bypassing syscall exit tracing
238         ALIGN
239         RING0_PTREGS_FRAME
240 ret_from_exception:
241         preempt_stop
242 ret_from_intr:
243         GET_THREAD_INFO(%ebp)
244 check_userspace:
245         movl EFLAGS(%esp), %eax         # mix EFLAGS and CS
246         movb CS(%esp), %al
247         andl $(VM_MASK | SEGMENT_RPL_MASK), %eax
248         cmpl $USER_RPL, %eax
249         jb resume_kernel                # not returning to v8086 or userspace
250 ENTRY(resume_userspace)
251         DISABLE_INTERRUPTS              # make sure we don't miss an interrupt
252                                         # setting need_resched or sigpending
253                                         # between sampling and the iret
254         movl TI_flags(%ebp), %ecx
255         andl $_TIF_WORK_MASK, %ecx      # is there any work to be done on
256                                         # int/exception return?
257         jne work_pending
258         jmp restore_all
259
260 #ifdef CONFIG_PREEMPT
261 ENTRY(resume_kernel)
262         DISABLE_INTERRUPTS
263         cmpl $0,TI_preempt_count(%ebp)  # non-zero preempt_count ?
264         jnz restore_nocheck
265 need_resched:
266         movl TI_flags(%ebp), %ecx       # need_resched set ?
267         testb $_TIF_NEED_RESCHED, %cl
268         jz restore_all
269         testl $IF_MASK,EFLAGS(%esp)     # interrupts off (exception path) ?
270         jz restore_all
271         call preempt_schedule_irq
272         jmp need_resched
273 #endif
274         CFI_ENDPROC
275
276 /* SYSENTER_RETURN points to after the "sysenter" instruction in
277    the vsyscall page.  See vsyscall-sysentry.S, which defines the symbol.  */
278
279         # sysenter call handler stub
280 ENTRY(sysenter_entry)
281         CFI_STARTPROC simple
282         CFI_SIGNAL_FRAME
283         CFI_DEF_CFA esp, 0
284         CFI_REGISTER esp, ebp
285         movl TSS_sysenter_esp0(%esp),%esp
286 sysenter_past_esp:
287         /*
288          * No need to follow this irqs on/off section: the syscall
289          * disabled irqs and here we enable it straight after entry:
290          */
291         ENABLE_INTERRUPTS
292         pushl $(__USER_DS)
293         CFI_ADJUST_CFA_OFFSET 4
294         /*CFI_REL_OFFSET ss, 0*/
295         pushl %ebp
296         CFI_ADJUST_CFA_OFFSET 4
297         CFI_REL_OFFSET esp, 0
298         pushfl
299         CFI_ADJUST_CFA_OFFSET 4
300         pushl $(__USER_CS)
301         CFI_ADJUST_CFA_OFFSET 4
302         /*CFI_REL_OFFSET cs, 0*/
303         /*
304          * Push current_thread_info()->sysenter_return to the stack.
305          * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
306          * pushed above; +8 corresponds to copy_thread's esp0 setting.
307          */
308         pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
309         CFI_ADJUST_CFA_OFFSET 4
310         CFI_REL_OFFSET eip, 0
311
312 /*
313  * Load the potential sixth argument from user stack.
314  * Careful about security.
315  */
316         cmpl $__PAGE_OFFSET-3,%ebp
317         jae syscall_fault
318 1:      movl (%ebp),%ebp
319 .section __ex_table,"a"
320         .align 4
321         .long 1b,syscall_fault
322 .previous
323
324         pushl %eax
325         CFI_ADJUST_CFA_OFFSET 4
326         SAVE_ALL
327         GET_THREAD_INFO(%ebp)
328
329         /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
330         testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
331         jnz syscall_trace_entry
332         cmpl $(nr_syscalls), %eax
333         jae syscall_badsys
334         call *sys_call_table(,%eax,4)
335         movl %eax,EAX(%esp)
336         DISABLE_INTERRUPTS
337         TRACE_IRQS_OFF
338         movl TI_flags(%ebp), %ecx
339         testw $_TIF_ALLWORK_MASK, %cx
340         jne syscall_exit_work
341 /* if something modifies registers it must also disable sysexit */
342         movl EIP(%esp), %edx
343         movl OLDESP(%esp), %ecx
344         xorl %ebp,%ebp
345         TRACE_IRQS_ON
346         ENABLE_INTERRUPTS_SYSEXIT
347         CFI_ENDPROC
348
349
350         # system call handler stub
351 ENTRY(system_call)
352         RING0_INT_FRAME                 # can't unwind into user space anyway
353         pushl %eax                      # save orig_eax
354         CFI_ADJUST_CFA_OFFSET 4
355         SAVE_ALL
356         GET_THREAD_INFO(%ebp)
357         testl $TF_MASK,EFLAGS(%esp)
358         jz no_singlestep
359         orl $_TIF_SINGLESTEP,TI_flags(%ebp)
360 no_singlestep:
361                                         # system call tracing in operation / emulation
362         /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
363         testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
364         jnz syscall_trace_entry
365         cmpl $(nr_syscalls), %eax
366         jae syscall_badsys
367 syscall_call:
368         call *sys_call_table(,%eax,4)
369         movl %eax,EAX(%esp)             # store the return value
370 syscall_exit:
371         DISABLE_INTERRUPTS              # make sure we don't miss an interrupt
372                                         # setting need_resched or sigpending
373                                         # between sampling and the iret
374         TRACE_IRQS_OFF
375         movl TI_flags(%ebp), %ecx
376         testw $_TIF_ALLWORK_MASK, %cx   # current->work
377         jne syscall_exit_work
378
379 restore_all:
380         movl EFLAGS(%esp), %eax         # mix EFLAGS, SS and CS
381         # Warning: OLDSS(%esp) contains the wrong/random values if we
382         # are returning to the kernel.
383         # See comments in process.c:copy_thread() for details.
384         movb OLDSS(%esp), %ah
385         movb CS(%esp), %al
386         andl $(VM_MASK | (SEGMENT_TI_MASK << 8) | SEGMENT_RPL_MASK), %eax
387         cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax
388         CFI_REMEMBER_STATE
389         je ldt_ss                       # returning to user-space with LDT SS
390 restore_nocheck:
391         TRACE_IRQS_IRET
392 restore_nocheck_notrace:
393         RESTORE_REGS
394         addl $4, %esp
395         CFI_ADJUST_CFA_OFFSET -4
396 1:      INTERRUPT_RETURN
397 .section .fixup,"ax"
398 iret_exc:
399         TRACE_IRQS_ON
400         ENABLE_INTERRUPTS
401         pushl $0                        # no error code
402         pushl $do_iret_error
403         jmp error_code
404 .previous
405 .section __ex_table,"a"
406         .align 4
407         .long 1b,iret_exc
408 .previous
409
410         CFI_RESTORE_STATE
411 ldt_ss:
412         larl OLDSS(%esp), %eax
413         jnz restore_nocheck
414         testl $0x00400000, %eax         # returning to 32bit stack?
415         jnz restore_nocheck             # allright, normal return
416         /* If returning to userspace with 16bit stack,
417          * try to fix the higher word of ESP, as the CPU
418          * won't restore it.
419          * This is an "official" bug of all the x86-compatible
420          * CPUs, which we can try to work around to make
421          * dosemu and wine happy. */
422         movl OLDESP(%esp), %eax
423         movl %esp, %edx
424         call patch_espfix_desc
425         pushl $__ESPFIX_SS
426         CFI_ADJUST_CFA_OFFSET 4
427         pushl %eax
428         CFI_ADJUST_CFA_OFFSET 4
429         DISABLE_INTERRUPTS
430         TRACE_IRQS_OFF
431         lss (%esp), %esp
432         CFI_ADJUST_CFA_OFFSET -8
433         jmp restore_nocheck
434         CFI_ENDPROC
435
436         # perform work that needs to be done immediately before resumption
437         ALIGN
438         RING0_PTREGS_FRAME              # can't unwind into user space anyway
439 work_pending:
440         testb $_TIF_NEED_RESCHED, %cl
441         jz work_notifysig
442 work_resched:
443         call schedule
444         DISABLE_INTERRUPTS              # make sure we don't miss an interrupt
445                                         # setting need_resched or sigpending
446                                         # between sampling and the iret
447         TRACE_IRQS_OFF
448         movl TI_flags(%ebp), %ecx
449         andl $_TIF_WORK_MASK, %ecx      # is there any work to be done other
450                                         # than syscall tracing?
451         jz restore_all
452         testb $_TIF_NEED_RESCHED, %cl
453         jnz work_resched
454
455 work_notifysig:                         # deal with pending signals and
456                                         # notify-resume requests
457         testl $VM_MASK, EFLAGS(%esp)
458         movl %esp, %eax
459         jne work_notifysig_v86          # returning to kernel-space or
460                                         # vm86-space
461         xorl %edx, %edx
462         call do_notify_resume
463         jmp resume_userspace_sig
464
465         ALIGN
466 work_notifysig_v86:
467 #ifdef CONFIG_VM86
468         pushl %ecx                      # save ti_flags for do_notify_resume
469         CFI_ADJUST_CFA_OFFSET 4
470         call save_v86_state             # %eax contains pt_regs pointer
471         popl %ecx
472         CFI_ADJUST_CFA_OFFSET -4
473         movl %eax, %esp
474         xorl %edx, %edx
475         call do_notify_resume
476         jmp resume_userspace_sig
477 #endif
478
479         # perform syscall exit tracing
480         ALIGN
481 syscall_trace_entry:
482         movl $-ENOSYS,EAX(%esp)
483         movl %esp, %eax
484         xorl %edx,%edx
485         call do_syscall_trace
486         cmpl $0, %eax
487         jne resume_userspace            # ret != 0 -> running under PTRACE_SYSEMU,
488                                         # so must skip actual syscall
489         movl ORIG_EAX(%esp), %eax
490         cmpl $(nr_syscalls), %eax
491         jnae syscall_call
492         jmp syscall_exit
493
494         # perform syscall exit tracing
495         ALIGN
496 syscall_exit_work:
497         testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP), %cl
498         jz work_pending
499         TRACE_IRQS_ON
500         ENABLE_INTERRUPTS               # could let do_syscall_trace() call
501                                         # schedule() instead
502         movl %esp, %eax
503         movl $1, %edx
504         call do_syscall_trace
505         jmp resume_userspace
506         CFI_ENDPROC
507
508         RING0_INT_FRAME                 # can't unwind into user space anyway
509 syscall_fault:
510         pushl %eax                      # save orig_eax
511         CFI_ADJUST_CFA_OFFSET 4
512         SAVE_ALL
513         GET_THREAD_INFO(%ebp)
514         movl $-EFAULT,EAX(%esp)
515         jmp resume_userspace
516
517 syscall_badsys:
518         movl $-ENOSYS,EAX(%esp)
519         jmp resume_userspace
520         CFI_ENDPROC
521
522 #define FIXUP_ESPFIX_STACK \
523         /* since we are on a wrong stack, we cant make it a C code :( */ \
524         GET_THREAD_INFO(%ebp); \
525         movl TI_cpu(%ebp), %ebx; \
526         PER_CPU(cpu_gdt_descr, %ebx); \
527         movl GDS_address(%ebx), %ebx; \
528         GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \
529         addl %esp, %eax; \
530         pushl $__KERNEL_DS; \
531         CFI_ADJUST_CFA_OFFSET 4; \
532         pushl %eax; \
533         CFI_ADJUST_CFA_OFFSET 4; \
534         lss (%esp), %esp; \
535         CFI_ADJUST_CFA_OFFSET -8;
536 #define UNWIND_ESPFIX_STACK \
537         movl %ss, %eax; \
538         /* see if on espfix stack */ \
539         cmpw $__ESPFIX_SS, %ax; \
540         jne 27f; \
541         movl $__KERNEL_DS, %eax; \
542         movl %eax, %ds; \
543         movl %eax, %es; \
544         /* switch to normal stack */ \
545         FIXUP_ESPFIX_STACK; \
546 27:;
547
548 /*
549  * Build the entry stubs and pointer table with
550  * some assembler magic.
551  */
552 .data
553 ENTRY(interrupt)
554 .text
555
556 vector=0
557 ENTRY(irq_entries_start)
558         RING0_INT_FRAME
559 .rept NR_IRQS
560         ALIGN
561  .if vector
562         CFI_ADJUST_CFA_OFFSET -4
563  .endif
564 1:      pushl $~(vector)
565         CFI_ADJUST_CFA_OFFSET 4
566         jmp common_interrupt
567 .data
568         .long 1b
569 .text
570 vector=vector+1
571 .endr
572
573 /*
574  * the CPU automatically disables interrupts when executing an IRQ vector,
575  * so IRQ-flags tracing has to follow that:
576  */
577         ALIGN
578 common_interrupt:
579         SAVE_ALL
580         TRACE_IRQS_OFF
581         movl %esp,%eax
582         call do_IRQ
583         jmp ret_from_intr
584         CFI_ENDPROC
585
586 #define BUILD_INTERRUPT(name, nr)       \
587 ENTRY(name)                             \
588         RING0_INT_FRAME;                \
589         pushl $~(nr);                   \
590         CFI_ADJUST_CFA_OFFSET 4;        \
591         SAVE_ALL;                       \
592         TRACE_IRQS_OFF                  \
593         movl %esp,%eax;                 \
594         call smp_/**/name;              \
595         jmp ret_from_intr;              \
596         CFI_ENDPROC
597
598 /* The include is where all of the SMP etc. interrupts come from */
599 #include "entry_arch.h"
600
601 KPROBE_ENTRY(page_fault)
602         RING0_EC_FRAME
603         pushl $do_page_fault
604         CFI_ADJUST_CFA_OFFSET 4
605         ALIGN
606 error_code:
607         pushl %ds
608         CFI_ADJUST_CFA_OFFSET 4
609         /*CFI_REL_OFFSET ds, 0*/
610         pushl %eax
611         CFI_ADJUST_CFA_OFFSET 4
612         CFI_REL_OFFSET eax, 0
613         pushl %ebp
614         CFI_ADJUST_CFA_OFFSET 4
615         CFI_REL_OFFSET ebp, 0
616         pushl %edi
617         CFI_ADJUST_CFA_OFFSET 4
618         CFI_REL_OFFSET edi, 0
619         pushl %esi
620         CFI_ADJUST_CFA_OFFSET 4
621         CFI_REL_OFFSET esi, 0
622         pushl %edx
623         CFI_ADJUST_CFA_OFFSET 4
624         CFI_REL_OFFSET edx, 0
625         pushl %ecx
626         CFI_ADJUST_CFA_OFFSET 4
627         CFI_REL_OFFSET ecx, 0
628         pushl %ebx
629         CFI_ADJUST_CFA_OFFSET 4
630         CFI_REL_OFFSET ebx, 0
631         cld
632         pushl %es
633         CFI_ADJUST_CFA_OFFSET 4
634         /*CFI_REL_OFFSET es, 0*/
635         UNWIND_ESPFIX_STACK
636         popl %ecx
637         CFI_ADJUST_CFA_OFFSET -4
638         /*CFI_REGISTER es, ecx*/
639         movl ES(%esp), %edi             # get the function address
640         movl ORIG_EAX(%esp), %edx       # get the error code
641         movl $-1, ORIG_EAX(%esp)
642         movl %ecx, ES(%esp)
643         /*CFI_REL_OFFSET es, ES*/
644         movl $(__USER_DS), %ecx
645         movl %ecx, %ds
646         movl %ecx, %es
647         movl %esp,%eax                  # pt_regs pointer
648         call *%edi
649         jmp ret_from_exception
650         CFI_ENDPROC
651 KPROBE_END(page_fault)
652
653 ENTRY(coprocessor_error)
654         RING0_INT_FRAME
655         pushl $0
656         CFI_ADJUST_CFA_OFFSET 4
657         pushl $do_coprocessor_error
658         CFI_ADJUST_CFA_OFFSET 4
659         jmp error_code
660         CFI_ENDPROC
661
662 ENTRY(simd_coprocessor_error)
663         RING0_INT_FRAME
664         pushl $0
665         CFI_ADJUST_CFA_OFFSET 4
666         pushl $do_simd_coprocessor_error
667         CFI_ADJUST_CFA_OFFSET 4
668         jmp error_code
669         CFI_ENDPROC
670
671 ENTRY(device_not_available)
672         RING0_INT_FRAME
673         pushl $-1                       # mark this as an int
674         CFI_ADJUST_CFA_OFFSET 4
675         SAVE_ALL
676         GET_CR0_INTO_EAX
677         testl $0x4, %eax                # EM (math emulation bit)
678         jne device_not_available_emulate
679         preempt_stop
680         call math_state_restore
681         jmp ret_from_exception
682 device_not_available_emulate:
683         pushl $0                        # temporary storage for ORIG_EIP
684         CFI_ADJUST_CFA_OFFSET 4
685         call math_emulate
686         addl $4, %esp
687         CFI_ADJUST_CFA_OFFSET -4
688         jmp ret_from_exception
689         CFI_ENDPROC
690
691 /*
692  * Debug traps and NMI can happen at the one SYSENTER instruction
693  * that sets up the real kernel stack. Check here, since we can't
694  * allow the wrong stack to be used.
695  *
696  * "TSS_sysenter_esp0+12" is because the NMI/debug handler will have
697  * already pushed 3 words if it hits on the sysenter instruction:
698  * eflags, cs and eip.
699  *
700  * We just load the right stack, and push the three (known) values
701  * by hand onto the new stack - while updating the return eip past
702  * the instruction that would have done it for sysenter.
703  */
704 #define FIX_STACK(offset, ok, label)            \
705         cmpw $__KERNEL_CS,4(%esp);              \
706         jne ok;                                 \
707 label:                                          \
708         movl TSS_sysenter_esp0+offset(%esp),%esp;       \
709         CFI_DEF_CFA esp, 0;                     \
710         CFI_UNDEFINED eip;                      \
711         pushfl;                                 \
712         CFI_ADJUST_CFA_OFFSET 4;                \
713         pushl $__KERNEL_CS;                     \
714         CFI_ADJUST_CFA_OFFSET 4;                \
715         pushl $sysenter_past_esp;               \
716         CFI_ADJUST_CFA_OFFSET 4;                \
717         CFI_REL_OFFSET eip, 0
718
719 KPROBE_ENTRY(debug)
720         RING0_INT_FRAME
721         cmpl $sysenter_entry,(%esp)
722         jne debug_stack_correct
723         FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn)
724 debug_stack_correct:
725         pushl $-1                       # mark this as an int
726         CFI_ADJUST_CFA_OFFSET 4
727         SAVE_ALL
728         xorl %edx,%edx                  # error code 0
729         movl %esp,%eax                  # pt_regs pointer
730         call do_debug
731         jmp ret_from_exception
732         CFI_ENDPROC
733 KPROBE_END(debug)
734
735 /*
736  * NMI is doubly nasty. It can happen _while_ we're handling
737  * a debug fault, and the debug fault hasn't yet been able to
738  * clear up the stack. So we first check whether we got  an
739  * NMI on the sysenter entry path, but after that we need to
740  * check whether we got an NMI on the debug path where the debug
741  * fault happened on the sysenter path.
742  */
743 KPROBE_ENTRY(nmi)
744         RING0_INT_FRAME
745         pushl %eax
746         CFI_ADJUST_CFA_OFFSET 4
747         movl %ss, %eax
748         cmpw $__ESPFIX_SS, %ax
749         popl %eax
750         CFI_ADJUST_CFA_OFFSET -4
751         je nmi_espfix_stack
752         cmpl $sysenter_entry,(%esp)
753         je nmi_stack_fixup
754         pushl %eax
755         CFI_ADJUST_CFA_OFFSET 4
756         movl %esp,%eax
757         /* Do not access memory above the end of our stack page,
758          * it might not exist.
759          */
760         andl $(THREAD_SIZE-1),%eax
761         cmpl $(THREAD_SIZE-20),%eax
762         popl %eax
763         CFI_ADJUST_CFA_OFFSET -4
764         jae nmi_stack_correct
765         cmpl $sysenter_entry,12(%esp)
766         je nmi_debug_stack_check
767 nmi_stack_correct:
768         /* We have a RING0_INT_FRAME here */
769         pushl %eax
770         CFI_ADJUST_CFA_OFFSET 4
771         SAVE_ALL
772         xorl %edx,%edx          # zero error code
773         movl %esp,%eax          # pt_regs pointer
774         call do_nmi
775         jmp restore_nocheck_notrace
776         CFI_ENDPROC
777
778 nmi_stack_fixup:
779         RING0_INT_FRAME
780         FIX_STACK(12,nmi_stack_correct, 1)
781         jmp nmi_stack_correct
782
783 nmi_debug_stack_check:
784         /* We have a RING0_INT_FRAME here */
785         cmpw $__KERNEL_CS,16(%esp)
786         jne nmi_stack_correct
787         cmpl $debug,(%esp)
788         jb nmi_stack_correct
789         cmpl $debug_esp_fix_insn,(%esp)
790         ja nmi_stack_correct
791         FIX_STACK(24,nmi_stack_correct, 1)
792         jmp nmi_stack_correct
793
794 nmi_espfix_stack:
795         /* We have a RING0_INT_FRAME here.
796          *
797          * create the pointer to lss back
798          */
799         pushl %ss
800         CFI_ADJUST_CFA_OFFSET 4
801         pushl %esp
802         CFI_ADJUST_CFA_OFFSET 4
803         addw $4, (%esp)
804         /* copy the iret frame of 12 bytes */
805         .rept 3
806         pushl 16(%esp)
807         CFI_ADJUST_CFA_OFFSET 4
808         .endr
809         pushl %eax
810         CFI_ADJUST_CFA_OFFSET 4
811         SAVE_ALL
812         FIXUP_ESPFIX_STACK              # %eax == %esp
813         xorl %edx,%edx                  # zero error code
814         call do_nmi
815         RESTORE_REGS
816         lss 12+4(%esp), %esp            # back to espfix stack
817         CFI_ADJUST_CFA_OFFSET -24
818 1:      INTERRUPT_RETURN
819         CFI_ENDPROC
820 .section __ex_table,"a"
821         .align 4
822         .long 1b,iret_exc
823 .previous
824 KPROBE_END(nmi)
825
826 KPROBE_ENTRY(int3)
827         RING0_INT_FRAME
828         pushl $-1                       # mark this as an int
829         CFI_ADJUST_CFA_OFFSET 4
830         SAVE_ALL
831         xorl %edx,%edx          # zero error code
832         movl %esp,%eax          # pt_regs pointer
833         call do_int3
834         jmp ret_from_exception
835         CFI_ENDPROC
836 KPROBE_END(int3)
837
838 ENTRY(overflow)
839         RING0_INT_FRAME
840         pushl $0
841         CFI_ADJUST_CFA_OFFSET 4
842         pushl $do_overflow
843         CFI_ADJUST_CFA_OFFSET 4
844         jmp error_code
845         CFI_ENDPROC
846
847 ENTRY(bounds)
848         RING0_INT_FRAME
849         pushl $0
850         CFI_ADJUST_CFA_OFFSET 4
851         pushl $do_bounds
852         CFI_ADJUST_CFA_OFFSET 4
853         jmp error_code
854         CFI_ENDPROC
855
856 ENTRY(invalid_op)
857         RING0_INT_FRAME
858         pushl $0
859         CFI_ADJUST_CFA_OFFSET 4
860         pushl $do_invalid_op
861         CFI_ADJUST_CFA_OFFSET 4
862         jmp error_code
863         CFI_ENDPROC
864
865 ENTRY(coprocessor_segment_overrun)
866         RING0_INT_FRAME
867         pushl $0
868         CFI_ADJUST_CFA_OFFSET 4
869         pushl $do_coprocessor_segment_overrun
870         CFI_ADJUST_CFA_OFFSET 4
871         jmp error_code
872         CFI_ENDPROC
873
874 ENTRY(invalid_TSS)
875         RING0_EC_FRAME
876         pushl $do_invalid_TSS
877         CFI_ADJUST_CFA_OFFSET 4
878         jmp error_code
879         CFI_ENDPROC
880
881 ENTRY(segment_not_present)
882         RING0_EC_FRAME
883         pushl $do_segment_not_present
884         CFI_ADJUST_CFA_OFFSET 4
885         jmp error_code
886         CFI_ENDPROC
887
888 ENTRY(stack_segment)
889         RING0_EC_FRAME
890         pushl $do_stack_segment
891         CFI_ADJUST_CFA_OFFSET 4
892         jmp error_code
893         CFI_ENDPROC
894
895 KPROBE_ENTRY(general_protection)
896         RING0_EC_FRAME
897         pushl $do_general_protection
898         CFI_ADJUST_CFA_OFFSET 4
899         jmp error_code
900         CFI_ENDPROC
901 KPROBE_END(general_protection)
902
903 ENTRY(alignment_check)
904         RING0_EC_FRAME
905         pushl $do_alignment_check
906         CFI_ADJUST_CFA_OFFSET 4
907         jmp error_code
908         CFI_ENDPROC
909
910 ENTRY(divide_error)
911         RING0_INT_FRAME
912         pushl $0                        # no error code
913         CFI_ADJUST_CFA_OFFSET 4
914         pushl $do_divide_error
915         CFI_ADJUST_CFA_OFFSET 4
916         jmp error_code
917         CFI_ENDPROC
918
919 #ifdef CONFIG_X86_MCE
920 ENTRY(machine_check)
921         RING0_INT_FRAME
922         pushl $0
923         CFI_ADJUST_CFA_OFFSET 4
924         pushl machine_check_vector
925         CFI_ADJUST_CFA_OFFSET 4
926         jmp error_code
927         CFI_ENDPROC
928 #endif
929
930 ENTRY(spurious_interrupt_bug)
931         RING0_INT_FRAME
932         pushl $0
933         CFI_ADJUST_CFA_OFFSET 4
934         pushl $do_spurious_interrupt_bug
935         CFI_ADJUST_CFA_OFFSET 4
936         jmp error_code
937         CFI_ENDPROC
938
939 #ifdef CONFIG_STACK_UNWIND
940 ENTRY(arch_unwind_init_running)
941         CFI_STARTPROC
942         movl    4(%esp), %edx
943         movl    (%esp), %ecx
944         leal    4(%esp), %eax
945         movl    %ebx, EBX(%edx)
946         xorl    %ebx, %ebx
947         movl    %ebx, ECX(%edx)
948         movl    %ebx, EDX(%edx)
949         movl    %esi, ESI(%edx)
950         movl    %edi, EDI(%edx)
951         movl    %ebp, EBP(%edx)
952         movl    %ebx, EAX(%edx)
953         movl    $__USER_DS, DS(%edx)
954         movl    $__USER_DS, ES(%edx)
955         movl    %ebx, ORIG_EAX(%edx)
956         movl    %ecx, EIP(%edx)
957         movl    12(%esp), %ecx
958         movl    $__KERNEL_CS, CS(%edx)
959         movl    %ebx, EFLAGS(%edx)
960         movl    %eax, OLDESP(%edx)
961         movl    8(%esp), %eax
962         movl    %ecx, 8(%esp)
963         movl    EBX(%edx), %ebx
964         movl    $__KERNEL_DS, OLDSS(%edx)
965         jmpl    *%eax
966         CFI_ENDPROC
967 ENDPROC(arch_unwind_init_running)
968 #endif
969
970 ENTRY(kernel_thread_helper)
971         pushl $0                # fake return address for unwinder
972         CFI_STARTPROC
973         movl %edx,%eax
974         push %edx
975         CFI_ADJUST_CFA_OFFSET 4
976         call *%ebx
977         push %eax
978         CFI_ADJUST_CFA_OFFSET 4
979         call do_exit
980         CFI_ENDPROC
981 ENDPROC(kernel_thread_helper)
982
983 .section .rodata,"a"
984 #include "syscall_table.S"
985
986 syscall_table_size=(.-sys_call_table)