]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/x86/kernel/entry_64.S
x86_64 syscall audit fast-path
[linux-2.6-omap-h63xx.git] / arch / x86 / kernel / entry_64.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
9 /*
10  * entry.S contains the system-call and fault low-level handling routines.
11  *
12  * NOTE: This code handles signal-recognition, which happens every time
13  * after an interrupt and after each system call.
14  * 
15  * Normal syscalls and interrupts don't save a full stack frame, this is 
16  * only done for syscall tracing, signals or fork/exec et.al.
17  * 
18  * A note on terminology:        
19  * - top of stack: Architecture defined interrupt frame from SS to RIP 
20  * at the top of the kernel process stack.      
21  * - partial stack frame: partially saved registers upto R11.
22  * - full stack frame: Like partial stack frame, but all register saved. 
23  *
24  * Some macro usage:
25  * - CFI macros are used to generate dwarf2 unwind information for better
26  * backtraces. They don't change any code.
27  * - SAVE_ALL/RESTORE_ALL - Save/restore all registers
28  * - SAVE_ARGS/RESTORE_ARGS - Save/restore registers that C functions modify.
29  * There are unfortunately lots of special cases where some registers
30  * not touched. The macro is a big mess that should be cleaned up.
31  * - SAVE_REST/RESTORE_REST - Handle the registers not saved by SAVE_ARGS.
32  * Gives a full stack frame.
33  * - ENTRY/END Define functions in the symbol table.
34  * - FIXUP_TOP_OF_STACK/RESTORE_TOP_OF_STACK - Fix up the hardware stack
35  * frame that is otherwise undefined after a SYSCALL
36  * - TRACE_IRQ_* - Trace hard interrupt state for lock debugging.
37  * - errorentry/paranoidentry/zeroentry - Define exception entry points.
38  */
39
40 #include <linux/linkage.h>
41 #include <asm/segment.h>
42 #include <asm/cache.h>
43 #include <asm/errno.h>
44 #include <asm/dwarf2.h>
45 #include <asm/calling.h>
46 #include <asm/asm-offsets.h>
47 #include <asm/msr.h>
48 #include <asm/unistd.h>
49 #include <asm/thread_info.h>
50 #include <asm/hw_irq.h>
51 #include <asm/page.h>
52 #include <asm/irqflags.h>
53 #include <asm/paravirt.h>
54 #include <asm/ftrace.h>
55
56 /* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this.  */
57 #include <linux/elf-em.h>
58 #define AUDIT_ARCH_X86_64       (EM_X86_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
59 #define __AUDIT_ARCH_64BIT 0x80000000
60 #define __AUDIT_ARCH_LE    0x40000000
61
62         .code64
63
64 #ifdef CONFIG_FTRACE
65 #ifdef CONFIG_DYNAMIC_FTRACE
66 ENTRY(mcount)
67
68         subq $0x38, %rsp
69         movq %rax, (%rsp)
70         movq %rcx, 8(%rsp)
71         movq %rdx, 16(%rsp)
72         movq %rsi, 24(%rsp)
73         movq %rdi, 32(%rsp)
74         movq %r8, 40(%rsp)
75         movq %r9, 48(%rsp)
76
77         movq 0x38(%rsp), %rdi
78         subq $MCOUNT_INSN_SIZE, %rdi
79
80 .globl mcount_call
81 mcount_call:
82         call ftrace_stub
83
84         movq 48(%rsp), %r9
85         movq 40(%rsp), %r8
86         movq 32(%rsp), %rdi
87         movq 24(%rsp), %rsi
88         movq 16(%rsp), %rdx
89         movq 8(%rsp), %rcx
90         movq (%rsp), %rax
91         addq $0x38, %rsp
92
93         retq
94 END(mcount)
95
96 ENTRY(ftrace_caller)
97
98         /* taken from glibc */
99         subq $0x38, %rsp
100         movq %rax, (%rsp)
101         movq %rcx, 8(%rsp)
102         movq %rdx, 16(%rsp)
103         movq %rsi, 24(%rsp)
104         movq %rdi, 32(%rsp)
105         movq %r8, 40(%rsp)
106         movq %r9, 48(%rsp)
107
108         movq 0x38(%rsp), %rdi
109         movq 8(%rbp), %rsi
110         subq $MCOUNT_INSN_SIZE, %rdi
111
112 .globl ftrace_call
113 ftrace_call:
114         call ftrace_stub
115
116         movq 48(%rsp), %r9
117         movq 40(%rsp), %r8
118         movq 32(%rsp), %rdi
119         movq 24(%rsp), %rsi
120         movq 16(%rsp), %rdx
121         movq 8(%rsp), %rcx
122         movq (%rsp), %rax
123         addq $0x38, %rsp
124
125 .globl ftrace_stub
126 ftrace_stub:
127         retq
128 END(ftrace_caller)
129
130 #else /* ! CONFIG_DYNAMIC_FTRACE */
131 ENTRY(mcount)
132         cmpq $ftrace_stub, ftrace_trace_function
133         jnz trace
134 .globl ftrace_stub
135 ftrace_stub:
136         retq
137
138 trace:
139         /* taken from glibc */
140         subq $0x38, %rsp
141         movq %rax, (%rsp)
142         movq %rcx, 8(%rsp)
143         movq %rdx, 16(%rsp)
144         movq %rsi, 24(%rsp)
145         movq %rdi, 32(%rsp)
146         movq %r8, 40(%rsp)
147         movq %r9, 48(%rsp)
148
149         movq 0x38(%rsp), %rdi
150         movq 8(%rbp), %rsi
151         subq $MCOUNT_INSN_SIZE, %rdi
152
153         call   *ftrace_trace_function
154
155         movq 48(%rsp), %r9
156         movq 40(%rsp), %r8
157         movq 32(%rsp), %rdi
158         movq 24(%rsp), %rsi
159         movq 16(%rsp), %rdx
160         movq 8(%rsp), %rcx
161         movq (%rsp), %rax
162         addq $0x38, %rsp
163
164         jmp ftrace_stub
165 END(mcount)
166 #endif /* CONFIG_DYNAMIC_FTRACE */
167 #endif /* CONFIG_FTRACE */
168
169 #ifndef CONFIG_PREEMPT
170 #define retint_kernel retint_restore_args
171 #endif  
172
173 #ifdef CONFIG_PARAVIRT
174 ENTRY(native_usergs_sysret64)
175         swapgs
176         sysretq
177 #endif /* CONFIG_PARAVIRT */
178
179
180 .macro TRACE_IRQS_IRETQ offset=ARGOFFSET
181 #ifdef CONFIG_TRACE_IRQFLAGS
182         bt   $9,EFLAGS-\offset(%rsp)    /* interrupts off? */
183         jnc  1f
184         TRACE_IRQS_ON
185 1:
186 #endif
187 .endm
188
189 /*
190  * C code is not supposed to know about undefined top of stack. Every time 
191  * a C function with an pt_regs argument is called from the SYSCALL based 
192  * fast path FIXUP_TOP_OF_STACK is needed.
193  * RESTORE_TOP_OF_STACK syncs the syscall state after any possible ptregs
194  * manipulation.
195  */             
196                 
197         /* %rsp:at FRAMEEND */ 
198         .macro FIXUP_TOP_OF_STACK tmp
199         movq    %gs:pda_oldrsp,\tmp
200         movq    \tmp,RSP(%rsp)
201         movq    $__USER_DS,SS(%rsp)
202         movq    $__USER_CS,CS(%rsp)
203         movq    $-1,RCX(%rsp)
204         movq    R11(%rsp),\tmp  /* get eflags */
205         movq    \tmp,EFLAGS(%rsp)
206         .endm
207
208         .macro RESTORE_TOP_OF_STACK tmp,offset=0
209         movq   RSP-\offset(%rsp),\tmp
210         movq   \tmp,%gs:pda_oldrsp
211         movq   EFLAGS-\offset(%rsp),\tmp
212         movq   \tmp,R11-\offset(%rsp)
213         .endm
214
215         .macro FAKE_STACK_FRAME child_rip
216         /* push in order ss, rsp, eflags, cs, rip */
217         xorl %eax, %eax
218         pushq $__KERNEL_DS /* ss */
219         CFI_ADJUST_CFA_OFFSET   8
220         /*CFI_REL_OFFSET        ss,0*/
221         pushq %rax /* rsp */
222         CFI_ADJUST_CFA_OFFSET   8
223         CFI_REL_OFFSET  rsp,0
224         pushq $(1<<9) /* eflags - interrupts on */
225         CFI_ADJUST_CFA_OFFSET   8
226         /*CFI_REL_OFFSET        rflags,0*/
227         pushq $__KERNEL_CS /* cs */
228         CFI_ADJUST_CFA_OFFSET   8
229         /*CFI_REL_OFFSET        cs,0*/
230         pushq \child_rip /* rip */
231         CFI_ADJUST_CFA_OFFSET   8
232         CFI_REL_OFFSET  rip,0
233         pushq   %rax /* orig rax */
234         CFI_ADJUST_CFA_OFFSET   8
235         .endm
236
237         .macro UNFAKE_STACK_FRAME
238         addq $8*6, %rsp
239         CFI_ADJUST_CFA_OFFSET   -(6*8)
240         .endm
241
242         .macro  CFI_DEFAULT_STACK start=1
243         .if \start
244         CFI_STARTPROC   simple
245         CFI_SIGNAL_FRAME
246         CFI_DEF_CFA     rsp,SS+8
247         .else
248         CFI_DEF_CFA_OFFSET SS+8
249         .endif
250         CFI_REL_OFFSET  r15,R15
251         CFI_REL_OFFSET  r14,R14
252         CFI_REL_OFFSET  r13,R13
253         CFI_REL_OFFSET  r12,R12
254         CFI_REL_OFFSET  rbp,RBP
255         CFI_REL_OFFSET  rbx,RBX
256         CFI_REL_OFFSET  r11,R11
257         CFI_REL_OFFSET  r10,R10
258         CFI_REL_OFFSET  r9,R9
259         CFI_REL_OFFSET  r8,R8
260         CFI_REL_OFFSET  rax,RAX
261         CFI_REL_OFFSET  rcx,RCX
262         CFI_REL_OFFSET  rdx,RDX
263         CFI_REL_OFFSET  rsi,RSI
264         CFI_REL_OFFSET  rdi,RDI
265         CFI_REL_OFFSET  rip,RIP
266         /*CFI_REL_OFFSET        cs,CS*/
267         /*CFI_REL_OFFSET        rflags,EFLAGS*/
268         CFI_REL_OFFSET  rsp,RSP
269         /*CFI_REL_OFFSET        ss,SS*/
270         .endm
271 /*
272  * A newly forked process directly context switches into this.
273  */     
274 /* rdi: prev */ 
275 ENTRY(ret_from_fork)
276         CFI_DEFAULT_STACK
277         push kernel_eflags(%rip)
278         CFI_ADJUST_CFA_OFFSET 4
279         popf                            # reset kernel eflags
280         CFI_ADJUST_CFA_OFFSET -4
281         call schedule_tail
282         GET_THREAD_INFO(%rcx)
283         testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%rcx)
284         jnz rff_trace
285 rff_action:     
286         RESTORE_REST
287         testl $3,CS-ARGOFFSET(%rsp)     # from kernel_thread?
288         je   int_ret_from_sys_call
289         testl $_TIF_IA32,TI_flags(%rcx)
290         jnz  int_ret_from_sys_call
291         RESTORE_TOP_OF_STACK %rdi,ARGOFFSET
292         jmp ret_from_sys_call
293 rff_trace:
294         movq %rsp,%rdi
295         call syscall_trace_leave
296         GET_THREAD_INFO(%rcx)   
297         jmp rff_action
298         CFI_ENDPROC
299 END(ret_from_fork)
300
301 /*
302  * System call entry. Upto 6 arguments in registers are supported.
303  *
304  * SYSCALL does not save anything on the stack and does not change the
305  * stack pointer.
306  */
307                 
308 /*
309  * Register setup:      
310  * rax  system call number
311  * rdi  arg0
312  * rcx  return address for syscall/sysret, C arg3 
313  * rsi  arg1
314  * rdx  arg2    
315  * r10  arg3    (--> moved to rcx for C)
316  * r8   arg4
317  * r9   arg5
318  * r11  eflags for syscall/sysret, temporary for C
319  * r12-r15,rbp,rbx saved by C code, not touched.                
320  * 
321  * Interrupts are off on entry.
322  * Only called from user space.
323  *
324  * XXX  if we had a free scratch register we could save the RSP into the stack frame
325  *      and report it properly in ps. Unfortunately we haven't.
326  *
327  * When user can change the frames always force IRET. That is because
328  * it deals with uncanonical addresses better. SYSRET has trouble
329  * with them due to bugs in both AMD and Intel CPUs.
330  */                                     
331
332 ENTRY(system_call)
333         CFI_STARTPROC   simple
334         CFI_SIGNAL_FRAME
335         CFI_DEF_CFA     rsp,PDA_STACKOFFSET
336         CFI_REGISTER    rip,rcx
337         /*CFI_REGISTER  rflags,r11*/
338         SWAPGS_UNSAFE_STACK
339         /*
340          * A hypervisor implementation might want to use a label
341          * after the swapgs, so that it can do the swapgs
342          * for the guest and jump here on syscall.
343          */
344 ENTRY(system_call_after_swapgs)
345
346         movq    %rsp,%gs:pda_oldrsp 
347         movq    %gs:pda_kernelstack,%rsp
348         /*
349          * No need to follow this irqs off/on section - it's straight
350          * and short:
351          */
352         ENABLE_INTERRUPTS(CLBR_NONE)
353         SAVE_ARGS 8,1
354         movq  %rax,ORIG_RAX-ARGOFFSET(%rsp) 
355         movq  %rcx,RIP-ARGOFFSET(%rsp)
356         CFI_REL_OFFSET rip,RIP-ARGOFFSET
357         GET_THREAD_INFO(%rcx)
358         testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%rcx)
359         jnz tracesys
360 system_call_fastpath:
361         cmpq $__NR_syscall_max,%rax
362         ja badsys
363         movq %r10,%rcx
364         call *sys_call_table(,%rax,8)  # XXX:    rip relative
365         movq %rax,RAX-ARGOFFSET(%rsp)
366 /*
367  * Syscall return path ending with SYSRET (fast path)
368  * Has incomplete stack frame and undefined top of stack. 
369  */             
370 ret_from_sys_call:
371         movl $_TIF_ALLWORK_MASK,%edi
372         /* edi: flagmask */
373 sysret_check:           
374         LOCKDEP_SYS_EXIT
375         GET_THREAD_INFO(%rcx)
376         DISABLE_INTERRUPTS(CLBR_NONE)
377         TRACE_IRQS_OFF
378         movl TI_flags(%rcx),%edx
379         andl %edi,%edx
380         jnz  sysret_careful 
381         CFI_REMEMBER_STATE
382         /*
383          * sysretq will re-enable interrupts:
384          */
385         TRACE_IRQS_ON
386         movq RIP-ARGOFFSET(%rsp),%rcx
387         CFI_REGISTER    rip,rcx
388         RESTORE_ARGS 0,-ARG_SKIP,1
389         /*CFI_REGISTER  rflags,r11*/
390         movq    %gs:pda_oldrsp, %rsp
391         USERGS_SYSRET64
392
393         CFI_RESTORE_STATE
394         /* Handle reschedules */
395         /* edx: work, edi: workmask */  
396 sysret_careful:
397         bt $TIF_NEED_RESCHED,%edx
398         jnc sysret_signal
399         TRACE_IRQS_ON
400         ENABLE_INTERRUPTS(CLBR_NONE)
401         pushq %rdi
402         CFI_ADJUST_CFA_OFFSET 8
403         call schedule
404         popq  %rdi
405         CFI_ADJUST_CFA_OFFSET -8
406         jmp sysret_check
407
408         /* Handle a signal */ 
409 sysret_signal:
410         TRACE_IRQS_ON
411         ENABLE_INTERRUPTS(CLBR_NONE)
412 #ifdef CONFIG_AUDITSYSCALL
413         bt $TIF_SYSCALL_AUDIT,%edx
414         jc sysret_audit
415 #endif
416         /* edx: work flags (arg3) */
417         leaq do_notify_resume(%rip),%rax
418         leaq -ARGOFFSET(%rsp),%rdi # &pt_regs -> arg1
419         xorl %esi,%esi # oldset -> arg2
420         call ptregscall_common
421         movl $_TIF_WORK_MASK,%edi
422         /* Use IRET because user could have changed frame. This
423            works because ptregscall_common has called FIXUP_TOP_OF_STACK. */
424         DISABLE_INTERRUPTS(CLBR_NONE)
425         TRACE_IRQS_OFF
426         jmp int_with_check
427         
428 badsys:
429         movq $-ENOSYS,RAX-ARGOFFSET(%rsp)
430         jmp ret_from_sys_call
431
432 #ifdef CONFIG_AUDITSYSCALL
433         /*
434          * Fast path for syscall audit without full syscall trace.
435          * We just call audit_syscall_entry() directly, and then
436          * jump back to the normal fast path.
437          */
438 auditsys:
439         movq %r10,%r9                   /* 6th arg: 4th syscall arg */
440         movq %rdx,%r8                   /* 5th arg: 3rd syscall arg */
441         movq %rsi,%rcx                  /* 4th arg: 2nd syscall arg */
442         movq %rdi,%rdx                  /* 3rd arg: 1st syscall arg */
443         movq %rax,%rsi                  /* 2nd arg: syscall number */
444         movl $AUDIT_ARCH_X86_64,%edi    /* 1st arg: audit arch */
445         call audit_syscall_entry
446         LOAD_ARGS 0             /* reload call-clobbered registers */
447         jmp system_call_fastpath
448
449         /*
450          * Return fast path for syscall audit.  Call audit_syscall_exit()
451          * directly and then jump back to the fast path with TIF_SYSCALL_AUDIT
452          * masked off.
453          */
454 sysret_audit:
455         movq %rax,%rsi          /* second arg, syscall return value */
456         cmpq $0,%rax            /* is it < 0? */
457         setl %al                /* 1 if so, 0 if not */
458         movzbl %al,%edi         /* zero-extend that into %edi */
459         inc %edi /* first arg, 0->1(AUDITSC_SUCCESS), 1->2(AUDITSC_FAILURE) */
460         call audit_syscall_exit
461         movl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),%edi
462         jmp sysret_check
463 #endif  /* CONFIG_AUDITSYSCALL */
464
465         /* Do syscall tracing */
466 tracesys:                        
467 #ifdef CONFIG_AUDITSYSCALL
468         testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags(%rcx)
469         jz auditsys
470 #endif
471         SAVE_REST
472         movq $-ENOSYS,RAX(%rsp) /* ptrace can change this for a bad syscall */
473         FIXUP_TOP_OF_STACK %rdi
474         movq %rsp,%rdi
475         call syscall_trace_enter
476         /*
477          * Reload arg registers from stack in case ptrace changed them.
478          * We don't reload %rax because syscall_trace_enter() returned
479          * the value it wants us to use in the table lookup.
480          */
481         LOAD_ARGS ARGOFFSET, 1
482         RESTORE_REST
483         cmpq $__NR_syscall_max,%rax
484         ja   int_ret_from_sys_call      /* RAX(%rsp) set to -ENOSYS above */
485         movq %r10,%rcx  /* fixup for C */
486         call *sys_call_table(,%rax,8)
487         movq %rax,RAX-ARGOFFSET(%rsp)
488         /* Use IRET because user could have changed frame */
489                 
490 /* 
491  * Syscall return path ending with IRET.
492  * Has correct top of stack, but partial stack frame.
493  */
494         .globl int_ret_from_sys_call
495 int_ret_from_sys_call:
496         DISABLE_INTERRUPTS(CLBR_NONE)
497         TRACE_IRQS_OFF
498         testl $3,CS-ARGOFFSET(%rsp)
499         je retint_restore_args
500         movl $_TIF_ALLWORK_MASK,%edi
501         /* edi: mask to check */
502 int_with_check:
503         LOCKDEP_SYS_EXIT_IRQ
504         GET_THREAD_INFO(%rcx)
505         movl TI_flags(%rcx),%edx
506         andl %edi,%edx
507         jnz   int_careful
508         andl    $~TS_COMPAT,TI_status(%rcx)
509         jmp   retint_swapgs
510
511         /* Either reschedule or signal or syscall exit tracking needed. */
512         /* First do a reschedule test. */
513         /* edx: work, edi: workmask */
514 int_careful:
515         bt $TIF_NEED_RESCHED,%edx
516         jnc  int_very_careful
517         TRACE_IRQS_ON
518         ENABLE_INTERRUPTS(CLBR_NONE)
519         pushq %rdi
520         CFI_ADJUST_CFA_OFFSET 8
521         call schedule
522         popq %rdi
523         CFI_ADJUST_CFA_OFFSET -8
524         DISABLE_INTERRUPTS(CLBR_NONE)
525         TRACE_IRQS_OFF
526         jmp int_with_check
527
528         /* handle signals and tracing -- both require a full stack frame */
529 int_very_careful:
530         TRACE_IRQS_ON
531         ENABLE_INTERRUPTS(CLBR_NONE)
532         SAVE_REST
533         /* Check for syscall exit trace */      
534         testl $_TIF_WORK_SYSCALL_EXIT,%edx
535         jz int_signal
536         pushq %rdi
537         CFI_ADJUST_CFA_OFFSET 8
538         leaq 8(%rsp),%rdi       # &ptregs -> arg1       
539         call syscall_trace_leave
540         popq %rdi
541         CFI_ADJUST_CFA_OFFSET -8
542         andl $~(_TIF_WORK_SYSCALL_EXIT|_TIF_SYSCALL_EMU),%edi
543         jmp int_restore_rest
544         
545 int_signal:
546         testl $_TIF_DO_NOTIFY_MASK,%edx
547         jz 1f
548         movq %rsp,%rdi          # &ptregs -> arg1
549         xorl %esi,%esi          # oldset -> arg2
550         call do_notify_resume
551 1:      movl $_TIF_WORK_MASK,%edi
552 int_restore_rest:
553         RESTORE_REST
554         DISABLE_INTERRUPTS(CLBR_NONE)
555         TRACE_IRQS_OFF
556         jmp int_with_check
557         CFI_ENDPROC
558 END(system_call)
559                 
560 /* 
561  * Certain special system calls that need to save a complete full stack frame.
562  */                                                             
563         
564         .macro PTREGSCALL label,func,arg
565         .globl \label
566 \label:
567         leaq    \func(%rip),%rax
568         leaq    -ARGOFFSET+8(%rsp),\arg /* 8 for return address */
569         jmp     ptregscall_common
570 END(\label)
571         .endm
572
573         CFI_STARTPROC
574
575         PTREGSCALL stub_clone, sys_clone, %r8
576         PTREGSCALL stub_fork, sys_fork, %rdi
577         PTREGSCALL stub_vfork, sys_vfork, %rdi
578         PTREGSCALL stub_sigaltstack, sys_sigaltstack, %rdx
579         PTREGSCALL stub_iopl, sys_iopl, %rsi
580
581 ENTRY(ptregscall_common)
582         popq %r11
583         CFI_ADJUST_CFA_OFFSET -8
584         CFI_REGISTER rip, r11
585         SAVE_REST
586         movq %r11, %r15
587         CFI_REGISTER rip, r15
588         FIXUP_TOP_OF_STACK %r11
589         call *%rax
590         RESTORE_TOP_OF_STACK %r11
591         movq %r15, %r11
592         CFI_REGISTER rip, r11
593         RESTORE_REST
594         pushq %r11
595         CFI_ADJUST_CFA_OFFSET 8
596         CFI_REL_OFFSET rip, 0
597         ret
598         CFI_ENDPROC
599 END(ptregscall_common)
600         
601 ENTRY(stub_execve)
602         CFI_STARTPROC
603         popq %r11
604         CFI_ADJUST_CFA_OFFSET -8
605         CFI_REGISTER rip, r11
606         SAVE_REST
607         FIXUP_TOP_OF_STACK %r11
608         movq %rsp, %rcx
609         call sys_execve
610         RESTORE_TOP_OF_STACK %r11
611         movq %rax,RAX(%rsp)
612         RESTORE_REST
613         jmp int_ret_from_sys_call
614         CFI_ENDPROC
615 END(stub_execve)
616         
617 /*
618  * sigreturn is special because it needs to restore all registers on return.
619  * This cannot be done with SYSRET, so use the IRET return path instead.
620  */                
621 ENTRY(stub_rt_sigreturn)
622         CFI_STARTPROC
623         addq $8, %rsp
624         CFI_ADJUST_CFA_OFFSET   -8
625         SAVE_REST
626         movq %rsp,%rdi
627         FIXUP_TOP_OF_STACK %r11
628         call sys_rt_sigreturn
629         movq %rax,RAX(%rsp) # fixme, this could be done at the higher layer
630         RESTORE_REST
631         jmp int_ret_from_sys_call
632         CFI_ENDPROC
633 END(stub_rt_sigreturn)
634
635 /*
636  * initial frame state for interrupts and exceptions
637  */
638         .macro _frame ref
639         CFI_STARTPROC simple
640         CFI_SIGNAL_FRAME
641         CFI_DEF_CFA rsp,SS+8-\ref
642         /*CFI_REL_OFFSET ss,SS-\ref*/
643         CFI_REL_OFFSET rsp,RSP-\ref
644         /*CFI_REL_OFFSET rflags,EFLAGS-\ref*/
645         /*CFI_REL_OFFSET cs,CS-\ref*/
646         CFI_REL_OFFSET rip,RIP-\ref
647         .endm
648
649 /* initial frame state for interrupts (and exceptions without error code) */
650 #define INTR_FRAME _frame RIP
651 /* initial frame state for exceptions with error code (and interrupts with
652    vector already pushed) */
653 #define XCPT_FRAME _frame ORIG_RAX
654
655 /* 
656  * Interrupt entry/exit.
657  *
658  * Interrupt entry points save only callee clobbered registers in fast path.
659  *      
660  * Entry runs with interrupts off.      
661  */ 
662
663 /* 0(%rsp): interrupt number */ 
664         .macro interrupt func
665         cld
666         SAVE_ARGS
667         leaq -ARGOFFSET(%rsp),%rdi      # arg1 for handler
668         pushq %rbp
669         CFI_ADJUST_CFA_OFFSET   8
670         CFI_REL_OFFSET          rbp, 0
671         movq %rsp,%rbp
672         CFI_DEF_CFA_REGISTER    rbp
673         testl $3,CS(%rdi)
674         je 1f
675         SWAPGS
676         /* irqcount is used to check if a CPU is already on an interrupt
677            stack or not. While this is essentially redundant with preempt_count
678            it is a little cheaper to use a separate counter in the PDA
679            (short of moving irq_enter into assembly, which would be too
680             much work) */
681 1:      incl    %gs:pda_irqcount
682         cmoveq %gs:pda_irqstackptr,%rsp
683         push    %rbp                    # backlink for old unwinder
684         /*
685          * We entered an interrupt context - irqs are off:
686          */
687         TRACE_IRQS_OFF
688         call \func
689         .endm
690
691 ENTRY(common_interrupt)
692         XCPT_FRAME
693         interrupt do_IRQ
694         /* 0(%rsp): oldrsp-ARGOFFSET */
695 ret_from_intr:
696         DISABLE_INTERRUPTS(CLBR_NONE)
697         TRACE_IRQS_OFF
698         decl %gs:pda_irqcount
699         leaveq
700         CFI_DEF_CFA_REGISTER    rsp
701         CFI_ADJUST_CFA_OFFSET   -8
702 exit_intr:
703         GET_THREAD_INFO(%rcx)
704         testl $3,CS-ARGOFFSET(%rsp)
705         je retint_kernel
706         
707         /* Interrupt came from user space */
708         /*
709          * Has a correct top of stack, but a partial stack frame
710          * %rcx: thread info. Interrupts off.
711          */             
712 retint_with_reschedule:
713         movl $_TIF_WORK_MASK,%edi
714 retint_check:
715         LOCKDEP_SYS_EXIT_IRQ
716         movl TI_flags(%rcx),%edx
717         andl %edi,%edx
718         CFI_REMEMBER_STATE
719         jnz  retint_careful
720
721 retint_swapgs:          /* return to user-space */
722         /*
723          * The iretq could re-enable interrupts:
724          */
725         DISABLE_INTERRUPTS(CLBR_ANY)
726         TRACE_IRQS_IRETQ
727         SWAPGS
728         jmp restore_args
729
730 retint_restore_args:    /* return to kernel space */
731         DISABLE_INTERRUPTS(CLBR_ANY)
732         /*
733          * The iretq could re-enable interrupts:
734          */
735         TRACE_IRQS_IRETQ
736 restore_args:
737         RESTORE_ARGS 0,8,0
738
739 irq_return:
740         INTERRUPT_RETURN
741
742         .section __ex_table, "a"
743         .quad irq_return, bad_iret
744         .previous
745
746 #ifdef CONFIG_PARAVIRT
747 ENTRY(native_iret)
748         iretq
749
750         .section __ex_table,"a"
751         .quad native_iret, bad_iret
752         .previous
753 #endif
754
755         .section .fixup,"ax"
756 bad_iret:
757         /*
758          * The iret traps when the %cs or %ss being restored is bogus.
759          * We've lost the original trap vector and error code.
760          * #GPF is the most likely one to get for an invalid selector.
761          * So pretend we completed the iret and took the #GPF in user mode.
762          *
763          * We are now running with the kernel GS after exception recovery.
764          * But error_entry expects us to have user GS to match the user %cs,
765          * so swap back.
766          */
767         pushq $0
768
769         SWAPGS
770         jmp general_protection
771
772         .previous
773
774         /* edi: workmask, edx: work */
775 retint_careful:
776         CFI_RESTORE_STATE
777         bt    $TIF_NEED_RESCHED,%edx
778         jnc   retint_signal
779         TRACE_IRQS_ON
780         ENABLE_INTERRUPTS(CLBR_NONE)
781         pushq %rdi
782         CFI_ADJUST_CFA_OFFSET   8
783         call  schedule
784         popq %rdi               
785         CFI_ADJUST_CFA_OFFSET   -8
786         GET_THREAD_INFO(%rcx)
787         DISABLE_INTERRUPTS(CLBR_NONE)
788         TRACE_IRQS_OFF
789         jmp retint_check
790         
791 retint_signal:
792         testl $_TIF_DO_NOTIFY_MASK,%edx
793         jz    retint_swapgs
794         TRACE_IRQS_ON
795         ENABLE_INTERRUPTS(CLBR_NONE)
796         SAVE_REST
797         movq $-1,ORIG_RAX(%rsp)                         
798         xorl %esi,%esi          # oldset
799         movq %rsp,%rdi          # &pt_regs
800         call do_notify_resume
801         RESTORE_REST
802         DISABLE_INTERRUPTS(CLBR_NONE)
803         TRACE_IRQS_OFF
804         GET_THREAD_INFO(%rcx)
805         jmp retint_with_reschedule
806
807 #ifdef CONFIG_PREEMPT
808         /* Returning to kernel space. Check if we need preemption */
809         /* rcx:  threadinfo. interrupts off. */
810 ENTRY(retint_kernel)
811         cmpl $0,TI_preempt_count(%rcx)
812         jnz  retint_restore_args
813         bt  $TIF_NEED_RESCHED,TI_flags(%rcx)
814         jnc  retint_restore_args
815         bt   $9,EFLAGS-ARGOFFSET(%rsp)  /* interrupts off? */
816         jnc  retint_restore_args
817         call preempt_schedule_irq
818         jmp exit_intr
819 #endif  
820
821         CFI_ENDPROC
822 END(common_interrupt)
823         
824 /*
825  * APIC interrupts.
826  */             
827         .macro apicinterrupt num,func
828         INTR_FRAME
829         pushq $~(\num)
830         CFI_ADJUST_CFA_OFFSET 8
831         interrupt \func
832         jmp ret_from_intr
833         CFI_ENDPROC
834         .endm
835
836 ENTRY(thermal_interrupt)
837         apicinterrupt THERMAL_APIC_VECTOR,smp_thermal_interrupt
838 END(thermal_interrupt)
839
840 ENTRY(threshold_interrupt)
841         apicinterrupt THRESHOLD_APIC_VECTOR,mce_threshold_interrupt
842 END(threshold_interrupt)
843
844 #ifdef CONFIG_SMP       
845 ENTRY(reschedule_interrupt)
846         apicinterrupt RESCHEDULE_VECTOR,smp_reschedule_interrupt
847 END(reschedule_interrupt)
848
849         .macro INVALIDATE_ENTRY num
850 ENTRY(invalidate_interrupt\num)
851         apicinterrupt INVALIDATE_TLB_VECTOR_START+\num,smp_invalidate_interrupt 
852 END(invalidate_interrupt\num)
853         .endm
854
855         INVALIDATE_ENTRY 0
856         INVALIDATE_ENTRY 1
857         INVALIDATE_ENTRY 2
858         INVALIDATE_ENTRY 3
859         INVALIDATE_ENTRY 4
860         INVALIDATE_ENTRY 5
861         INVALIDATE_ENTRY 6
862         INVALIDATE_ENTRY 7
863
864 ENTRY(call_function_interrupt)
865         apicinterrupt CALL_FUNCTION_VECTOR,smp_call_function_interrupt
866 END(call_function_interrupt)
867 ENTRY(call_function_single_interrupt)
868         apicinterrupt CALL_FUNCTION_SINGLE_VECTOR,smp_call_function_single_interrupt
869 END(call_function_single_interrupt)
870 ENTRY(irq_move_cleanup_interrupt)
871         apicinterrupt IRQ_MOVE_CLEANUP_VECTOR,smp_irq_move_cleanup_interrupt
872 END(irq_move_cleanup_interrupt)
873 #endif
874
875 ENTRY(apic_timer_interrupt)
876         apicinterrupt LOCAL_TIMER_VECTOR,smp_apic_timer_interrupt
877 END(apic_timer_interrupt)
878
879 ENTRY(uv_bau_message_intr1)
880         apicinterrupt 220,uv_bau_message_interrupt
881 END(uv_bau_message_intr1)
882
883 ENTRY(error_interrupt)
884         apicinterrupt ERROR_APIC_VECTOR,smp_error_interrupt
885 END(error_interrupt)
886
887 ENTRY(spurious_interrupt)
888         apicinterrupt SPURIOUS_APIC_VECTOR,smp_spurious_interrupt
889 END(spurious_interrupt)
890                                 
891 /*
892  * Exception entry points.
893  */             
894         .macro zeroentry sym
895         INTR_FRAME
896         PARAVIRT_ADJUST_EXCEPTION_FRAME
897         pushq $0        /* push error code/oldrax */ 
898         CFI_ADJUST_CFA_OFFSET 8
899         pushq %rax      /* push real oldrax to the rdi slot */ 
900         CFI_ADJUST_CFA_OFFSET 8
901         CFI_REL_OFFSET rax,0
902         leaq  \sym(%rip),%rax
903         jmp error_entry
904         CFI_ENDPROC
905         .endm   
906
907         .macro errorentry sym
908         XCPT_FRAME
909         PARAVIRT_ADJUST_EXCEPTION_FRAME
910         pushq %rax
911         CFI_ADJUST_CFA_OFFSET 8
912         CFI_REL_OFFSET rax,0
913         leaq  \sym(%rip),%rax
914         jmp error_entry
915         CFI_ENDPROC
916         .endm
917
918         /* error code is on the stack already */
919         /* handle NMI like exceptions that can happen everywhere */
920         .macro paranoidentry sym, ist=0, irqtrace=1
921         SAVE_ALL
922         cld
923         movl $1,%ebx
924         movl  $MSR_GS_BASE,%ecx
925         rdmsr
926         testl %edx,%edx
927         js    1f
928         SWAPGS
929         xorl  %ebx,%ebx
930 1:
931         .if \ist
932         movq    %gs:pda_data_offset, %rbp
933         .endif
934         movq %rsp,%rdi
935         movq ORIG_RAX(%rsp),%rsi
936         movq $-1,ORIG_RAX(%rsp)
937         .if \ist
938         subq    $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
939         .endif
940         call \sym
941         .if \ist
942         addq    $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
943         .endif
944         DISABLE_INTERRUPTS(CLBR_NONE)
945         .if \irqtrace
946         TRACE_IRQS_OFF
947         .endif
948         .endm
949
950         /*
951          * "Paranoid" exit path from exception stack.
952          * Paranoid because this is used by NMIs and cannot take
953          * any kernel state for granted.
954          * We don't do kernel preemption checks here, because only
955          * NMI should be common and it does not enable IRQs and
956          * cannot get reschedule ticks.
957          *
958          * "trace" is 0 for the NMI handler only, because irq-tracing
959          * is fundamentally NMI-unsafe. (we cannot change the soft and
960          * hard flags at once, atomically)
961          */
962         .macro paranoidexit trace=1
963         /* ebx: no swapgs flag */
964 paranoid_exit\trace:
965         testl %ebx,%ebx                         /* swapgs needed? */
966         jnz paranoid_restore\trace
967         testl $3,CS(%rsp)
968         jnz   paranoid_userspace\trace
969 paranoid_swapgs\trace:
970         .if \trace
971         TRACE_IRQS_IRETQ 0
972         .endif
973         SWAPGS_UNSAFE_STACK
974 paranoid_restore\trace:
975         RESTORE_ALL 8
976         jmp irq_return
977 paranoid_userspace\trace:
978         GET_THREAD_INFO(%rcx)
979         movl TI_flags(%rcx),%ebx
980         andl $_TIF_WORK_MASK,%ebx
981         jz paranoid_swapgs\trace
982         movq %rsp,%rdi                  /* &pt_regs */
983         call sync_regs
984         movq %rax,%rsp                  /* switch stack for scheduling */
985         testl $_TIF_NEED_RESCHED,%ebx
986         jnz paranoid_schedule\trace
987         movl %ebx,%edx                  /* arg3: thread flags */
988         .if \trace
989         TRACE_IRQS_ON
990         .endif
991         ENABLE_INTERRUPTS(CLBR_NONE)
992         xorl %esi,%esi                  /* arg2: oldset */
993         movq %rsp,%rdi                  /* arg1: &pt_regs */
994         call do_notify_resume
995         DISABLE_INTERRUPTS(CLBR_NONE)
996         .if \trace
997         TRACE_IRQS_OFF
998         .endif
999         jmp paranoid_userspace\trace
1000 paranoid_schedule\trace:
1001         .if \trace
1002         TRACE_IRQS_ON
1003         .endif
1004         ENABLE_INTERRUPTS(CLBR_ANY)
1005         call schedule
1006         DISABLE_INTERRUPTS(CLBR_ANY)
1007         .if \trace
1008         TRACE_IRQS_OFF
1009         .endif
1010         jmp paranoid_userspace\trace
1011         CFI_ENDPROC
1012         .endm
1013
1014 /*
1015  * Exception entry point. This expects an error code/orig_rax on the stack
1016  * and the exception handler in %rax.   
1017  */                                             
1018 KPROBE_ENTRY(error_entry)
1019         _frame RDI
1020         CFI_REL_OFFSET rax,0
1021         /* rdi slot contains rax, oldrax contains error code */
1022         cld     
1023         subq  $14*8,%rsp
1024         CFI_ADJUST_CFA_OFFSET   (14*8)
1025         movq %rsi,13*8(%rsp)
1026         CFI_REL_OFFSET  rsi,RSI
1027         movq 14*8(%rsp),%rsi    /* load rax from rdi slot */
1028         CFI_REGISTER    rax,rsi
1029         movq %rdx,12*8(%rsp)
1030         CFI_REL_OFFSET  rdx,RDX
1031         movq %rcx,11*8(%rsp)
1032         CFI_REL_OFFSET  rcx,RCX
1033         movq %rsi,10*8(%rsp)    /* store rax */ 
1034         CFI_REL_OFFSET  rax,RAX
1035         movq %r8, 9*8(%rsp)
1036         CFI_REL_OFFSET  r8,R8
1037         movq %r9, 8*8(%rsp)
1038         CFI_REL_OFFSET  r9,R9
1039         movq %r10,7*8(%rsp)
1040         CFI_REL_OFFSET  r10,R10
1041         movq %r11,6*8(%rsp)
1042         CFI_REL_OFFSET  r11,R11
1043         movq %rbx,5*8(%rsp) 
1044         CFI_REL_OFFSET  rbx,RBX
1045         movq %rbp,4*8(%rsp) 
1046         CFI_REL_OFFSET  rbp,RBP
1047         movq %r12,3*8(%rsp) 
1048         CFI_REL_OFFSET  r12,R12
1049         movq %r13,2*8(%rsp) 
1050         CFI_REL_OFFSET  r13,R13
1051         movq %r14,1*8(%rsp) 
1052         CFI_REL_OFFSET  r14,R14
1053         movq %r15,(%rsp) 
1054         CFI_REL_OFFSET  r15,R15
1055         xorl %ebx,%ebx  
1056         testl $3,CS(%rsp)
1057         je  error_kernelspace
1058 error_swapgs:   
1059         SWAPGS
1060 error_sti:      
1061         movq %rdi,RDI(%rsp)     
1062         CFI_REL_OFFSET  rdi,RDI
1063         movq %rsp,%rdi
1064         movq ORIG_RAX(%rsp),%rsi        /* get error code */ 
1065         movq $-1,ORIG_RAX(%rsp)
1066         call *%rax
1067         /* ebx: no swapgs flag (1: don't need swapgs, 0: need it) */
1068 error_exit:
1069         movl %ebx,%eax
1070         RESTORE_REST
1071         DISABLE_INTERRUPTS(CLBR_NONE)
1072         TRACE_IRQS_OFF
1073         GET_THREAD_INFO(%rcx)   
1074         testl %eax,%eax
1075         jne  retint_kernel
1076         LOCKDEP_SYS_EXIT_IRQ
1077         movl  TI_flags(%rcx),%edx
1078         movl  $_TIF_WORK_MASK,%edi
1079         andl  %edi,%edx
1080         jnz  retint_careful
1081         jmp retint_swapgs
1082         CFI_ENDPROC
1083
1084 error_kernelspace:
1085         incl %ebx
1086        /* There are two places in the kernel that can potentially fault with
1087           usergs. Handle them here. The exception handlers after
1088            iret run with kernel gs again, so don't set the user space flag.
1089            B stepping K8s sometimes report an truncated RIP for IRET 
1090            exceptions returning to compat mode. Check for these here too. */
1091         leaq irq_return(%rip),%rcx
1092         cmpq %rcx,RIP(%rsp)
1093         je   error_swapgs
1094         movl %ecx,%ecx  /* zero extend */
1095         cmpq %rcx,RIP(%rsp)
1096         je   error_swapgs
1097         cmpq $gs_change,RIP(%rsp)
1098         je   error_swapgs
1099         jmp  error_sti
1100 KPROBE_END(error_entry)
1101         
1102        /* Reload gs selector with exception handling */
1103        /* edi:  new selector */ 
1104 ENTRY(native_load_gs_index)
1105         CFI_STARTPROC
1106         pushf
1107         CFI_ADJUST_CFA_OFFSET 8
1108         DISABLE_INTERRUPTS(CLBR_ANY | ~(CLBR_RDI))
1109         SWAPGS
1110 gs_change:     
1111         movl %edi,%gs   
1112 2:      mfence          /* workaround */
1113         SWAPGS
1114         popf
1115         CFI_ADJUST_CFA_OFFSET -8
1116         ret
1117         CFI_ENDPROC
1118 ENDPROC(native_load_gs_index)
1119        
1120         .section __ex_table,"a"
1121         .align 8
1122         .quad gs_change,bad_gs
1123         .previous
1124         .section .fixup,"ax"
1125         /* running with kernelgs */
1126 bad_gs: 
1127         SWAPGS                  /* switch back to user gs */
1128         xorl %eax,%eax
1129         movl %eax,%gs
1130         jmp  2b
1131         .previous       
1132         
1133 /*
1134  * Create a kernel thread.
1135  *
1136  * C extern interface:
1137  *      extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
1138  *
1139  * asm input arguments:
1140  *      rdi: fn, rsi: arg, rdx: flags
1141  */
1142 ENTRY(kernel_thread)
1143         CFI_STARTPROC
1144         FAKE_STACK_FRAME $child_rip
1145         SAVE_ALL
1146
1147         # rdi: flags, rsi: usp, rdx: will be &pt_regs
1148         movq %rdx,%rdi
1149         orq  kernel_thread_flags(%rip),%rdi
1150         movq $-1, %rsi
1151         movq %rsp, %rdx
1152
1153         xorl %r8d,%r8d
1154         xorl %r9d,%r9d
1155         
1156         # clone now
1157         call do_fork
1158         movq %rax,RAX(%rsp)
1159         xorl %edi,%edi
1160
1161         /*
1162          * It isn't worth to check for reschedule here,
1163          * so internally to the x86_64 port you can rely on kernel_thread()
1164          * not to reschedule the child before returning, this avoids the need
1165          * of hacks for example to fork off the per-CPU idle tasks.
1166          * [Hopefully no generic code relies on the reschedule -AK]     
1167          */
1168         RESTORE_ALL
1169         UNFAKE_STACK_FRAME
1170         ret
1171         CFI_ENDPROC
1172 ENDPROC(kernel_thread)
1173         
1174 child_rip:
1175         pushq $0                # fake return address
1176         CFI_STARTPROC
1177         /*
1178          * Here we are in the child and the registers are set as they were
1179          * at kernel_thread() invocation in the parent.
1180          */
1181         movq %rdi, %rax
1182         movq %rsi, %rdi
1183         call *%rax
1184         # exit
1185         mov %eax, %edi
1186         call do_exit
1187         CFI_ENDPROC
1188 ENDPROC(child_rip)
1189
1190 /*
1191  * execve(). This function needs to use IRET, not SYSRET, to set up all state properly.
1192  *
1193  * C extern interface:
1194  *       extern long execve(char *name, char **argv, char **envp)
1195  *
1196  * asm input arguments:
1197  *      rdi: name, rsi: argv, rdx: envp
1198  *
1199  * We want to fallback into:
1200  *      extern long sys_execve(char *name, char **argv,char **envp, struct pt_regs *regs)
1201  *
1202  * do_sys_execve asm fallback arguments:
1203  *      rdi: name, rsi: argv, rdx: envp, rcx: fake frame on the stack
1204  */
1205 ENTRY(kernel_execve)
1206         CFI_STARTPROC
1207         FAKE_STACK_FRAME $0
1208         SAVE_ALL        
1209         movq %rsp,%rcx
1210         call sys_execve
1211         movq %rax, RAX(%rsp)    
1212         RESTORE_REST
1213         testq %rax,%rax
1214         je int_ret_from_sys_call
1215         RESTORE_ARGS
1216         UNFAKE_STACK_FRAME
1217         ret
1218         CFI_ENDPROC
1219 ENDPROC(kernel_execve)
1220
1221 KPROBE_ENTRY(page_fault)
1222         errorentry do_page_fault
1223 KPROBE_END(page_fault)
1224
1225 ENTRY(coprocessor_error)
1226         zeroentry do_coprocessor_error
1227 END(coprocessor_error)
1228
1229 ENTRY(simd_coprocessor_error)
1230         zeroentry do_simd_coprocessor_error     
1231 END(simd_coprocessor_error)
1232
1233 ENTRY(device_not_available)
1234         zeroentry math_state_restore
1235 END(device_not_available)
1236
1237         /* runs on exception stack */
1238 KPROBE_ENTRY(debug)
1239         INTR_FRAME
1240         PARAVIRT_ADJUST_EXCEPTION_FRAME
1241         pushq $0
1242         CFI_ADJUST_CFA_OFFSET 8         
1243         paranoidentry do_debug, DEBUG_STACK
1244         paranoidexit
1245 KPROBE_END(debug)
1246
1247         /* runs on exception stack */   
1248 KPROBE_ENTRY(nmi)
1249         INTR_FRAME
1250         PARAVIRT_ADJUST_EXCEPTION_FRAME
1251         pushq $-1
1252         CFI_ADJUST_CFA_OFFSET 8
1253         paranoidentry do_nmi, 0, 0
1254 #ifdef CONFIG_TRACE_IRQFLAGS
1255         paranoidexit 0
1256 #else
1257         jmp paranoid_exit1
1258         CFI_ENDPROC
1259 #endif
1260 KPROBE_END(nmi)
1261
1262 KPROBE_ENTRY(int3)
1263         INTR_FRAME
1264         PARAVIRT_ADJUST_EXCEPTION_FRAME
1265         pushq $0
1266         CFI_ADJUST_CFA_OFFSET 8
1267         paranoidentry do_int3, DEBUG_STACK
1268         jmp paranoid_exit1
1269         CFI_ENDPROC
1270 KPROBE_END(int3)
1271
1272 ENTRY(overflow)
1273         zeroentry do_overflow
1274 END(overflow)
1275
1276 ENTRY(bounds)
1277         zeroentry do_bounds
1278 END(bounds)
1279
1280 ENTRY(invalid_op)
1281         zeroentry do_invalid_op 
1282 END(invalid_op)
1283
1284 ENTRY(coprocessor_segment_overrun)
1285         zeroentry do_coprocessor_segment_overrun
1286 END(coprocessor_segment_overrun)
1287
1288         /* runs on exception stack */
1289 ENTRY(double_fault)
1290         XCPT_FRAME
1291         PARAVIRT_ADJUST_EXCEPTION_FRAME
1292         paranoidentry do_double_fault
1293         jmp paranoid_exit1
1294         CFI_ENDPROC
1295 END(double_fault)
1296
1297 ENTRY(invalid_TSS)
1298         errorentry do_invalid_TSS
1299 END(invalid_TSS)
1300
1301 ENTRY(segment_not_present)
1302         errorentry do_segment_not_present
1303 END(segment_not_present)
1304
1305         /* runs on exception stack */
1306 ENTRY(stack_segment)
1307         XCPT_FRAME
1308         PARAVIRT_ADJUST_EXCEPTION_FRAME
1309         paranoidentry do_stack_segment
1310         jmp paranoid_exit1
1311         CFI_ENDPROC
1312 END(stack_segment)
1313
1314 KPROBE_ENTRY(general_protection)
1315         errorentry do_general_protection
1316 KPROBE_END(general_protection)
1317
1318 ENTRY(alignment_check)
1319         errorentry do_alignment_check
1320 END(alignment_check)
1321
1322 ENTRY(divide_error)
1323         zeroentry do_divide_error
1324 END(divide_error)
1325
1326 ENTRY(spurious_interrupt_bug)
1327         zeroentry do_spurious_interrupt_bug
1328 END(spurious_interrupt_bug)
1329
1330 #ifdef CONFIG_X86_MCE
1331         /* runs on exception stack */
1332 ENTRY(machine_check)
1333         INTR_FRAME
1334         PARAVIRT_ADJUST_EXCEPTION_FRAME
1335         pushq $0
1336         CFI_ADJUST_CFA_OFFSET 8 
1337         paranoidentry do_machine_check
1338         jmp paranoid_exit1
1339         CFI_ENDPROC
1340 END(machine_check)
1341 #endif
1342
1343 /* Call softirq on interrupt stack. Interrupts are off. */
1344 ENTRY(call_softirq)
1345         CFI_STARTPROC
1346         push %rbp
1347         CFI_ADJUST_CFA_OFFSET   8
1348         CFI_REL_OFFSET rbp,0
1349         mov  %rsp,%rbp
1350         CFI_DEF_CFA_REGISTER rbp
1351         incl %gs:pda_irqcount
1352         cmove %gs:pda_irqstackptr,%rsp
1353         push  %rbp                      # backlink for old unwinder
1354         call __do_softirq
1355         leaveq
1356         CFI_DEF_CFA_REGISTER    rsp
1357         CFI_ADJUST_CFA_OFFSET   -8
1358         decl %gs:pda_irqcount
1359         ret
1360         CFI_ENDPROC
1361 ENDPROC(call_softirq)
1362
1363 KPROBE_ENTRY(ignore_sysret)
1364         CFI_STARTPROC
1365         mov $-ENOSYS,%eax
1366         sysret
1367         CFI_ENDPROC
1368 ENDPROC(ignore_sysret)
1369
1370 #ifdef CONFIG_XEN
1371 ENTRY(xen_hypervisor_callback)
1372         zeroentry xen_do_hypervisor_callback
1373 END(xen_hypervisor_callback)
1374
1375 /*
1376 # A note on the "critical region" in our callback handler.
1377 # We want to avoid stacking callback handlers due to events occurring
1378 # during handling of the last event. To do this, we keep events disabled
1379 # until we've done all processing. HOWEVER, we must enable events before
1380 # popping the stack frame (can't be done atomically) and so it would still
1381 # be possible to get enough handler activations to overflow the stack.
1382 # Although unlikely, bugs of that kind are hard to track down, so we'd
1383 # like to avoid the possibility.
1384 # So, on entry to the handler we detect whether we interrupted an
1385 # existing activation in its critical region -- if so, we pop the current
1386 # activation and restart the handler using the previous one.
1387 */
1388 ENTRY(xen_do_hypervisor_callback)   # do_hypervisor_callback(struct *pt_regs)
1389         CFI_STARTPROC
1390 /* Since we don't modify %rdi, evtchn_do_upall(struct *pt_regs) will
1391    see the correct pointer to the pt_regs */
1392         movq %rdi, %rsp            # we don't return, adjust the stack frame
1393         CFI_ENDPROC
1394         CFI_DEFAULT_STACK
1395 11:     incl %gs:pda_irqcount
1396         movq %rsp,%rbp
1397         CFI_DEF_CFA_REGISTER rbp
1398         cmovzq %gs:pda_irqstackptr,%rsp
1399         pushq %rbp                      # backlink for old unwinder
1400         call xen_evtchn_do_upcall
1401         popq %rsp
1402         CFI_DEF_CFA_REGISTER rsp
1403         decl %gs:pda_irqcount
1404         jmp  error_exit
1405         CFI_ENDPROC
1406 END(do_hypervisor_callback)
1407
1408 /*
1409 # Hypervisor uses this for application faults while it executes.
1410 # We get here for two reasons:
1411 #  1. Fault while reloading DS, ES, FS or GS
1412 #  2. Fault while executing IRET
1413 # Category 1 we do not need to fix up as Xen has already reloaded all segment
1414 # registers that could be reloaded and zeroed the others.
1415 # Category 2 we fix up by killing the current process. We cannot use the
1416 # normal Linux return path in this case because if we use the IRET hypercall
1417 # to pop the stack frame we end up in an infinite loop of failsafe callbacks.
1418 # We distinguish between categories by comparing each saved segment register
1419 # with its current contents: any discrepancy means we in category 1.
1420 */
1421 ENTRY(xen_failsafe_callback)
1422         framesz = (RIP-0x30)    /* workaround buggy gas */
1423         _frame framesz
1424         CFI_REL_OFFSET rcx, 0
1425         CFI_REL_OFFSET r11, 8
1426         movw %ds,%cx
1427         cmpw %cx,0x10(%rsp)
1428         CFI_REMEMBER_STATE
1429         jne 1f
1430         movw %es,%cx
1431         cmpw %cx,0x18(%rsp)
1432         jne 1f
1433         movw %fs,%cx
1434         cmpw %cx,0x20(%rsp)
1435         jne 1f
1436         movw %gs,%cx
1437         cmpw %cx,0x28(%rsp)
1438         jne 1f
1439         /* All segments match their saved values => Category 2 (Bad IRET). */
1440         movq (%rsp),%rcx
1441         CFI_RESTORE rcx
1442         movq 8(%rsp),%r11
1443         CFI_RESTORE r11
1444         addq $0x30,%rsp
1445         CFI_ADJUST_CFA_OFFSET -0x30
1446         pushq $0
1447         CFI_ADJUST_CFA_OFFSET 8
1448         pushq %r11
1449         CFI_ADJUST_CFA_OFFSET 8
1450         pushq %rcx
1451         CFI_ADJUST_CFA_OFFSET 8
1452         jmp general_protection
1453         CFI_RESTORE_STATE
1454 1:      /* Segment mismatch => Category 1 (Bad segment). Retry the IRET. */
1455         movq (%rsp),%rcx
1456         CFI_RESTORE rcx
1457         movq 8(%rsp),%r11
1458         CFI_RESTORE r11
1459         addq $0x30,%rsp
1460         CFI_ADJUST_CFA_OFFSET -0x30
1461         pushq $0
1462         CFI_ADJUST_CFA_OFFSET 8
1463         SAVE_ALL
1464         jmp error_exit
1465         CFI_ENDPROC
1466 END(xen_failsafe_callback)
1467
1468 #endif /* CONFIG_XEN */