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