[PATCH] x86_64: Don't call do_exit with interrupts disabled after IRET exception
[linux-2.6] / arch / x86_64 / kernel / entry.S
1 /*
2  *  linux/arch/x86_64/entry.S
3  *
4  *  Copyright (C) 1991, 1992  Linus Torvalds
5  *  Copyright (C) 2000, 2001, 2002  Andi Kleen SuSE Labs
6  *  Copyright (C) 2000  Pavel Machek <pavel@suse.cz>
7  * 
8  *  $Id$
9  */
10
11 /*
12  * entry.S contains the system-call and fault low-level handling routines.
13  *
14  * NOTE: This code handles signal-recognition, which happens every time
15  * after an interrupt and after each system call.
16  * 
17  * Normal syscalls and interrupts don't save a full stack frame, this is 
18  * only done for syscall tracing, signals or fork/exec et.al.
19  * 
20  * A note on terminology:        
21  * - top of stack: Architecture defined interrupt frame from SS to RIP 
22  * at the top of the kernel process stack.      
23  * - partial stack frame: partially saved registers upto R11.
24  * - full stack frame: Like partial stack frame, but all register saved. 
25  *      
26  * TODO:         
27  * - schedule it carefully for the final hardware.
28  */
29
30 #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         sti
558         jmp do_exit                     
559         .previous       
560         
561         /* edi: workmask, edx: work */
562 retint_careful:
563         CFI_RESTORE_STATE
564         bt    $TIF_NEED_RESCHED,%edx
565         jnc   retint_signal
566         sti
567         pushq %rdi
568         CFI_ADJUST_CFA_OFFSET   8
569         call  schedule
570         popq %rdi               
571         CFI_ADJUST_CFA_OFFSET   -8
572         GET_THREAD_INFO(%rcx)
573         cli
574         jmp retint_check
575         
576 retint_signal:
577         testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx
578         jz    retint_swapgs
579         sti
580         SAVE_REST
581         movq $-1,ORIG_RAX(%rsp)                         
582         xorl %esi,%esi          # oldset
583         movq %rsp,%rdi          # &pt_regs
584         call do_notify_resume
585         RESTORE_REST
586         cli
587         movl $_TIF_NEED_RESCHED,%edi
588         GET_THREAD_INFO(%rcx)
589         jmp retint_check
590
591 #ifdef CONFIG_PREEMPT
592         /* Returning to kernel space. Check if we need preemption */
593         /* rcx:  threadinfo. interrupts off. */
594         .p2align
595 retint_kernel:  
596         cmpl $0,threadinfo_preempt_count(%rcx)
597         jnz  retint_restore_args
598         bt  $TIF_NEED_RESCHED,threadinfo_flags(%rcx)
599         jnc  retint_restore_args
600         bt   $9,EFLAGS-ARGOFFSET(%rsp)  /* interrupts off? */
601         jnc  retint_restore_args
602         call preempt_schedule_irq
603         jmp exit_intr
604 #endif  
605         CFI_ENDPROC
606         
607 /*
608  * APIC interrupts.
609  */             
610         .macro apicinterrupt num,func
611         INTR_FRAME
612         pushq $\num-256
613         CFI_ADJUST_CFA_OFFSET 8
614         interrupt \func
615         jmp ret_from_intr
616         CFI_ENDPROC
617         .endm
618
619 ENTRY(thermal_interrupt)
620         apicinterrupt THERMAL_APIC_VECTOR,smp_thermal_interrupt
621
622 ENTRY(threshold_interrupt)
623         apicinterrupt THRESHOLD_APIC_VECTOR,mce_threshold_interrupt
624
625 #ifdef CONFIG_SMP       
626 ENTRY(reschedule_interrupt)
627         apicinterrupt RESCHEDULE_VECTOR,smp_reschedule_interrupt
628
629         .macro INVALIDATE_ENTRY num
630 ENTRY(invalidate_interrupt\num)
631         apicinterrupt INVALIDATE_TLB_VECTOR_START+\num,smp_invalidate_interrupt 
632         .endm
633
634         INVALIDATE_ENTRY 0
635         INVALIDATE_ENTRY 1
636         INVALIDATE_ENTRY 2
637         INVALIDATE_ENTRY 3
638         INVALIDATE_ENTRY 4
639         INVALIDATE_ENTRY 5
640         INVALIDATE_ENTRY 6
641         INVALIDATE_ENTRY 7
642
643 ENTRY(call_function_interrupt)
644         apicinterrupt CALL_FUNCTION_VECTOR,smp_call_function_interrupt
645 #endif
646
647 #ifdef CONFIG_X86_LOCAL_APIC    
648 ENTRY(apic_timer_interrupt)
649         apicinterrupt LOCAL_TIMER_VECTOR,smp_apic_timer_interrupt
650
651 ENTRY(error_interrupt)
652         apicinterrupt ERROR_APIC_VECTOR,smp_error_interrupt
653
654 ENTRY(spurious_interrupt)
655         apicinterrupt SPURIOUS_APIC_VECTOR,smp_spurious_interrupt
656 #endif
657                                 
658 /*
659  * Exception entry points.
660  */             
661         .macro zeroentry sym
662         INTR_FRAME
663         pushq $0        /* push error code/oldrax */ 
664         CFI_ADJUST_CFA_OFFSET 8
665         pushq %rax      /* push real oldrax to the rdi slot */ 
666         CFI_ADJUST_CFA_OFFSET 8
667         leaq  \sym(%rip),%rax
668         jmp error_entry
669         CFI_ENDPROC
670         .endm   
671
672         .macro errorentry sym
673         XCPT_FRAME
674         pushq %rax
675         CFI_ADJUST_CFA_OFFSET 8
676         leaq  \sym(%rip),%rax
677         jmp error_entry
678         CFI_ENDPROC
679         .endm
680
681         /* error code is on the stack already */
682         /* handle NMI like exceptions that can happen everywhere */
683         .macro paranoidentry sym, ist=0
684         SAVE_ALL
685         cld
686         movl $1,%ebx
687         movl  $MSR_GS_BASE,%ecx
688         rdmsr
689         testl %edx,%edx
690         js    1f
691         swapgs
692         xorl  %ebx,%ebx
693 1:
694         .if \ist
695         movq    %gs:pda_data_offset, %rbp
696         .endif
697         movq %rsp,%rdi
698         movq ORIG_RAX(%rsp),%rsi
699         movq $-1,ORIG_RAX(%rsp)
700         .if \ist
701         subq    $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
702         .endif
703         call \sym
704         .if \ist
705         addq    $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
706         .endif
707         cli
708         .endm
709         
710 /*
711  * Exception entry point. This expects an error code/orig_rax on the stack
712  * and the exception handler in %rax.   
713  */                                             
714 ENTRY(error_entry)
715         _frame RDI
716         /* rdi slot contains rax, oldrax contains error code */
717         cld     
718         subq  $14*8,%rsp
719         CFI_ADJUST_CFA_OFFSET   (14*8)
720         movq %rsi,13*8(%rsp)
721         CFI_REL_OFFSET  rsi,RSI
722         movq 14*8(%rsp),%rsi    /* load rax from rdi slot */
723         movq %rdx,12*8(%rsp)
724         CFI_REL_OFFSET  rdx,RDX
725         movq %rcx,11*8(%rsp)
726         CFI_REL_OFFSET  rcx,RCX
727         movq %rsi,10*8(%rsp)    /* store rax */ 
728         CFI_REL_OFFSET  rax,RAX
729         movq %r8, 9*8(%rsp)
730         CFI_REL_OFFSET  r8,R8
731         movq %r9, 8*8(%rsp)
732         CFI_REL_OFFSET  r9,R9
733         movq %r10,7*8(%rsp)
734         CFI_REL_OFFSET  r10,R10
735         movq %r11,6*8(%rsp)
736         CFI_REL_OFFSET  r11,R11
737         movq %rbx,5*8(%rsp) 
738         CFI_REL_OFFSET  rbx,RBX
739         movq %rbp,4*8(%rsp) 
740         CFI_REL_OFFSET  rbp,RBP
741         movq %r12,3*8(%rsp) 
742         CFI_REL_OFFSET  r12,R12
743         movq %r13,2*8(%rsp) 
744         CFI_REL_OFFSET  r13,R13
745         movq %r14,1*8(%rsp) 
746         CFI_REL_OFFSET  r14,R14
747         movq %r15,(%rsp) 
748         CFI_REL_OFFSET  r15,R15
749         xorl %ebx,%ebx  
750         testl $3,CS(%rsp)
751         je  error_kernelspace
752 error_swapgs:   
753         swapgs
754 error_sti:      
755         movq %rdi,RDI(%rsp)     
756         movq %rsp,%rdi
757         movq ORIG_RAX(%rsp),%rsi        /* get error code */ 
758         movq $-1,ORIG_RAX(%rsp)
759         call *%rax
760         /* ebx: no swapgs flag (1: don't need swapgs, 0: need it) */     
761 error_exit:             
762         movl %ebx,%eax          
763         RESTORE_REST
764         cli
765         GET_THREAD_INFO(%rcx)   
766         testl %eax,%eax
767         jne  retint_kernel
768         movl  threadinfo_flags(%rcx),%edx
769         movl  $_TIF_WORK_MASK,%edi
770         andl  %edi,%edx
771         jnz  retint_careful
772         swapgs 
773         RESTORE_ARGS 0,8,0                                              
774         jmp iret_label
775         CFI_ENDPROC
776
777 error_kernelspace:
778         incl %ebx
779        /* There are two places in the kernel that can potentially fault with
780           usergs. Handle them here. The exception handlers after
781            iret run with kernel gs again, so don't set the user space flag.
782            B stepping K8s sometimes report an truncated RIP for IRET 
783            exceptions returning to compat mode. Check for these here too. */
784         leaq iret_label(%rip),%rbp
785         cmpq %rbp,RIP(%rsp) 
786         je   error_swapgs
787         movl %ebp,%ebp  /* zero extend */
788         cmpq %rbp,RIP(%rsp) 
789         je   error_swapgs
790         cmpq $gs_change,RIP(%rsp)
791         je   error_swapgs
792         jmp  error_sti
793         
794        /* Reload gs selector with exception handling */
795        /* edi:  new selector */ 
796 ENTRY(load_gs_index)
797         CFI_STARTPROC
798         pushf
799         CFI_ADJUST_CFA_OFFSET 8
800         cli
801         swapgs
802 gs_change:     
803         movl %edi,%gs   
804 2:      mfence          /* workaround */
805         swapgs
806         popf
807         CFI_ADJUST_CFA_OFFSET -8
808         ret
809         CFI_ENDPROC
810        
811         .section __ex_table,"a"
812         .align 8
813         .quad gs_change,bad_gs
814         .previous
815         .section .fixup,"ax"
816         /* running with kernelgs */
817 bad_gs: 
818         swapgs                  /* switch back to user gs */
819         xorl %eax,%eax
820         movl %eax,%gs
821         jmp  2b
822         .previous       
823         
824 /*
825  * Create a kernel thread.
826  *
827  * C extern interface:
828  *      extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
829  *
830  * asm input arguments:
831  *      rdi: fn, rsi: arg, rdx: flags
832  */
833 ENTRY(kernel_thread)
834         CFI_STARTPROC
835         FAKE_STACK_FRAME $child_rip
836         SAVE_ALL
837
838         # rdi: flags, rsi: usp, rdx: will be &pt_regs
839         movq %rdx,%rdi
840         orq  kernel_thread_flags(%rip),%rdi
841         movq $-1, %rsi
842         movq %rsp, %rdx
843
844         xorl %r8d,%r8d
845         xorl %r9d,%r9d
846         
847         # clone now
848         call do_fork
849         movq %rax,RAX(%rsp)
850         xorl %edi,%edi
851
852         /*
853          * It isn't worth to check for reschedule here,
854          * so internally to the x86_64 port you can rely on kernel_thread()
855          * not to reschedule the child before returning, this avoids the need
856          * of hacks for example to fork off the per-CPU idle tasks.
857          * [Hopefully no generic code relies on the reschedule -AK]     
858          */
859         RESTORE_ALL
860         UNFAKE_STACK_FRAME
861         ret
862         CFI_ENDPROC
863
864         
865 child_rip:
866         /*
867          * Here we are in the child and the registers are set as they were
868          * at kernel_thread() invocation in the parent.
869          */
870         movq %rdi, %rax
871         movq %rsi, %rdi
872         call *%rax
873         # exit
874         xorl %edi, %edi
875         call do_exit
876
877 /*
878  * execve(). This function needs to use IRET, not SYSRET, to set up all state properly.
879  *
880  * C extern interface:
881  *       extern long execve(char *name, char **argv, char **envp)
882  *
883  * asm input arguments:
884  *      rdi: name, rsi: argv, rdx: envp
885  *
886  * We want to fallback into:
887  *      extern long sys_execve(char *name, char **argv,char **envp, struct pt_regs regs)
888  *
889  * do_sys_execve asm fallback arguments:
890  *      rdi: name, rsi: argv, rdx: envp, fake frame on the stack
891  */
892 ENTRY(execve)
893         CFI_STARTPROC
894         FAKE_STACK_FRAME $0
895         SAVE_ALL        
896         call sys_execve
897         movq %rax, RAX(%rsp)    
898         RESTORE_REST
899         testq %rax,%rax
900         je int_ret_from_sys_call
901         RESTORE_ARGS
902         UNFAKE_STACK_FRAME
903         ret
904         CFI_ENDPROC
905
906 KPROBE_ENTRY(page_fault)
907         errorentry do_page_fault
908         .previous .text
909
910 ENTRY(coprocessor_error)
911         zeroentry do_coprocessor_error
912
913 ENTRY(simd_coprocessor_error)
914         zeroentry do_simd_coprocessor_error     
915
916 ENTRY(device_not_available)
917         zeroentry math_state_restore
918
919         /* runs on exception stack */
920 KPROBE_ENTRY(debug)
921         INTR_FRAME
922         pushq $0
923         CFI_ADJUST_CFA_OFFSET 8         
924         paranoidentry do_debug, DEBUG_STACK
925         jmp paranoid_exit
926         CFI_ENDPROC
927         .previous .text
928
929         /* runs on exception stack */   
930 KPROBE_ENTRY(nmi)
931         INTR_FRAME
932         pushq $-1
933         CFI_ADJUST_CFA_OFFSET 8
934         paranoidentry do_nmi
935         /*
936          * "Paranoid" exit path from exception stack.
937          * Paranoid because this is used by NMIs and cannot take
938          * any kernel state for granted.
939          * We don't do kernel preemption checks here, because only
940          * NMI should be common and it does not enable IRQs and
941          * cannot get reschedule ticks.
942          */
943         /* ebx: no swapgs flag */
944 paranoid_exit:
945         testl %ebx,%ebx                         /* swapgs needed? */
946         jnz paranoid_restore
947         testl $3,CS(%rsp)
948         jnz   paranoid_userspace
949 paranoid_swapgs:        
950         swapgs
951 paranoid_restore:       
952         RESTORE_ALL 8
953         iretq
954 paranoid_userspace:     
955         GET_THREAD_INFO(%rcx)
956         movl threadinfo_flags(%rcx),%ebx
957         andl $_TIF_WORK_MASK,%ebx
958         jz paranoid_swapgs
959         movq %rsp,%rdi                  /* &pt_regs */
960         call sync_regs
961         movq %rax,%rsp                  /* switch stack for scheduling */
962         testl $_TIF_NEED_RESCHED,%ebx
963         jnz paranoid_schedule
964         movl %ebx,%edx                  /* arg3: thread flags */
965         sti
966         xorl %esi,%esi                  /* arg2: oldset */
967         movq %rsp,%rdi                  /* arg1: &pt_regs */
968         call do_notify_resume
969         cli
970         jmp paranoid_userspace
971 paranoid_schedule:
972         sti
973         call schedule
974         cli
975         jmp paranoid_userspace
976         CFI_ENDPROC
977         .previous .text
978
979 KPROBE_ENTRY(int3)
980         INTR_FRAME
981         pushq $0
982         CFI_ADJUST_CFA_OFFSET 8
983         paranoidentry do_int3, DEBUG_STACK
984         jmp paranoid_exit
985         CFI_ENDPROC
986         .previous .text
987
988 ENTRY(overflow)
989         zeroentry do_overflow
990
991 ENTRY(bounds)
992         zeroentry do_bounds
993
994 ENTRY(invalid_op)
995         zeroentry do_invalid_op 
996
997 ENTRY(coprocessor_segment_overrun)
998         zeroentry do_coprocessor_segment_overrun
999
1000 ENTRY(reserved)
1001         zeroentry do_reserved
1002
1003         /* runs on exception stack */
1004 ENTRY(double_fault)
1005         XCPT_FRAME
1006         paranoidentry do_double_fault
1007         jmp paranoid_exit
1008         CFI_ENDPROC
1009
1010 ENTRY(invalid_TSS)
1011         errorentry do_invalid_TSS
1012
1013 ENTRY(segment_not_present)
1014         errorentry do_segment_not_present
1015
1016         /* runs on exception stack */
1017 ENTRY(stack_segment)
1018         XCPT_FRAME
1019         paranoidentry do_stack_segment
1020         jmp paranoid_exit
1021         CFI_ENDPROC
1022
1023 KPROBE_ENTRY(general_protection)
1024         errorentry do_general_protection
1025         .previous .text
1026
1027 ENTRY(alignment_check)
1028         errorentry do_alignment_check
1029
1030 ENTRY(divide_error)
1031         zeroentry do_divide_error
1032
1033 ENTRY(spurious_interrupt_bug)
1034         zeroentry do_spurious_interrupt_bug
1035
1036 #ifdef CONFIG_X86_MCE
1037         /* runs on exception stack */
1038 ENTRY(machine_check)
1039         INTR_FRAME
1040         pushq $0
1041         CFI_ADJUST_CFA_OFFSET 8 
1042         paranoidentry do_machine_check
1043         jmp paranoid_exit
1044         CFI_ENDPROC
1045 #endif
1046
1047 ENTRY(call_softirq)
1048         CFI_STARTPROC
1049         movq %gs:pda_irqstackptr,%rax
1050         movq %rsp,%rdx
1051         CFI_DEF_CFA_REGISTER    rdx
1052         incl %gs:pda_irqcount
1053         cmove %rax,%rsp
1054         pushq %rdx
1055         /*todo CFI_DEF_CFA_EXPRESSION ...*/
1056         call __do_softirq
1057         popq %rsp
1058         CFI_DEF_CFA_REGISTER    rsp
1059         decl %gs:pda_irqcount
1060         ret
1061         CFI_ENDPROC