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