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