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