vserver 1.9.3
[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|_TIF_SINGLESTEP),%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         btr  $TIF_SINGLESTEP,%edi
309         jmp int_restore_rest
310         
311 int_signal:
312         testl $(_TIF_NOTIFY_RESUME|_TIF_SIGPENDING|_TIF_SINGLESTEP),%edx
313         jz 1f
314         movq %rsp,%rdi          # &ptregs -> arg1
315         xorl %esi,%esi          # oldset -> arg2
316         call do_notify_resume
317 1:      movl $_TIF_NEED_RESCHED,%edi    
318 int_restore_rest:
319         RESTORE_REST
320         jmp int_with_check
321         CFI_ENDPROC
322                 
323 /* 
324  * Certain special system calls that need to save a complete full stack frame.
325  */                                                             
326         
327         .macro PTREGSCALL label,func,arg
328         .globl \label
329 \label:
330         leaq    \func(%rip),%rax
331         leaq    -ARGOFFSET+8(%rsp),\arg /* 8 for return address */
332         jmp     ptregscall_common
333         .endm
334
335         PTREGSCALL stub_clone, sys_clone, %r8
336         PTREGSCALL stub_fork, sys_fork, %rdi
337         PTREGSCALL stub_vfork, sys_vfork, %rdi
338         PTREGSCALL stub_rt_sigsuspend, sys_rt_sigsuspend, %rdx
339         PTREGSCALL stub_sigaltstack, sys_sigaltstack, %rdx
340         PTREGSCALL stub_iopl, sys_iopl, %rsi
341
342 ENTRY(ptregscall_common)
343         CFI_STARTPROC
344         popq %r11
345         CFI_ADJUST_CFA_OFFSET   -8
346         SAVE_REST
347         movq %r11, %r15
348         FIXUP_TOP_OF_STACK %r11
349         call *%rax
350         RESTORE_TOP_OF_STACK %r11
351         movq %r15, %r11
352         RESTORE_REST
353         pushq %r11
354         CFI_ADJUST_CFA_OFFSET   8
355         ret
356         CFI_ENDPROC
357         
358 ENTRY(stub_execve)
359         CFI_STARTPROC
360         popq %r11
361         CFI_ADJUST_CFA_OFFSET   -8
362         SAVE_REST
363         movq %r11, %r15
364         FIXUP_TOP_OF_STACK %r11
365         call sys_execve
366         GET_THREAD_INFO(%rcx)
367         bt $TIF_IA32,threadinfo_flags(%rcx)
368         jc exec_32bit
369         RESTORE_TOP_OF_STACK %r11
370         movq %r15, %r11
371         RESTORE_REST
372         push %r11
373         ret
374
375 exec_32bit:
376         CFI_ADJUST_CFA_OFFSET   REST_SKIP
377         movq %rax,RAX(%rsp)
378         RESTORE_REST
379         jmp int_ret_from_sys_call
380         CFI_ENDPROC
381         
382 /*
383  * sigreturn is special because it needs to restore all registers on return.
384  * This cannot be done with SYSRET, so use the IRET return path instead.
385  */                
386 ENTRY(stub_rt_sigreturn)
387         CFI_STARTPROC
388         addq $8, %rsp           
389         SAVE_REST
390         movq %rsp,%rdi
391         FIXUP_TOP_OF_STACK %r11
392         call sys_rt_sigreturn
393         movq %rax,RAX(%rsp) # fixme, this could be done at the higher layer
394         RESTORE_REST
395         jmp int_ret_from_sys_call
396         CFI_ENDPROC
397
398 /* 
399  * Interrupt entry/exit.
400  *
401  * Interrupt entry points save only callee clobbered registers in fast path.
402  *      
403  * Entry runs with interrupts off.      
404  */ 
405
406 /* 0(%rsp): interrupt number */ 
407         .macro interrupt func
408         CFI_STARTPROC   simple
409         CFI_DEF_CFA     rsp,(SS-RDI)
410         CFI_REL_OFFSET  rsp,(RSP-ORIG_RAX)
411         CFI_REL_OFFSET  rip,(RIP-ORIG_RAX)
412         cld
413 #ifdef CONFIG_DEBUG_INFO
414         SAVE_ALL        
415         movq %rsp,%rdi
416         /*
417          * Setup a stack frame pointer.  This allows gdb to trace
418          * back to the original stack.
419          */
420         movq %rsp,%rbp
421         CFI_DEF_CFA_REGISTER    rbp
422 #else           
423         SAVE_ARGS
424         leaq -ARGOFFSET(%rsp),%rdi      # arg1 for handler
425 #endif  
426         testl $3,CS(%rdi)
427         je 1f
428         swapgs  
429 1:      addl $1,%gs:pda_irqcount        # RED-PEN should check preempt count
430         movq %gs:pda_irqstackptr,%rax
431         cmoveq %rax,%rsp                                                        
432         pushq %rdi                      # save old stack        
433         call \func
434         .endm
435
436 ENTRY(common_interrupt)
437         interrupt do_IRQ
438         /* 0(%rsp): oldrsp-ARGOFFSET */
439 ret_from_intr:          
440         popq  %rdi
441         cli     
442         subl $1,%gs:pda_irqcount
443 #ifdef CONFIG_DEBUG_INFO
444         movq RBP(%rdi),%rbp
445 #endif
446         leaq ARGOFFSET(%rdi),%rsp
447 exit_intr:              
448         GET_THREAD_INFO(%rcx)
449         testl $3,CS-ARGOFFSET(%rsp)
450         je retint_kernel
451         
452         /* Interrupt came from user space */
453         /*
454          * Has a correct top of stack, but a partial stack frame
455          * %rcx: thread info. Interrupts off.
456          */             
457 retint_with_reschedule:
458         movl $_TIF_WORK_MASK,%edi
459 retint_check:                   
460         movl threadinfo_flags(%rcx),%edx
461         andl %edi,%edx
462         jnz  retint_careful
463 retint_swapgs:          
464         cli
465         swapgs 
466 retint_restore_args:                            
467         cli
468         RESTORE_ARGS 0,8,0                                              
469 iret_label:     
470         iretq
471
472         .section __ex_table,"a"
473         .quad iret_label,bad_iret       
474         .previous
475         .section .fixup,"ax"
476         /* force a signal here? this matches i386 behaviour */
477         /* running with kernel gs */
478 bad_iret:
479         movq $-9999,%rdi        /* better code? */
480         jmp do_exit                     
481         .previous       
482         
483         /* edi: workmask, edx: work */  
484 retint_careful:
485         bt    $TIF_NEED_RESCHED,%edx
486         jnc   retint_signal
487         sti
488         pushq %rdi
489         call  schedule
490         popq %rdi               
491         GET_THREAD_INFO(%rcx)
492         cli
493         jmp retint_check
494         
495 retint_signal:
496         testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx
497         jz    retint_swapgs
498         sti
499         SAVE_REST
500         movq $-1,ORIG_RAX(%rsp)                         
501         xorq %rsi,%rsi          # oldset
502         movq %rsp,%rdi          # &pt_regs
503         call do_notify_resume
504         RESTORE_REST
505         cli
506         movl $_TIF_NEED_RESCHED,%edi
507         GET_THREAD_INFO(%rcx)   
508         jmp retint_check
509
510 #ifdef CONFIG_PREEMPT
511         /* Returning to kernel space. Check if we need preemption */
512         /* rcx:  threadinfo. interrupts off. */
513         .p2align
514 retint_kernel:  
515         cmpl $0,threadinfo_preempt_count(%rcx)
516         jnz  retint_restore_args
517         bt  $TIF_NEED_RESCHED,threadinfo_flags(%rcx)
518         jnc  retint_restore_args
519         bt   $9,EFLAGS-ARGOFFSET(%rsp)  /* interrupts off? */
520         jc   retint_restore_args
521         movl $PREEMPT_ACTIVE,threadinfo_preempt_count(%rcx)
522         sti
523         call schedule
524         cli
525         GET_THREAD_INFO(%rcx)
526         movl $0,threadinfo_preempt_count(%rcx) 
527         jmp exit_intr
528 #endif  
529         CFI_ENDPROC
530         
531 /*
532  * APIC interrupts.
533  */             
534         .macro apicinterrupt num,func
535         pushq $\num-256
536         interrupt \func
537         jmp ret_from_intr
538         CFI_ENDPROC
539         .endm
540
541 #ifdef CONFIG_SMP       
542 ENTRY(reschedule_interrupt)
543         apicinterrupt RESCHEDULE_VECTOR,smp_reschedule_interrupt
544
545 ENTRY(invalidate_interrupt)
546         apicinterrupt INVALIDATE_TLB_VECTOR,smp_invalidate_interrupt
547
548 ENTRY(call_function_interrupt)
549         apicinterrupt CALL_FUNCTION_VECTOR,smp_call_function_interrupt
550 #endif
551
552 #ifdef CONFIG_X86_LOCAL_APIC    
553 ENTRY(apic_timer_interrupt)
554         apicinterrupt LOCAL_TIMER_VECTOR,smp_apic_timer_interrupt
555
556 ENTRY(error_interrupt)
557         apicinterrupt ERROR_APIC_VECTOR,smp_error_interrupt
558
559 ENTRY(spurious_interrupt)
560         apicinterrupt SPURIOUS_APIC_VECTOR,smp_spurious_interrupt
561 #endif
562                                 
563 /*
564  * Exception entry points.
565  */             
566         .macro zeroentry sym
567         pushq $0        /* push error code/oldrax */ 
568         pushq %rax      /* push real oldrax to the rdi slot */ 
569         leaq  \sym(%rip),%rax
570         jmp error_entry
571         .endm   
572
573         .macro errorentry sym
574         pushq %rax
575         leaq  \sym(%rip),%rax
576         jmp error_entry
577         .endm
578
579         /* error code is on the stack already */
580         /* handle NMI like exceptions that can happen everywhere */
581         .macro paranoidentry sym
582         SAVE_ALL
583         cld
584         movl $1,%ebx
585         movl  $MSR_GS_BASE,%ecx
586         rdmsr
587         testl %edx,%edx
588         js    1f
589         swapgs
590         xorl  %ebx,%ebx
591 1:      movq %rsp,%rdi
592         movq ORIG_RAX(%rsp),%rsi
593         movq $-1,ORIG_RAX(%rsp)
594         call \sym
595         .endm
596         
597 /*
598  * Exception entry point. This expects an error code/orig_rax on the stack
599  * and the exception handler in %rax.   
600  */                                             
601 ENTRY(error_entry)
602         CFI_STARTPROC   simple
603         CFI_DEF_CFA     rsp,(SS-RDI)
604         CFI_REL_OFFSET  rsp,(RSP-RDI)
605         CFI_REL_OFFSET  rip,(RIP-RDI)
606         /* rdi slot contains rax, oldrax contains error code */
607         cld     
608         subq  $14*8,%rsp
609         CFI_ADJUST_CFA_OFFSET   (14*8)
610         movq %rsi,13*8(%rsp)
611         CFI_REL_OFFSET  rsi,RSI
612         movq 14*8(%rsp),%rsi    /* load rax from rdi slot */
613         movq %rdx,12*8(%rsp)
614         CFI_REL_OFFSET  rdx,RDX
615         movq %rcx,11*8(%rsp)
616         CFI_REL_OFFSET  rcx,RCX
617         movq %rsi,10*8(%rsp)    /* store rax */ 
618         CFI_REL_OFFSET  rax,RAX
619         movq %r8, 9*8(%rsp)
620         CFI_REL_OFFSET  r8,R8
621         movq %r9, 8*8(%rsp)
622         CFI_REL_OFFSET  r9,R9
623         movq %r10,7*8(%rsp)
624         CFI_REL_OFFSET  r10,R10
625         movq %r11,6*8(%rsp)
626         CFI_REL_OFFSET  r11,R11
627         movq %rbx,5*8(%rsp) 
628         CFI_REL_OFFSET  rbx,RBX
629         movq %rbp,4*8(%rsp) 
630         CFI_REL_OFFSET  rbp,RBP
631         movq %r12,3*8(%rsp) 
632         CFI_REL_OFFSET  r12,R12
633         movq %r13,2*8(%rsp) 
634         CFI_REL_OFFSET  r13,R13
635         movq %r14,1*8(%rsp) 
636         CFI_REL_OFFSET  r14,R14
637         movq %r15,(%rsp) 
638         CFI_REL_OFFSET  r15,R15
639         xorl %ebx,%ebx  
640         testl $3,CS(%rsp)
641         je  error_kernelspace
642 error_swapgs:   
643         swapgs
644 error_sti:      
645         movq %rdi,RDI(%rsp)     
646         movq %rsp,%rdi
647         movq ORIG_RAX(%rsp),%rsi        /* get error code */ 
648         movq $-1,ORIG_RAX(%rsp)
649         call *%rax
650         /* ebx: no swapgs flag (1: don't need swapgs, 0: need it) */     
651 error_exit:             
652         movl %ebx,%eax          
653         RESTORE_REST
654         cli
655         GET_THREAD_INFO(%rcx)   
656         testl %eax,%eax
657         jne  retint_kernel
658         movl  threadinfo_flags(%rcx),%edx
659         movl  $_TIF_WORK_MASK,%edi
660         andl  %edi,%edx
661         jnz  retint_careful
662         swapgs 
663         RESTORE_ARGS 0,8,0                                              
664         iretq
665         CFI_ENDPROC
666
667 error_kernelspace:
668         incl %ebx
669        /* There are two places in the kernel that can potentially fault with
670           usergs. Handle them here. The exception handlers after
671            iret run with kernel gs again, so don't set the user space flag.
672            B stepping K8s sometimes report an truncated RIP for IRET 
673            exceptions returning to compat mode. Check for these here too. */
674         leaq iret_label(%rip),%rbp
675         cmpq %rbp,RIP(%rsp) 
676         je   error_swapgs
677         movl %ebp,%ebp  /* zero extend */
678         cmpq %rbp,RIP(%rsp) 
679         je   error_swapgs
680         cmpq $gs_change,RIP(%rsp)
681         je   error_swapgs
682         jmp  error_sti
683         
684        /* Reload gs selector with exception handling */
685        /* edi:  new selector */ 
686 ENTRY(load_gs_index)
687         pushf
688         cli
689         swapgs
690 gs_change:     
691         movl %edi,%gs   
692 2:      mfence          /* workaround */
693         swapgs
694         popf
695         ret
696        
697         .section __ex_table,"a"
698         .align 8
699         .quad gs_change,bad_gs
700         .previous
701         .section .fixup,"ax"
702         /* running with kernelgs */
703 bad_gs: 
704         swapgs                  /* switch back to user gs */
705         xorl %eax,%eax
706         movl %eax,%gs
707         jmp  2b
708         .previous       
709         
710 /*
711  * Create a kernel thread.
712  *
713  * C extern interface:
714  *      extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
715  *
716  * asm input arguments:
717  *      rdi: fn, rsi: arg, rdx: flags
718  */
719 ENTRY(kernel_thread)
720         CFI_STARTPROC
721         FAKE_STACK_FRAME $child_rip
722         SAVE_ALL
723
724         # rdi: flags, rsi: usp, rdx: will be &pt_regs
725         movq %rdx,%rdi
726         orq  kernel_thread_flags(%rip),%rdi
727         movq $-1, %rsi
728         movq %rsp, %rdx
729
730         xorl %r8d,%r8d
731         xorl %r9d,%r9d
732         
733         # clone now
734         call do_fork
735         movq %rax,RAX(%rsp)
736         xorl %edi,%edi
737
738         /*
739          * It isn't worth to check for reschedule here,
740          * so internally to the x86_64 port you can rely on kernel_thread()
741          * not to reschedule the child before returning, this avoids the need
742          * of hacks for example to fork off the per-CPU idle tasks.
743          * [Hopefully no generic code relies on the reschedule -AK]     
744          */
745         RESTORE_ALL
746         UNFAKE_STACK_FRAME
747         ret
748         CFI_ENDPROC
749
750         
751 child_rip:
752         /*
753          * Here we are in the child and the registers are set as they were
754          * at kernel_thread() invocation in the parent.
755          */
756         movq %rdi, %rax
757         movq %rsi, %rdi
758         call *%rax
759         # exit
760         xorq %rdi, %rdi
761         call do_exit
762
763 /*
764  * execve(). This function needs to use IRET, not SYSRET, to set up all state properly.
765  *
766  * C extern interface:
767  *       extern long execve(char *name, char **argv, char **envp)
768  *
769  * asm input arguments:
770  *      rdi: name, rsi: argv, rdx: envp
771  *
772  * We want to fallback into:
773  *      extern long sys_execve(char *name, char **argv,char **envp, struct pt_regs regs)
774  *
775  * do_sys_execve asm fallback arguments:
776  *      rdi: name, rsi: argv, rdx: envp, fake frame on the stack
777  */
778 ENTRY(execve)
779         CFI_STARTPROC
780         FAKE_STACK_FRAME $0
781         SAVE_ALL        
782         call sys_execve
783         movq %rax, RAX(%rsp)    
784         RESTORE_REST
785         testq %rax,%rax
786         je int_ret_from_sys_call
787         RESTORE_ARGS
788         UNFAKE_STACK_FRAME
789         ret
790         CFI_ENDPROC
791
792 ENTRY(page_fault)
793         errorentry do_page_fault
794
795 ENTRY(coprocessor_error)
796         zeroentry do_coprocessor_error
797
798 ENTRY(simd_coprocessor_error)
799         zeroentry do_simd_coprocessor_error     
800
801 ENTRY(device_not_available)
802         zeroentry math_state_restore
803
804         /* runs on exception stack */
805 ENTRY(debug)
806         CFI_STARTPROC
807         pushq $0
808         CFI_ADJUST_CFA_OFFSET 8         
809         paranoidentry do_debug
810         /* switch back to process stack to restore the state ptrace touched */
811         movq %rax,%rsp  
812         testl $3,CS(%rsp)
813         jnz   paranoid_userspace        
814         jmp paranoid_exit
815         CFI_ENDPROC
816
817         /* runs on exception stack */   
818 ENTRY(nmi)
819         CFI_STARTPROC
820         pushq $-1
821         CFI_ADJUST_CFA_OFFSET 8         
822         paranoidentry do_nmi
823         /* ebx: no swapgs flag */
824 paranoid_exit:
825         testl %ebx,%ebx                         /* swapgs needed? */
826         jnz paranoid_restore
827 paranoid_swapgs:        
828         cli
829         swapgs
830 paranoid_restore:       
831         RESTORE_ALL 8
832         iretq
833 paranoid_userspace:     
834         cli
835         GET_THREAD_INFO(%rcx)
836         movl threadinfo_flags(%rcx),%edx
837         testl $_TIF_NEED_RESCHED,%edx
838         jnz paranoid_resched
839         testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx
840         jnz paranoid_signal
841         jmp paranoid_swapgs
842 paranoid_resched:               
843         sti
844         call schedule
845         jmp paranoid_exit
846 paranoid_signal:                
847         sti
848         xorl %esi,%esi /* oldset */
849         movq %rsp,%rdi /* &pt_regs */
850         call do_notify_resume
851         jmp paranoid_exit
852         CFI_ENDPROC
853         
854 ENTRY(int3)
855         zeroentry do_int3       
856
857 ENTRY(overflow)
858         zeroentry do_overflow
859
860 ENTRY(bounds)
861         zeroentry do_bounds
862
863 ENTRY(invalid_op)
864         zeroentry do_invalid_op 
865
866 ENTRY(coprocessor_segment_overrun)
867         zeroentry do_coprocessor_segment_overrun
868
869 ENTRY(reserved)
870         zeroentry do_reserved
871
872         /* runs on exception stack */
873 ENTRY(double_fault)
874         CFI_STARTPROC
875         paranoidentry do_double_fault
876         movq %rax,%rsp
877         testl $3,CS(%rsp)
878         jnz paranoid_userspace          
879         jmp paranoid_exit
880         CFI_ENDPROC
881
882 ENTRY(invalid_TSS)
883         errorentry do_invalid_TSS
884
885 ENTRY(segment_not_present)
886         errorentry do_segment_not_present
887
888         /* runs on exception stack */
889 ENTRY(stack_segment)
890         CFI_STARTPROC
891         paranoidentry do_stack_segment
892         movq %rax,%rsp
893         testl $3,CS(%rsp)
894         jnz paranoid_userspace
895         jmp paranoid_exit
896         CFI_ENDPROC
897
898 ENTRY(general_protection)
899         errorentry do_general_protection
900
901 ENTRY(alignment_check)
902         errorentry do_alignment_check
903
904 ENTRY(divide_error)
905         zeroentry do_divide_error
906
907 ENTRY(spurious_interrupt_bug)
908         zeroentry do_spurious_interrupt_bug
909
910         /* runs on exception stack */
911 ENTRY(machine_check)
912         CFI_STARTPROC
913         pushq $0
914         CFI_ADJUST_CFA_OFFSET 8 
915         paranoidentry do_machine_check
916         jmp paranoid_exit
917         CFI_ENDPROC
918
919 ENTRY(call_debug)
920        zeroentry do_call_debug
921