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