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