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