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