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