[PATCH] x86_64: Remove useless KDB vector
[safe/jmp/linux-2.6] / arch / x86_64 / kernel / entry.S
1 /*
2  *  linux/arch/x86_64/entry.S
3  *
4  *  Copyright (C) 1991, 1992  Linus Torvalds
5  *  Copyright (C) 2000, 2001, 2002  Andi Kleen SuSE Labs
6  *  Copyright (C) 2000  Pavel Machek <pavel@suse.cz>
7  * 
8  *  $Id$
9  */
10
11 /*
12  * entry.S contains the system-call and fault low-level handling routines.
13  *
14  * NOTE: This code handles signal-recognition, which happens every time
15  * after an interrupt and after each system call.
16  * 
17  * Normal syscalls and interrupts don't save a full stack frame, this is 
18  * only done for syscall tracing, signals or fork/exec et.al.
19  * 
20  * A note on terminology:        
21  * - top of stack: Architecture defined interrupt frame from SS to RIP 
22  * at the top of the kernel process stack.      
23  * - partial stack frame: partially saved registers upto R11.
24  * - full stack frame: Like partial stack frame, but all register saved. 
25  *      
26  * TODO:         
27  * - schedule it carefully for the final hardware.
28  */
29
30 #define ASSEMBLY 1
31 #include <linux/config.h>
32 #include <linux/linkage.h>
33 #include <asm/segment.h>
34 #include <asm/smp.h>
35 #include <asm/cache.h>
36 #include <asm/errno.h>
37 #include <asm/dwarf2.h>
38 #include <asm/calling.h>
39 #include <asm/asm-offsets.h>
40 #include <asm/msr.h>
41 #include <asm/unistd.h>
42 #include <asm/thread_info.h>
43 #include <asm/hw_irq.h>
44
45         .code64
46
47 #ifndef CONFIG_PREEMPT
48 #define retint_kernel retint_restore_args
49 #endif  
50         
51 /*
52  * C code is not supposed to know about undefined top of stack. Every time 
53  * a C function with an pt_regs argument is called from the SYSCALL based 
54  * fast path FIXUP_TOP_OF_STACK is needed.
55  * RESTORE_TOP_OF_STACK syncs the syscall state after any possible ptregs
56  * manipulation.
57  */             
58                 
59         /* %rsp:at FRAMEEND */ 
60         .macro FIXUP_TOP_OF_STACK tmp
61         movq    %gs:pda_oldrsp,\tmp
62         movq    \tmp,RSP(%rsp)
63         movq    $__USER_DS,SS(%rsp)
64         movq    $__USER_CS,CS(%rsp)
65         movq    $-1,RCX(%rsp)
66         movq    R11(%rsp),\tmp  /* get eflags */
67         movq    \tmp,EFLAGS(%rsp)
68         .endm
69
70         .macro RESTORE_TOP_OF_STACK tmp,offset=0
71         movq   RSP-\offset(%rsp),\tmp
72         movq   \tmp,%gs:pda_oldrsp
73         movq   EFLAGS-\offset(%rsp),\tmp
74         movq   \tmp,R11-\offset(%rsp)
75         .endm
76
77         .macro FAKE_STACK_FRAME child_rip
78         /* push in order ss, rsp, eflags, cs, rip */
79         xorl %eax, %eax
80         pushq %rax /* ss */
81         CFI_ADJUST_CFA_OFFSET   8
82         /*CFI_REL_OFFSET        ss,0*/
83         pushq %rax /* rsp */
84         CFI_ADJUST_CFA_OFFSET   8
85         CFI_REL_OFFSET  rsp,0
86         pushq $(1<<9) /* eflags - interrupts on */
87         CFI_ADJUST_CFA_OFFSET   8
88         /*CFI_REL_OFFSET        rflags,0*/
89         pushq $__KERNEL_CS /* cs */
90         CFI_ADJUST_CFA_OFFSET   8
91         /*CFI_REL_OFFSET        cs,0*/
92         pushq \child_rip /* rip */
93         CFI_ADJUST_CFA_OFFSET   8
94         CFI_REL_OFFSET  rip,0
95         pushq   %rax /* orig rax */
96         CFI_ADJUST_CFA_OFFSET   8
97         .endm
98
99         .macro UNFAKE_STACK_FRAME
100         addq $8*6, %rsp
101         CFI_ADJUST_CFA_OFFSET   -(6*8)
102         .endm
103
104         .macro  CFI_DEFAULT_STACK start=1
105         .if \start
106         CFI_STARTPROC   simple
107         CFI_DEF_CFA     rsp,SS+8
108         .else
109         CFI_DEF_CFA_OFFSET SS+8
110         .endif
111         CFI_REL_OFFSET  r15,R15
112         CFI_REL_OFFSET  r14,R14
113         CFI_REL_OFFSET  r13,R13
114         CFI_REL_OFFSET  r12,R12
115         CFI_REL_OFFSET  rbp,RBP
116         CFI_REL_OFFSET  rbx,RBX
117         CFI_REL_OFFSET  r11,R11
118         CFI_REL_OFFSET  r10,R10
119         CFI_REL_OFFSET  r9,R9
120         CFI_REL_OFFSET  r8,R8
121         CFI_REL_OFFSET  rax,RAX
122         CFI_REL_OFFSET  rcx,RCX
123         CFI_REL_OFFSET  rdx,RDX
124         CFI_REL_OFFSET  rsi,RSI
125         CFI_REL_OFFSET  rdi,RDI
126         CFI_REL_OFFSET  rip,RIP
127         /*CFI_REL_OFFSET        cs,CS*/
128         /*CFI_REL_OFFSET        rflags,EFLAGS*/
129         CFI_REL_OFFSET  rsp,RSP
130         /*CFI_REL_OFFSET        ss,SS*/
131         .endm
132 /*
133  * A newly forked process directly context switches into this.
134  */     
135 /* rdi: prev */ 
136 ENTRY(ret_from_fork)
137         CFI_DEFAULT_STACK
138         call schedule_tail
139         GET_THREAD_INFO(%rcx)
140         testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),threadinfo_flags(%rcx)
141         jnz rff_trace
142 rff_action:     
143         RESTORE_REST
144         testl $3,CS-ARGOFFSET(%rsp)     # from kernel_thread?
145         je   int_ret_from_sys_call
146         testl $_TIF_IA32,threadinfo_flags(%rcx)
147         jnz  int_ret_from_sys_call
148         RESTORE_TOP_OF_STACK %rdi,ARGOFFSET
149         jmp ret_from_sys_call
150 rff_trace:
151         movq %rsp,%rdi
152         call syscall_trace_leave
153         GET_THREAD_INFO(%rcx)   
154         jmp rff_action
155         CFI_ENDPROC
156
157 /*
158  * System call entry. Upto 6 arguments in registers are supported.
159  *
160  * SYSCALL does not save anything on the stack and does not change the
161  * stack pointer.
162  */
163                 
164 /*
165  * Register setup:      
166  * rax  system call number
167  * rdi  arg0
168  * rcx  return address for syscall/sysret, C arg3 
169  * rsi  arg1
170  * rdx  arg2    
171  * r10  arg3    (--> moved to rcx for C)
172  * r8   arg4
173  * r9   arg5
174  * r11  eflags for syscall/sysret, temporary for C
175  * r12-r15,rbp,rbx saved by C code, not touched.                
176  * 
177  * Interrupts are off on entry.
178  * Only called from user space.
179  *
180  * XXX  if we had a free scratch register we could save the RSP into the stack frame
181  *      and report it properly in ps. Unfortunately we haven't.
182  */                                     
183
184 ENTRY(system_call)
185         CFI_STARTPROC   simple
186         CFI_DEF_CFA     rsp,0
187         CFI_REGISTER    rip,rcx
188         /*CFI_REGISTER  rflags,r11*/
189         swapgs
190         movq    %rsp,%gs:pda_oldrsp 
191         movq    %gs:pda_kernelstack,%rsp
192         sti                                     
193         SAVE_ARGS 8,1
194         movq  %rax,ORIG_RAX-ARGOFFSET(%rsp) 
195         movq  %rcx,RIP-ARGOFFSET(%rsp)
196         CFI_REL_OFFSET rip,RIP-ARGOFFSET
197         GET_THREAD_INFO(%rcx)
198         testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%rcx)
199         CFI_REMEMBER_STATE
200         jnz tracesys
201         cmpq $__NR_syscall_max,%rax
202         ja badsys
203         movq %r10,%rcx
204         call *sys_call_table(,%rax,8)  # XXX:    rip relative
205         movq %rax,RAX-ARGOFFSET(%rsp)
206 /*
207  * Syscall return path ending with SYSRET (fast path)
208  * Has incomplete stack frame and undefined top of stack. 
209  */             
210         .globl ret_from_sys_call
211 ret_from_sys_call:
212         movl $_TIF_ALLWORK_MASK,%edi
213         /* edi: flagmask */
214 sysret_check:           
215         GET_THREAD_INFO(%rcx)
216         cli
217         movl threadinfo_flags(%rcx),%edx
218         andl %edi,%edx
219         CFI_REMEMBER_STATE
220         jnz  sysret_careful 
221         movq RIP-ARGOFFSET(%rsp),%rcx
222         CFI_REGISTER    rip,rcx
223         RESTORE_ARGS 0,-ARG_SKIP,1
224         /*CFI_REGISTER  rflags,r11*/
225         movq    %gs:pda_oldrsp,%rsp
226         swapgs
227         sysretq
228
229         /* Handle reschedules */
230         /* edx: work, edi: workmask */  
231 sysret_careful:
232         CFI_RESTORE_STATE
233         bt $TIF_NEED_RESCHED,%edx
234         jnc sysret_signal
235         sti
236         pushq %rdi
237         CFI_ADJUST_CFA_OFFSET 8
238         call schedule
239         popq  %rdi
240         CFI_ADJUST_CFA_OFFSET -8
241         jmp sysret_check
242
243         /* Handle a signal */ 
244 sysret_signal:
245         sti
246         testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx
247         jz    1f
248
249         /* Really a signal */
250         /* edx: work flags (arg3) */
251         leaq do_notify_resume(%rip),%rax
252         leaq -ARGOFFSET(%rsp),%rdi # &pt_regs -> arg1
253         xorl %esi,%esi # oldset -> arg2
254         call ptregscall_common
255 1:      movl $_TIF_NEED_RESCHED,%edi
256         jmp sysret_check
257         
258 badsys:
259         movq $-ENOSYS,RAX-ARGOFFSET(%rsp)
260         jmp ret_from_sys_call
261
262         /* Do syscall tracing */
263 tracesys:                        
264         CFI_RESTORE_STATE
265         SAVE_REST
266         movq $-ENOSYS,RAX(%rsp)
267         FIXUP_TOP_OF_STACK %rdi
268         movq %rsp,%rdi
269         call syscall_trace_enter
270         LOAD_ARGS ARGOFFSET  /* reload args from stack in case ptrace changed it */
271         RESTORE_REST
272         cmpq $__NR_syscall_max,%rax
273         ja  1f
274         movq %r10,%rcx  /* fixup for C */
275         call *sys_call_table(,%rax,8)
276         movq %rax,RAX-ARGOFFSET(%rsp)
277 1:      SAVE_REST
278         movq %rsp,%rdi
279         call syscall_trace_leave
280         RESTORE_TOP_OF_STACK %rbx
281         RESTORE_REST
282         jmp ret_from_sys_call
283         CFI_ENDPROC
284                 
285 /* 
286  * Syscall return path ending with IRET.
287  * Has correct top of stack, but partial stack frame.
288  */     
289 ENTRY(int_ret_from_sys_call)
290         CFI_STARTPROC   simple
291         CFI_DEF_CFA     rsp,SS+8-ARGOFFSET
292         /*CFI_REL_OFFSET        ss,SS-ARGOFFSET*/
293         CFI_REL_OFFSET  rsp,RSP-ARGOFFSET
294         /*CFI_REL_OFFSET        rflags,EFLAGS-ARGOFFSET*/
295         /*CFI_REL_OFFSET        cs,CS-ARGOFFSET*/
296         CFI_REL_OFFSET  rip,RIP-ARGOFFSET
297         CFI_REL_OFFSET  rdx,RDX-ARGOFFSET
298         CFI_REL_OFFSET  rcx,RCX-ARGOFFSET
299         CFI_REL_OFFSET  rax,RAX-ARGOFFSET
300         CFI_REL_OFFSET  rdi,RDI-ARGOFFSET
301         CFI_REL_OFFSET  rsi,RSI-ARGOFFSET
302         CFI_REL_OFFSET  r8,R8-ARGOFFSET
303         CFI_REL_OFFSET  r9,R9-ARGOFFSET
304         CFI_REL_OFFSET  r10,R10-ARGOFFSET
305         CFI_REL_OFFSET  r11,R11-ARGOFFSET
306         cli
307         testl $3,CS-ARGOFFSET(%rsp)
308         je retint_restore_args
309         movl $_TIF_ALLWORK_MASK,%edi
310         /* edi: mask to check */
311 int_with_check:
312         GET_THREAD_INFO(%rcx)
313         movl threadinfo_flags(%rcx),%edx
314         andl %edi,%edx
315         jnz   int_careful
316         andl    $~TS_COMPAT,threadinfo_status(%rcx)
317         jmp   retint_swapgs
318
319         /* Either reschedule or signal or syscall exit tracking needed. */
320         /* First do a reschedule test. */
321         /* edx: work, edi: workmask */
322 int_careful:
323         bt $TIF_NEED_RESCHED,%edx
324         jnc  int_very_careful
325         sti
326         pushq %rdi
327         CFI_ADJUST_CFA_OFFSET 8
328         call schedule
329         popq %rdi
330         CFI_ADJUST_CFA_OFFSET -8
331         cli
332         jmp int_with_check
333
334         /* handle signals and tracing -- both require a full stack frame */
335 int_very_careful:
336         sti
337         SAVE_REST
338         /* Check for syscall exit trace */      
339         testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edx
340         jz int_signal
341         pushq %rdi
342         CFI_ADJUST_CFA_OFFSET 8
343         leaq 8(%rsp),%rdi       # &ptregs -> arg1       
344         call syscall_trace_leave
345         popq %rdi
346         CFI_ADJUST_CFA_OFFSET -8
347         andl $~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edi
348         cli
349         jmp int_restore_rest
350         
351 int_signal:
352         testl $(_TIF_NOTIFY_RESUME|_TIF_SIGPENDING|_TIF_SINGLESTEP),%edx
353         jz 1f
354         movq %rsp,%rdi          # &ptregs -> arg1
355         xorl %esi,%esi          # oldset -> arg2
356         call do_notify_resume
357 1:      movl $_TIF_NEED_RESCHED,%edi    
358 int_restore_rest:
359         RESTORE_REST
360         cli
361         jmp int_with_check
362         CFI_ENDPROC
363                 
364 /* 
365  * Certain special system calls that need to save a complete full stack frame.
366  */                                                             
367         
368         .macro PTREGSCALL label,func,arg
369         .globl \label
370 \label:
371         leaq    \func(%rip),%rax
372         leaq    -ARGOFFSET+8(%rsp),\arg /* 8 for return address */
373         jmp     ptregscall_common
374         .endm
375
376         CFI_STARTPROC
377
378         PTREGSCALL stub_clone, sys_clone, %r8
379         PTREGSCALL stub_fork, sys_fork, %rdi
380         PTREGSCALL stub_vfork, sys_vfork, %rdi
381         PTREGSCALL stub_rt_sigsuspend, sys_rt_sigsuspend, %rdx
382         PTREGSCALL stub_sigaltstack, sys_sigaltstack, %rdx
383         PTREGSCALL stub_iopl, sys_iopl, %rsi
384
385 ENTRY(ptregscall_common)
386         popq %r11
387         CFI_ADJUST_CFA_OFFSET -8
388         CFI_REGISTER rip, r11
389         SAVE_REST
390         movq %r11, %r15
391         CFI_REGISTER rip, r15
392         FIXUP_TOP_OF_STACK %r11
393         call *%rax
394         RESTORE_TOP_OF_STACK %r11
395         movq %r15, %r11
396         CFI_REGISTER rip, r11
397         RESTORE_REST
398         pushq %r11
399         CFI_ADJUST_CFA_OFFSET 8
400         CFI_REL_OFFSET rip, 0
401         ret
402         CFI_ENDPROC
403         
404 ENTRY(stub_execve)
405         CFI_STARTPROC
406         popq %r11
407         CFI_ADJUST_CFA_OFFSET -8
408         CFI_REGISTER rip, r11
409         SAVE_REST
410         movq %r11, %r15
411         CFI_REGISTER rip, r15
412         FIXUP_TOP_OF_STACK %r11
413         call sys_execve
414         GET_THREAD_INFO(%rcx)
415         bt $TIF_IA32,threadinfo_flags(%rcx)
416         CFI_REMEMBER_STATE
417         jc exec_32bit
418         RESTORE_TOP_OF_STACK %r11
419         movq %r15, %r11
420         CFI_REGISTER rip, r11
421         RESTORE_REST
422         pushq %r11
423         CFI_ADJUST_CFA_OFFSET 8
424         CFI_REL_OFFSET rip, 0
425         ret
426
427 exec_32bit:
428         CFI_RESTORE_STATE
429         movq %rax,RAX(%rsp)
430         RESTORE_REST
431         jmp int_ret_from_sys_call
432         CFI_ENDPROC
433         
434 /*
435  * sigreturn is special because it needs to restore all registers on return.
436  * This cannot be done with SYSRET, so use the IRET return path instead.
437  */                
438 ENTRY(stub_rt_sigreturn)
439         CFI_STARTPROC
440         addq $8, %rsp
441         CFI_ADJUST_CFA_OFFSET   -8
442         SAVE_REST
443         movq %rsp,%rdi
444         FIXUP_TOP_OF_STACK %r11
445         call sys_rt_sigreturn
446         movq %rax,RAX(%rsp) # fixme, this could be done at the higher layer
447         RESTORE_REST
448         jmp int_ret_from_sys_call
449         CFI_ENDPROC
450
451 /*
452  * initial frame state for interrupts and exceptions
453  */
454         .macro _frame ref
455         CFI_STARTPROC simple
456         CFI_DEF_CFA rsp,SS+8-\ref
457         /*CFI_REL_OFFSET ss,SS-\ref*/
458         CFI_REL_OFFSET rsp,RSP-\ref
459         /*CFI_REL_OFFSET rflags,EFLAGS-\ref*/
460         /*CFI_REL_OFFSET cs,CS-\ref*/
461         CFI_REL_OFFSET rip,RIP-\ref
462         .endm
463
464 /* initial frame state for interrupts (and exceptions without error code) */
465 #define INTR_FRAME _frame RIP
466 /* initial frame state for exceptions with error code (and interrupts with
467    vector already pushed) */
468 #define XCPT_FRAME _frame ORIG_RAX
469
470 /* 
471  * Interrupt entry/exit.
472  *
473  * Interrupt entry points save only callee clobbered registers in fast path.
474  *      
475  * Entry runs with interrupts off.      
476  */ 
477
478 /* 0(%rsp): interrupt number */ 
479         .macro interrupt func
480         cld
481 #ifdef CONFIG_DEBUG_INFO
482         SAVE_ALL        
483         movq %rsp,%rdi
484         /*
485          * Setup a stack frame pointer.  This allows gdb to trace
486          * back to the original stack.
487          */
488         movq %rsp,%rbp
489         CFI_DEF_CFA_REGISTER    rbp
490 #else           
491         SAVE_ARGS
492         leaq -ARGOFFSET(%rsp),%rdi      # arg1 for handler
493 #endif  
494         testl $3,CS(%rdi)
495         je 1f
496         swapgs  
497 1:      incl    %gs:pda_irqcount        # RED-PEN should check preempt count
498         movq %gs:pda_irqstackptr,%rax
499         cmoveq %rax,%rsp /*todo This needs CFI annotation! */
500         pushq %rdi                      # save old stack        
501         CFI_ADJUST_CFA_OFFSET   8
502         call \func
503         .endm
504
505 ENTRY(common_interrupt)
506         XCPT_FRAME
507         interrupt do_IRQ
508         /* 0(%rsp): oldrsp-ARGOFFSET */
509 ret_from_intr:
510         popq  %rdi
511         CFI_ADJUST_CFA_OFFSET   -8
512         cli     
513         decl %gs:pda_irqcount
514 #ifdef CONFIG_DEBUG_INFO
515         movq RBP(%rdi),%rbp
516         CFI_DEF_CFA_REGISTER    rsp
517 #endif
518         leaq ARGOFFSET(%rdi),%rsp /*todo This needs CFI annotation! */
519 exit_intr:
520         GET_THREAD_INFO(%rcx)
521         testl $3,CS-ARGOFFSET(%rsp)
522         je retint_kernel
523         
524         /* Interrupt came from user space */
525         /*
526          * Has a correct top of stack, but a partial stack frame
527          * %rcx: thread info. Interrupts off.
528          */             
529 retint_with_reschedule:
530         movl $_TIF_WORK_MASK,%edi
531 retint_check:
532         movl threadinfo_flags(%rcx),%edx
533         andl %edi,%edx
534         CFI_REMEMBER_STATE
535         jnz  retint_careful
536 retint_swapgs:          
537         swapgs 
538 retint_restore_args:                            
539         cli
540         RESTORE_ARGS 0,8,0                                              
541 iret_label:     
542         iretq
543
544         .section __ex_table,"a"
545         .quad iret_label,bad_iret       
546         .previous
547         .section .fixup,"ax"
548         /* force a signal here? this matches i386 behaviour */
549         /* running with kernel gs */
550 bad_iret:
551         movq $-9999,%rdi        /* better code? */
552         jmp do_exit                     
553         .previous       
554         
555         /* edi: workmask, edx: work */
556 retint_careful:
557         CFI_RESTORE_STATE
558         bt    $TIF_NEED_RESCHED,%edx
559         jnc   retint_signal
560         sti
561         pushq %rdi
562         CFI_ADJUST_CFA_OFFSET   8
563         call  schedule
564         popq %rdi               
565         CFI_ADJUST_CFA_OFFSET   -8
566         GET_THREAD_INFO(%rcx)
567         cli
568         jmp retint_check
569         
570 retint_signal:
571         testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx
572         jz    retint_swapgs
573         sti
574         SAVE_REST
575         movq $-1,ORIG_RAX(%rsp)                         
576         xorl %esi,%esi          # oldset
577         movq %rsp,%rdi          # &pt_regs
578         call do_notify_resume
579         RESTORE_REST
580         cli
581         movl $_TIF_NEED_RESCHED,%edi
582         GET_THREAD_INFO(%rcx)
583         jmp retint_check
584
585 #ifdef CONFIG_PREEMPT
586         /* Returning to kernel space. Check if we need preemption */
587         /* rcx:  threadinfo. interrupts off. */
588         .p2align
589 retint_kernel:  
590         cmpl $0,threadinfo_preempt_count(%rcx)
591         jnz  retint_restore_args
592         bt  $TIF_NEED_RESCHED,threadinfo_flags(%rcx)
593         jnc  retint_restore_args
594         bt   $9,EFLAGS-ARGOFFSET(%rsp)  /* interrupts off? */
595         jnc  retint_restore_args
596         call preempt_schedule_irq
597         jmp exit_intr
598 #endif  
599         CFI_ENDPROC
600         
601 /*
602  * APIC interrupts.
603  */             
604         .macro apicinterrupt num,func
605         INTR_FRAME
606         pushq $\num-256
607         CFI_ADJUST_CFA_OFFSET 8
608         interrupt \func
609         jmp ret_from_intr
610         CFI_ENDPROC
611         .endm
612
613 ENTRY(thermal_interrupt)
614         apicinterrupt THERMAL_APIC_VECTOR,smp_thermal_interrupt
615
616 ENTRY(threshold_interrupt)
617         apicinterrupt THRESHOLD_APIC_VECTOR,mce_threshold_interrupt
618
619 #ifdef CONFIG_SMP       
620 ENTRY(reschedule_interrupt)
621         apicinterrupt RESCHEDULE_VECTOR,smp_reschedule_interrupt
622
623         .macro INVALIDATE_ENTRY num
624 ENTRY(invalidate_interrupt\num)
625         apicinterrupt INVALIDATE_TLB_VECTOR_START+\num,smp_invalidate_interrupt 
626         .endm
627
628         INVALIDATE_ENTRY 0
629         INVALIDATE_ENTRY 1
630         INVALIDATE_ENTRY 2
631         INVALIDATE_ENTRY 3
632         INVALIDATE_ENTRY 4
633         INVALIDATE_ENTRY 5
634         INVALIDATE_ENTRY 6
635         INVALIDATE_ENTRY 7
636
637 ENTRY(call_function_interrupt)
638         apicinterrupt CALL_FUNCTION_VECTOR,smp_call_function_interrupt
639 #endif
640
641 #ifdef CONFIG_X86_LOCAL_APIC    
642 ENTRY(apic_timer_interrupt)
643         apicinterrupt LOCAL_TIMER_VECTOR,smp_apic_timer_interrupt
644
645 ENTRY(error_interrupt)
646         apicinterrupt ERROR_APIC_VECTOR,smp_error_interrupt
647
648 ENTRY(spurious_interrupt)
649         apicinterrupt SPURIOUS_APIC_VECTOR,smp_spurious_interrupt
650 #endif
651                                 
652 /*
653  * Exception entry points.
654  */             
655         .macro zeroentry sym
656         INTR_FRAME
657         pushq $0        /* push error code/oldrax */ 
658         CFI_ADJUST_CFA_OFFSET 8
659         pushq %rax      /* push real oldrax to the rdi slot */ 
660         CFI_ADJUST_CFA_OFFSET 8
661         leaq  \sym(%rip),%rax
662         jmp error_entry
663         CFI_ENDPROC
664         .endm   
665
666         .macro errorentry sym
667         XCPT_FRAME
668         pushq %rax
669         CFI_ADJUST_CFA_OFFSET 8
670         leaq  \sym(%rip),%rax
671         jmp error_entry
672         CFI_ENDPROC
673         .endm
674
675         /* error code is on the stack already */
676         /* handle NMI like exceptions that can happen everywhere */
677 #ifndef DEBUG_IST
678 # define DEBUG_IST 0
679 #endif
680         .macro paranoidentry sym, ist=0
681         SAVE_ALL
682         cld
683         movl $1,%ebx
684         movl  $MSR_GS_BASE,%ecx
685         rdmsr
686         testl %edx,%edx
687         js    1f
688         swapgs
689         xorl  %ebx,%ebx
690 1:
691         .if \ist
692         movq    %gs:pda_data_offset, %rbp
693         .endif
694         movq %rsp,%rdi
695         movq ORIG_RAX(%rsp),%rsi
696         movq $-1,ORIG_RAX(%rsp)
697         .if \ist
698         subq    $EXCEPTION_STACK_SIZE, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
699         .endif
700         call \sym
701         .if \ist
702         addq    $EXCEPTION_STACK_SIZE, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
703         .endif
704         cli
705         .endm
706         
707 /*
708  * Exception entry point. This expects an error code/orig_rax on the stack
709  * and the exception handler in %rax.   
710  */                                             
711 ENTRY(error_entry)
712         _frame RDI
713         /* rdi slot contains rax, oldrax contains error code */
714         cld     
715         subq  $14*8,%rsp
716         CFI_ADJUST_CFA_OFFSET   (14*8)
717         movq %rsi,13*8(%rsp)
718         CFI_REL_OFFSET  rsi,RSI
719         movq 14*8(%rsp),%rsi    /* load rax from rdi slot */
720         movq %rdx,12*8(%rsp)
721         CFI_REL_OFFSET  rdx,RDX
722         movq %rcx,11*8(%rsp)
723         CFI_REL_OFFSET  rcx,RCX
724         movq %rsi,10*8(%rsp)    /* store rax */ 
725         CFI_REL_OFFSET  rax,RAX
726         movq %r8, 9*8(%rsp)
727         CFI_REL_OFFSET  r8,R8
728         movq %r9, 8*8(%rsp)
729         CFI_REL_OFFSET  r9,R9
730         movq %r10,7*8(%rsp)
731         CFI_REL_OFFSET  r10,R10
732         movq %r11,6*8(%rsp)
733         CFI_REL_OFFSET  r11,R11
734         movq %rbx,5*8(%rsp) 
735         CFI_REL_OFFSET  rbx,RBX
736         movq %rbp,4*8(%rsp) 
737         CFI_REL_OFFSET  rbp,RBP
738         movq %r12,3*8(%rsp) 
739         CFI_REL_OFFSET  r12,R12
740         movq %r13,2*8(%rsp) 
741         CFI_REL_OFFSET  r13,R13
742         movq %r14,1*8(%rsp) 
743         CFI_REL_OFFSET  r14,R14
744         movq %r15,(%rsp) 
745         CFI_REL_OFFSET  r15,R15
746         xorl %ebx,%ebx  
747         testl $3,CS(%rsp)
748         je  error_kernelspace
749 error_swapgs:   
750         swapgs
751 error_sti:      
752         movq %rdi,RDI(%rsp)     
753         movq %rsp,%rdi
754         movq ORIG_RAX(%rsp),%rsi        /* get error code */ 
755         movq $-1,ORIG_RAX(%rsp)
756         call *%rax
757         /* ebx: no swapgs flag (1: don't need swapgs, 0: need it) */     
758 error_exit:             
759         movl %ebx,%eax          
760         RESTORE_REST
761         cli
762         GET_THREAD_INFO(%rcx)   
763         testl %eax,%eax
764         jne  retint_kernel
765         movl  threadinfo_flags(%rcx),%edx
766         movl  $_TIF_WORK_MASK,%edi
767         andl  %edi,%edx
768         jnz  retint_careful
769         swapgs 
770         RESTORE_ARGS 0,8,0                                              
771         jmp iret_label
772         CFI_ENDPROC
773
774 error_kernelspace:
775         incl %ebx
776        /* There are two places in the kernel that can potentially fault with
777           usergs. Handle them here. The exception handlers after
778            iret run with kernel gs again, so don't set the user space flag.
779            B stepping K8s sometimes report an truncated RIP for IRET 
780            exceptions returning to compat mode. Check for these here too. */
781         leaq iret_label(%rip),%rbp
782         cmpq %rbp,RIP(%rsp) 
783         je   error_swapgs
784         movl %ebp,%ebp  /* zero extend */
785         cmpq %rbp,RIP(%rsp) 
786         je   error_swapgs
787         cmpq $gs_change,RIP(%rsp)
788         je   error_swapgs
789         jmp  error_sti
790         
791        /* Reload gs selector with exception handling */
792        /* edi:  new selector */ 
793 ENTRY(load_gs_index)
794         CFI_STARTPROC
795         pushf
796         CFI_ADJUST_CFA_OFFSET 8
797         cli
798         swapgs
799 gs_change:     
800         movl %edi,%gs   
801 2:      mfence          /* workaround */
802         swapgs
803         popf
804         CFI_ADJUST_CFA_OFFSET -8
805         ret
806         CFI_ENDPROC
807        
808         .section __ex_table,"a"
809         .align 8
810         .quad gs_change,bad_gs
811         .previous
812         .section .fixup,"ax"
813         /* running with kernelgs */
814 bad_gs: 
815         swapgs                  /* switch back to user gs */
816         xorl %eax,%eax
817         movl %eax,%gs
818         jmp  2b
819         .previous       
820         
821 /*
822  * Create a kernel thread.
823  *
824  * C extern interface:
825  *      extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
826  *
827  * asm input arguments:
828  *      rdi: fn, rsi: arg, rdx: flags
829  */
830 ENTRY(kernel_thread)
831         CFI_STARTPROC
832         FAKE_STACK_FRAME $child_rip
833         SAVE_ALL
834
835         # rdi: flags, rsi: usp, rdx: will be &pt_regs
836         movq %rdx,%rdi
837         orq  kernel_thread_flags(%rip),%rdi
838         movq $-1, %rsi
839         movq %rsp, %rdx
840
841         xorl %r8d,%r8d
842         xorl %r9d,%r9d
843         
844         # clone now
845         call do_fork
846         movq %rax,RAX(%rsp)
847         xorl %edi,%edi
848
849         /*
850          * It isn't worth to check for reschedule here,
851          * so internally to the x86_64 port you can rely on kernel_thread()
852          * not to reschedule the child before returning, this avoids the need
853          * of hacks for example to fork off the per-CPU idle tasks.
854          * [Hopefully no generic code relies on the reschedule -AK]     
855          */
856         RESTORE_ALL
857         UNFAKE_STACK_FRAME
858         ret
859         CFI_ENDPROC
860
861         
862 child_rip:
863         /*
864          * Here we are in the child and the registers are set as they were
865          * at kernel_thread() invocation in the parent.
866          */
867         movq %rdi, %rax
868         movq %rsi, %rdi
869         call *%rax
870         # exit
871         xorl %edi, %edi
872         call do_exit
873
874 /*
875  * execve(). This function needs to use IRET, not SYSRET, to set up all state properly.
876  *
877  * C extern interface:
878  *       extern long execve(char *name, char **argv, char **envp)
879  *
880  * asm input arguments:
881  *      rdi: name, rsi: argv, rdx: envp
882  *
883  * We want to fallback into:
884  *      extern long sys_execve(char *name, char **argv,char **envp, struct pt_regs regs)
885  *
886  * do_sys_execve asm fallback arguments:
887  *      rdi: name, rsi: argv, rdx: envp, fake frame on the stack
888  */
889 ENTRY(execve)
890         CFI_STARTPROC
891         FAKE_STACK_FRAME $0
892         SAVE_ALL        
893         call sys_execve
894         movq %rax, RAX(%rsp)    
895         RESTORE_REST
896         testq %rax,%rax
897         je int_ret_from_sys_call
898         RESTORE_ARGS
899         UNFAKE_STACK_FRAME
900         ret
901         CFI_ENDPROC
902
903 KPROBE_ENTRY(page_fault)
904         errorentry do_page_fault
905         .previous .text
906
907 ENTRY(coprocessor_error)
908         zeroentry do_coprocessor_error
909
910 ENTRY(simd_coprocessor_error)
911         zeroentry do_simd_coprocessor_error     
912
913 ENTRY(device_not_available)
914         zeroentry math_state_restore
915
916         /* runs on exception stack */
917 KPROBE_ENTRY(debug)
918         INTR_FRAME
919         pushq $0
920         CFI_ADJUST_CFA_OFFSET 8         
921         paranoidentry do_debug, DEBUG_IST
922         jmp paranoid_exit
923         CFI_ENDPROC
924         .previous .text
925
926         /* runs on exception stack */   
927 ENTRY(nmi)
928         INTR_FRAME
929         pushq $-1
930         CFI_ADJUST_CFA_OFFSET 8
931         paranoidentry do_nmi
932         /*
933          * "Paranoid" exit path from exception stack.
934          * Paranoid because this is used by NMIs and cannot take
935          * any kernel state for granted.
936          * We don't do kernel preemption checks here, because only
937          * NMI should be common and it does not enable IRQs and
938          * cannot get reschedule ticks.
939          */
940         /* ebx: no swapgs flag */
941 paranoid_exit:
942         testl %ebx,%ebx                         /* swapgs needed? */
943         jnz paranoid_restore
944         testl $3,CS(%rsp)
945         jnz   paranoid_userspace
946 paranoid_swapgs:        
947         swapgs
948 paranoid_restore:       
949         RESTORE_ALL 8
950         iretq
951 paranoid_userspace:     
952         GET_THREAD_INFO(%rcx)
953         movl threadinfo_flags(%rcx),%ebx
954         andl $_TIF_WORK_MASK,%ebx
955         jz paranoid_swapgs
956         movq %rsp,%rdi                  /* &pt_regs */
957         call sync_regs
958         movq %rax,%rsp                  /* switch stack for scheduling */
959         testl $_TIF_NEED_RESCHED,%ebx
960         jnz paranoid_schedule
961         movl %ebx,%edx                  /* arg3: thread flags */
962         sti
963         xorl %esi,%esi                  /* arg2: oldset */
964         movq %rsp,%rdi                  /* arg1: &pt_regs */
965         call do_notify_resume
966         cli
967         jmp paranoid_userspace
968 paranoid_schedule:
969         sti
970         call schedule
971         cli
972         jmp paranoid_userspace
973         CFI_ENDPROC
974
975 KPROBE_ENTRY(int3)
976         INTR_FRAME
977         pushq $0
978         CFI_ADJUST_CFA_OFFSET 8
979         paranoidentry do_int3, DEBUG_IST
980         jmp paranoid_exit
981         CFI_ENDPROC
982         .previous .text
983
984 ENTRY(overflow)
985         zeroentry do_overflow
986
987 ENTRY(bounds)
988         zeroentry do_bounds
989
990 ENTRY(invalid_op)
991         zeroentry do_invalid_op 
992
993 ENTRY(coprocessor_segment_overrun)
994         zeroentry do_coprocessor_segment_overrun
995
996 ENTRY(reserved)
997         zeroentry do_reserved
998
999         /* runs on exception stack */
1000 ENTRY(double_fault)
1001         XCPT_FRAME
1002         paranoidentry do_double_fault
1003         jmp paranoid_exit
1004         CFI_ENDPROC
1005
1006 ENTRY(invalid_TSS)
1007         errorentry do_invalid_TSS
1008
1009 ENTRY(segment_not_present)
1010         errorentry do_segment_not_present
1011
1012         /* runs on exception stack */
1013 ENTRY(stack_segment)
1014         XCPT_FRAME
1015         paranoidentry do_stack_segment
1016         jmp paranoid_exit
1017         CFI_ENDPROC
1018
1019 KPROBE_ENTRY(general_protection)
1020         errorentry do_general_protection
1021         .previous .text
1022
1023 ENTRY(alignment_check)
1024         errorentry do_alignment_check
1025
1026 ENTRY(divide_error)
1027         zeroentry do_divide_error
1028
1029 ENTRY(spurious_interrupt_bug)
1030         zeroentry do_spurious_interrupt_bug
1031
1032 #ifdef CONFIG_X86_MCE
1033         /* runs on exception stack */
1034 ENTRY(machine_check)
1035         INTR_FRAME
1036         pushq $0
1037         CFI_ADJUST_CFA_OFFSET 8 
1038         paranoidentry do_machine_check
1039         jmp paranoid_exit
1040         CFI_ENDPROC
1041 #endif
1042
1043 ENTRY(call_softirq)
1044         CFI_STARTPROC
1045         movq %gs:pda_irqstackptr,%rax
1046         movq %rsp,%rdx
1047         CFI_DEF_CFA_REGISTER    rdx
1048         incl %gs:pda_irqcount
1049         cmove %rax,%rsp
1050         pushq %rdx
1051         /*todo CFI_DEF_CFA_EXPRESSION ...*/
1052         call __do_softirq
1053         popq %rsp
1054         CFI_DEF_CFA_REGISTER    rsp
1055         decl %gs:pda_irqcount
1056         ret
1057         CFI_ENDPROC