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