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