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