This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / arch / x86_64 / kernel / entry-xen.S
1 /*
2  *  linux/arch/x86_64/entry.S
3  *
4  *  Copyright (C) 1991, 1992  Linus Torvalds
5  *  Copyright (C) 2000, 2001, 2002  Andi Kleen SuSE Labs
6  *  Copyright (C) 2000  Pavel Machek <pavel@suse.cz>
7  * 
8  *  $Id$
9  *
10  *  Jun Nakajima <jun.nakajima@intel.com>
11  *  Asit Mallick <asit.k.mallick@intel.com>
12  *      Modified for Xen
13  */
14
15 /*
16  * entry.S contains the system-call and fault low-level handling routines.
17  *
18  * NOTE: This code handles signal-recognition, which happens every time
19  * after an interrupt and after each system call.
20  * 
21  * Normal syscalls and interrupts don't save a full stack frame, this is 
22  * only done for syscall tracing, signals or fork/exec et.al.
23  * 
24  * A note on terminology:        
25  * - top of stack: Architecture defined interrupt frame from SS to RIP 
26  * at the top of the kernel process stack.      
27  * - partial stack frame: partially saved registers upto R11.
28  * - full stack frame: Like partial stack frame, but all register saved. 
29  *      
30  * TODO:         
31  * - schedule it carefully for the final hardware.
32  */
33
34 #define ASSEMBLY 1
35 #include <linux/config.h>
36 #ifdef CONFIG_DEBUG_INFO
37 #undef CONFIG_DEBUG_INFO
38 #endif
39 #include <linux/linkage.h>
40 #include <asm/segment.h>
41 #include <asm/smp.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/errno.h>
53 #include <xen/interface/arch-x86_64.h>
54 #include <xen/interface/features.h>
55
56 #include "irq_vectors.h"
57
58 #include "xen_entry.S"
59         
60         .code64
61
62 #ifndef CONFIG_PREEMPT
63 #define retint_kernel retint_restore_args
64 #endif  
65
66 NMI_MASK = 0x80000000
67         
68 /*
69  * C code is not supposed to know about undefined top of stack. Every time 
70  * a C function with an pt_regs argument is called from the SYSCALL based 
71  * fast path FIXUP_TOP_OF_STACK is needed.
72  * RESTORE_TOP_OF_STACK syncs the syscall state after any possible ptregs
73  * manipulation.
74  */             
75                 
76         /* %rsp:at FRAMEEND */ 
77         .macro FIXUP_TOP_OF_STACK tmp
78         movq    $__USER_CS,CS(%rsp)
79         movq    $-1,RCX(%rsp)
80         .endm
81
82         .macro RESTORE_TOP_OF_STACK tmp,offset=0
83         .endm
84
85         .macro FAKE_STACK_FRAME child_rip
86         /* push in order ss, rsp, eflags, cs, rip */
87         xorl %eax, %eax
88         pushq %rax /* ss */
89         CFI_ADJUST_CFA_OFFSET   8
90         /*CFI_REL_OFFSET        ss,0*/
91         pushq %rax /* rsp */
92         CFI_ADJUST_CFA_OFFSET   8
93         CFI_REL_OFFSET  rsp,0
94         pushq $(1<<9) /* eflags - interrupts on */
95         CFI_ADJUST_CFA_OFFSET   8
96         /*CFI_REL_OFFSET        rflags,0*/
97         pushq $__KERNEL_CS /* cs */
98         CFI_ADJUST_CFA_OFFSET   8
99         /*CFI_REL_OFFSET        cs,0*/
100         pushq \child_rip /* rip */
101         CFI_ADJUST_CFA_OFFSET   8
102         CFI_REL_OFFSET  rip,0
103         pushq   %rax /* orig rax */
104         CFI_ADJUST_CFA_OFFSET   8
105         .endm
106
107         .macro UNFAKE_STACK_FRAME
108         addq $8*6, %rsp
109         CFI_ADJUST_CFA_OFFSET   -(6*8)
110         .endm
111
112         .macro  CFI_DEFAULT_STACK start=1
113         .if \start
114         CFI_STARTPROC   simple
115         CFI_DEF_CFA     rsp,SS+8
116         .else
117         CFI_DEF_CFA_OFFSET SS+8
118         .endif
119         CFI_REL_OFFSET  r15,R15
120         CFI_REL_OFFSET  r14,R14
121         CFI_REL_OFFSET  r13,R13
122         CFI_REL_OFFSET  r12,R12
123         CFI_REL_OFFSET  rbp,RBP
124         CFI_REL_OFFSET  rbx,RBX
125         CFI_REL_OFFSET  r11,R11
126         CFI_REL_OFFSET  r10,R10
127         CFI_REL_OFFSET  r9,R9
128         CFI_REL_OFFSET  r8,R8
129         CFI_REL_OFFSET  rax,RAX
130         CFI_REL_OFFSET  rcx,RCX
131         CFI_REL_OFFSET  rdx,RDX
132         CFI_REL_OFFSET  rsi,RSI
133         CFI_REL_OFFSET  rdi,RDI
134         CFI_REL_OFFSET  rip,RIP
135         /*CFI_REL_OFFSET        cs,CS*/
136         /*CFI_REL_OFFSET        rflags,EFLAGS*/
137         CFI_REL_OFFSET  rsp,RSP
138         /*CFI_REL_OFFSET        ss,SS*/
139         .endm
140
141         /*
142          * Must be consistent with the definition in arch-x86_64.h:    
143          *     struct iret_context {
144          *        u64 rax, r11, rcx, flags, rip, cs, rflags, rsp, ss;
145          *     };
146          * #define VGCF_IN_SYSCALL (1<<8) 
147          */
148         .macro HYPERVISOR_IRET flag
149         testb $3,1*8(%rsp)
150         jnz   2f
151         testl $NMI_MASK,2*8(%rsp)
152         jnz   2f
153
154         testb $1,(xen_features+XENFEAT_supervisor_mode_kernel)
155         jnz   1f
156
157         /* Direct iret to kernel space. Correct CS and SS. */
158         orb   $3,1*8(%rsp)
159         orb   $3,4*8(%rsp)
160 1:      iretq
161
162 2:      /* Slow iret via hypervisor. */
163         andl  $~NMI_MASK, 16(%rsp)
164         pushq $\flag
165         jmp  hypercall_page + (__HYPERVISOR_iret * 32)
166         .endm
167
168         .macro SWITCH_TO_KERNEL ssoff,adjust=0
169         jc  1f
170         orb  $1,\ssoff-\adjust+4(%rsp)
171 1:
172         .endm
173
174 /*
175  * A newly forked process directly context switches into this.
176  */     
177 /* rdi: prev */ 
178 ENTRY(ret_from_fork)
179         CFI_DEFAULT_STACK
180         call schedule_tail
181         GET_THREAD_INFO(%rcx)
182         testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%rcx)
183         jnz rff_trace
184 rff_action:     
185         RESTORE_REST
186         testl $3,CS-ARGOFFSET(%rsp)     # from kernel_thread?
187         je   int_ret_from_sys_call
188         testl $_TIF_IA32,threadinfo_flags(%rcx)
189         jnz  int_ret_from_sys_call
190         RESTORE_TOP_OF_STACK %rdi,ARGOFFSET
191         jmp ret_from_sys_call
192 rff_trace:
193         movq %rsp,%rdi
194         call syscall_trace_leave
195         GET_THREAD_INFO(%rcx)   
196         jmp rff_action
197         CFI_ENDPROC
198
199 /*
200  * System call entry. Upto 6 arguments in registers are supported.
201  *
202  * SYSCALL does not save anything on the stack and does not change the
203  * stack pointer.
204  */
205                 
206 /*
207  * Register setup:      
208  * rax  system call number
209  * rdi  arg0
210  * rcx  return address for syscall/sysret, C arg3 
211  * rsi  arg1
212  * rdx  arg2    
213  * r10  arg3    (--> moved to rcx for C)
214  * r8   arg4
215  * r9   arg5
216  * r11  eflags for syscall/sysret, temporary for C
217  * r12-r15,rbp,rbx saved by C code, not touched.                
218  * 
219  * Interrupts are off on entry.
220  * Only called from user space.
221  *
222  * XXX  if we had a free scratch register we could save the RSP into the stack frame
223  *      and report it properly in ps. Unfortunately we haven't.
224  *
225  * When user can change the frames always force IRET. That is because
226  * it deals with uncanonical addresses better. SYSRET has trouble
227  * with them due to bugs in both AMD and Intel CPUs.
228  */                                     
229
230 ENTRY(system_call)
231         CFI_STARTPROC   simple
232         CFI_DEF_CFA     rsp,0
233         CFI_REGISTER    rip,rcx
234         /*CFI_REGISTER  rflags,r11*/
235         SAVE_ARGS -8,0
236         movq  %rax,ORIG_RAX-ARGOFFSET(%rsp) 
237         XEN_UNBLOCK_EVENTS(%r11)        
238         GET_THREAD_INFO(%rcx)
239         testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%rcx)
240         CFI_REMEMBER_STATE
241         jnz tracesys
242         cmpq $__NR_syscall_max,%rax
243         ja badsys
244         movq %r10,%rcx
245         call *sys_call_table(,%rax,8)  # XXX:    rip relative
246         movq %rax,RAX-ARGOFFSET(%rsp)
247 /*
248  * Syscall return path ending with SYSRET (fast path)
249  * Has incomplete stack frame and undefined top of stack. 
250  */             
251         .globl ret_from_sys_call
252 ret_from_sys_call:
253         movl $_TIF_ALLWORK_MASK,%edi
254         /* edi: flagmask */
255 sysret_check:           
256         GET_THREAD_INFO(%rcx)
257         XEN_BLOCK_EVENTS(%rsi)        
258         movl threadinfo_flags(%rcx),%edx
259         andl %edi,%edx
260         CFI_REMEMBER_STATE
261         jnz  sysret_careful 
262         XEN_UNBLOCK_EVENTS(%rsi)                
263         CFI_REGISTER    rip,rcx
264         RESTORE_ARGS 0,8,0
265         /*CFI_REGISTER  rflags,r11*/
266         HYPERVISOR_IRET VGCF_IN_SYSCALL
267
268         /* Handle reschedules */
269         /* edx: work, edi: workmask */  
270 sysret_careful:
271         CFI_RESTORE_STATE
272         bt $TIF_NEED_RESCHED,%edx
273         jnc sysret_signal
274         XEN_BLOCK_EVENTS(%rsi)        
275         pushq %rdi
276         CFI_ADJUST_CFA_OFFSET 8
277         call schedule
278         popq  %rdi
279         CFI_ADJUST_CFA_OFFSET -8
280         jmp sysret_check
281
282         /* Handle a signal */ 
283 sysret_signal:
284 /*      sti */
285         XEN_UNBLOCK_EVENTS(%rsi)        
286         testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx
287         jz    1f
288
289         /* Really a signal */
290         /* edx: work flags (arg3) */
291         leaq do_notify_resume(%rip),%rax
292         leaq -ARGOFFSET(%rsp),%rdi # &pt_regs -> arg1
293         xorl %esi,%esi # oldset -> arg2
294         call ptregscall_common
295 1:      movl $_TIF_NEED_RESCHED,%edi
296         /* Use IRET because user could have changed frame. This
297            works because ptregscall_common has called FIXUP_TOP_OF_STACK. */
298         cli
299         jmp int_with_check
300         
301 badsys:
302         movq $-ENOSYS,RAX-ARGOFFSET(%rsp)
303         jmp ret_from_sys_call
304
305         /* Do syscall tracing */
306 tracesys:                        
307         CFI_RESTORE_STATE
308         SAVE_REST
309         movq $-ENOSYS,RAX(%rsp)
310         FIXUP_TOP_OF_STACK %rdi
311         movq %rsp,%rdi
312         call syscall_trace_enter
313         LOAD_ARGS ARGOFFSET  /* reload args from stack in case ptrace changed it */
314         RESTORE_REST
315         cmpq $__NR_syscall_max,%rax
316         ja  1f
317         movq %r10,%rcx  /* fixup for C */
318         call *sys_call_table(,%rax,8)
319         movq %rax,RAX-ARGOFFSET(%rsp)
320 1:      SAVE_REST
321         movq %rsp,%rdi
322         call syscall_trace_leave
323         RESTORE_TOP_OF_STACK %rbx
324         RESTORE_REST
325         /* Use IRET because user could have changed frame */
326         jmp int_ret_from_sys_call
327         CFI_ENDPROC
328                 
329 /* 
330  * Syscall return path ending with IRET.
331  * Has correct top of stack, but partial stack frame.
332  */     
333 ENTRY(int_ret_from_sys_call)
334         CFI_STARTPROC   simple
335         CFI_DEF_CFA     rsp,SS+8-ARGOFFSET
336         /*CFI_REL_OFFSET        ss,SS-ARGOFFSET*/
337         CFI_REL_OFFSET  rsp,RSP-ARGOFFSET
338         /*CFI_REL_OFFSET        rflags,EFLAGS-ARGOFFSET*/
339         /*CFI_REL_OFFSET        cs,CS-ARGOFFSET*/
340         CFI_REL_OFFSET  rip,RIP-ARGOFFSET
341         CFI_REL_OFFSET  rdx,RDX-ARGOFFSET
342         CFI_REL_OFFSET  rcx,RCX-ARGOFFSET
343         CFI_REL_OFFSET  rax,RAX-ARGOFFSET
344         CFI_REL_OFFSET  rdi,RDI-ARGOFFSET
345         CFI_REL_OFFSET  rsi,RSI-ARGOFFSET
346         CFI_REL_OFFSET  r8,R8-ARGOFFSET
347         CFI_REL_OFFSET  r9,R9-ARGOFFSET
348         CFI_REL_OFFSET  r10,R10-ARGOFFSET
349         CFI_REL_OFFSET  r11,R11-ARGOFFSET
350         XEN_BLOCK_EVENTS(%rsi)
351         testb $3,CS-ARGOFFSET(%rsp)
352         jnz 1f
353         /* Need to set the proper %ss (not NULL) for ring 3 iretq */
354         movl $__KERNEL_DS,SS-ARGOFFSET(%rsp)
355         jmp retint_restore_args   # retrun from ring3 kernel
356 1:              
357         movl $_TIF_ALLWORK_MASK,%edi
358         /* edi: mask to check */
359 int_with_check:
360         GET_THREAD_INFO(%rcx)
361         movl threadinfo_flags(%rcx),%edx
362         andl %edi,%edx
363         jnz   int_careful
364         andl    $~TS_COMPAT,threadinfo_status(%rcx)
365         jmp   retint_restore_args
366
367         /* Either reschedule or signal or syscall exit tracking needed. */
368         /* First do a reschedule test. */
369         /* edx: work, edi: workmask */
370 int_careful:
371         bt $TIF_NEED_RESCHED,%edx
372         jnc  int_very_careful
373 /*      sti */
374         XEN_UNBLOCK_EVENTS(%rsi)
375         pushq %rdi
376         CFI_ADJUST_CFA_OFFSET 8
377         call schedule
378         popq %rdi
379         CFI_ADJUST_CFA_OFFSET -8
380         cli
381         jmp int_with_check
382
383         /* handle signals and tracing -- both require a full stack frame */
384 int_very_careful:
385 /*      sti */
386         XEN_UNBLOCK_EVENTS(%rsi)
387         SAVE_REST
388         /* Check for syscall exit trace */      
389         testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edx
390         jz int_signal
391         pushq %rdi
392         CFI_ADJUST_CFA_OFFSET 8
393         leaq 8(%rsp),%rdi       # &ptregs -> arg1       
394         call syscall_trace_leave
395         popq %rdi
396         CFI_ADJUST_CFA_OFFSET -8
397         andl $~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edi
398         cli
399         jmp int_restore_rest
400         
401 int_signal:
402         testl $(_TIF_NOTIFY_RESUME|_TIF_SIGPENDING|_TIF_SINGLESTEP),%edx
403         jz 1f
404         movq %rsp,%rdi          # &ptregs -> arg1
405         xorl %esi,%esi          # oldset -> arg2
406         call do_notify_resume
407 1:      movl $_TIF_NEED_RESCHED,%edi    
408 int_restore_rest:
409         RESTORE_REST
410         cli
411         jmp int_with_check
412         CFI_ENDPROC
413                 
414 /* 
415  * Certain special system calls that need to save a complete full stack frame.
416  */                                                             
417         
418         .macro PTREGSCALL label,func,arg
419         .globl \label
420 \label:
421         leaq    \func(%rip),%rax
422         leaq    -ARGOFFSET+8(%rsp),\arg /* 8 for return address */
423         jmp     ptregscall_common
424         .endm
425
426         CFI_STARTPROC
427
428         PTREGSCALL stub_clone, sys_clone, %r8
429         PTREGSCALL stub_fork, sys_fork, %rdi
430         PTREGSCALL stub_vfork, sys_vfork, %rdi
431         PTREGSCALL stub_rt_sigsuspend, sys_rt_sigsuspend, %rdx
432         PTREGSCALL stub_sigaltstack, sys_sigaltstack, %rdx
433         PTREGSCALL stub_iopl, sys_iopl, %rsi
434
435 ENTRY(ptregscall_common)
436         popq %r11
437         CFI_ADJUST_CFA_OFFSET -8
438         CFI_REGISTER rip, r11
439         SAVE_REST
440         movq %r11, %r15
441         CFI_REGISTER rip, r15
442         FIXUP_TOP_OF_STACK %r11
443         call *%rax
444         RESTORE_TOP_OF_STACK %r11
445         movq %r15, %r11
446         CFI_REGISTER rip, r11
447         RESTORE_REST
448         pushq %r11
449         CFI_ADJUST_CFA_OFFSET 8
450         CFI_REL_OFFSET rip, 0
451         ret
452         CFI_ENDPROC
453         
454 ENTRY(stub_execve)
455         CFI_STARTPROC
456         popq %r11
457         CFI_ADJUST_CFA_OFFSET -8
458         CFI_REGISTER rip, r11
459         SAVE_REST
460         FIXUP_TOP_OF_STACK %r11
461         call sys_execve
462         RESTORE_TOP_OF_STACK %r11
463         movq %rax,RAX(%rsp)
464         RESTORE_REST
465         jmp int_ret_from_sys_call
466         CFI_ENDPROC
467         
468 /*
469  * sigreturn is special because it needs to restore all registers on return.
470  * This cannot be done with SYSRET, so use the IRET return path instead.
471  */                
472 ENTRY(stub_rt_sigreturn)
473         CFI_STARTPROC
474         addq $8, %rsp
475         CFI_ADJUST_CFA_OFFSET   -8
476         SAVE_REST
477         movq %rsp,%rdi
478         FIXUP_TOP_OF_STACK %r11
479         call sys_rt_sigreturn
480         movq %rax,RAX(%rsp) # fixme, this could be done at the higher layer
481         RESTORE_REST
482         jmp int_ret_from_sys_call
483         CFI_ENDPROC
484
485 /*
486  * initial frame state for interrupts and exceptions
487  */
488         .macro _frame ref
489         CFI_STARTPROC simple
490         CFI_DEF_CFA rsp,SS+8-\ref
491         /*CFI_REL_OFFSET ss,SS-\ref*/
492         CFI_REL_OFFSET rsp,RSP-\ref
493         /*CFI_REL_OFFSET rflags,EFLAGS-\ref*/
494         /*CFI_REL_OFFSET cs,CS-\ref*/
495         CFI_REL_OFFSET rip,RIP-\ref
496         .endm
497
498 /* initial frame state for interrupts (and exceptions without error code) */
499 #define INTR_FRAME _frame RIP
500 /* initial frame state for exceptions with error code (and interrupts with
501    vector already pushed) */
502 #define XCPT_FRAME _frame ORIG_RAX
503
504 /* 
505  * Interrupt exit.
506  *
507  */ 
508
509 retint_check:
510         movl threadinfo_flags(%rcx),%edx
511         andl %edi,%edx
512         CFI_REMEMBER_STATE
513         jnz  retint_careful
514 retint_restore_args:
515         movl EFLAGS-REST_SKIP(%rsp), %eax
516         shr $9, %eax                    # EAX[0] == IRET_EFLAGS.IF
517         XEN_GET_VCPU_INFO(%rsi)
518         andb evtchn_upcall_mask(%rsi),%al
519         andb $1,%al                     # EAX[0] == IRET_EFLAGS.IF & event_mask
520         jnz restore_all_enable_events   #        != 0 => enable event delivery
521         XEN_PUT_VCPU_INFO(%rsi)
522                 
523         RESTORE_ARGS 0,8,0
524         HYPERVISOR_IRET 0
525         
526         /* edi: workmask, edx: work */
527 retint_careful:
528         CFI_RESTORE_STATE
529         bt    $TIF_NEED_RESCHED,%edx
530         jnc   retint_signal
531         XEN_UNBLOCK_EVENTS(%rsi)
532 /*      sti */        
533         pushq %rdi
534         CFI_ADJUST_CFA_OFFSET   8
535         call  schedule
536         popq %rdi               
537         CFI_ADJUST_CFA_OFFSET   -8
538         XEN_BLOCK_EVENTS(%rsi)          
539         GET_THREAD_INFO(%rcx)
540 /*      cli */
541         jmp retint_check
542         
543 retint_signal:
544         testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx
545         jz    retint_restore_args
546         XEN_UNBLOCK_EVENTS(%rsi)
547         SAVE_REST
548         movq $-1,ORIG_RAX(%rsp)                         
549         xorl %esi,%esi          # oldset
550         movq %rsp,%rdi          # &pt_regs
551         call do_notify_resume
552         RESTORE_REST
553         XEN_BLOCK_EVENTS(%rsi)          
554         movl $_TIF_NEED_RESCHED,%edi
555         GET_THREAD_INFO(%rcx)
556         jmp retint_check
557
558 #ifdef CONFIG_PREEMPT
559         /* Returning to kernel space. Check if we need preemption */
560         /* rcx:  threadinfo. interrupts off. */
561         .p2align
562 retint_kernel:  
563         cmpl $0,threadinfo_preempt_count(%rcx)
564         jnz  retint_restore_args
565         bt  $TIF_NEED_RESCHED,threadinfo_flags(%rcx)
566         jnc  retint_restore_args
567         bt   $9,EFLAGS-ARGOFFSET(%rsp)  /* interrupts off? */
568         jnc  retint_restore_args
569         call preempt_schedule_irq
570         jmp retint_kernel       /* check again */
571 #endif  
572         CFI_ENDPROC
573         
574 /*
575  * APIC interrupts.
576  */             
577         .macro apicinterrupt num,func
578         INTR_FRAME
579         pushq $~(\num)
580         CFI_ADJUST_CFA_OFFSET 8
581         interrupt \func
582         jmp error_entry
583         CFI_ENDPROC
584         .endm
585
586 #ifndef CONFIG_XEN
587 ENTRY(thermal_interrupt)
588         apicinterrupt THERMAL_APIC_VECTOR,smp_thermal_interrupt
589
590 ENTRY(threshold_interrupt)
591         apicinterrupt THRESHOLD_APIC_VECTOR,mce_threshold_interrupt
592
593 #ifdef CONFIG_SMP       
594 ENTRY(reschedule_interrupt)
595         apicinterrupt RESCHEDULE_VECTOR,smp_reschedule_interrupt
596
597         .macro INVALIDATE_ENTRY num
598 ENTRY(invalidate_interrupt\num)
599         apicinterrupt INVALIDATE_TLB_VECTOR_START+\num,smp_invalidate_interrupt 
600         .endm
601
602         INVALIDATE_ENTRY 0
603         INVALIDATE_ENTRY 1
604         INVALIDATE_ENTRY 2
605         INVALIDATE_ENTRY 3
606         INVALIDATE_ENTRY 4
607         INVALIDATE_ENTRY 5
608         INVALIDATE_ENTRY 6
609         INVALIDATE_ENTRY 7
610
611 ENTRY(call_function_interrupt)
612         apicinterrupt CALL_FUNCTION_VECTOR,smp_call_function_interrupt
613 #endif
614
615 #ifdef CONFIG_X86_LOCAL_APIC    
616 ENTRY(apic_timer_interrupt)
617         apicinterrupt LOCAL_TIMER_VECTOR,smp_apic_timer_interrupt
618
619 ENTRY(error_interrupt)
620         apicinterrupt ERROR_APIC_VECTOR,smp_error_interrupt
621
622 ENTRY(spurious_interrupt)
623         apicinterrupt SPURIOUS_APIC_VECTOR,smp_spurious_interrupt
624 #endif
625 #endif /* !CONFIG_XEN */
626                                 
627 /*
628  * Exception entry points.
629  */             
630         .macro zeroentry sym
631         INTR_FRAME
632         movq (%rsp),%rcx
633         movq 8(%rsp),%r11
634         addq $0x10,%rsp /* skip rcx and r11 */
635         pushq $0        /* push error code/oldrax */ 
636         CFI_ADJUST_CFA_OFFSET 8
637         pushq %rax      /* push real oldrax to the rdi slot */ 
638         CFI_ADJUST_CFA_OFFSET 8
639         leaq  \sym(%rip),%rax
640         jmp error_entry
641         CFI_ENDPROC
642         .endm   
643
644         .macro errorentry sym
645         XCPT_FRAME
646         movq (%rsp),%rcx
647         movq 8(%rsp),%r11
648         addq $0x10,%rsp /* rsp points to the error code */
649         pushq %rax
650         CFI_ADJUST_CFA_OFFSET 8
651         leaq  \sym(%rip),%rax
652         jmp error_entry
653         CFI_ENDPROC
654         .endm
655
656 #if 0 /* not XEN */
657         /* error code is on the stack already */
658         /* handle NMI like exceptions that can happen everywhere */
659         .macro paranoidentry sym, ist=0
660         movq (%rsp),%rcx
661         movq 8(%rsp),%r11
662         addq $0x10,%rsp /* skip rcx and r11 */        
663         SAVE_ALL
664         cld
665 #if 0 /* not XEN */
666         movl $1,%ebx
667         movl  $MSR_GS_BASE,%ecx
668         rdmsr
669         testl %edx,%edx
670         js    1f
671         swapgs
672         xorl  %ebx,%ebx
673 1:
674 #endif
675         .if \ist
676         movq    %gs:pda_data_offset, %rbp
677         .endif
678         movq %rsp,%rdi
679         movq ORIG_RAX(%rsp),%rsi
680         movq $-1,ORIG_RAX(%rsp)
681         .if \ist
682         subq    $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
683         .endif
684         call \sym
685         .if \ist
686         addq    $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
687         .endif
688 /*      cli */
689         XEN_BLOCK_EVENTS(%rsi)          
690         .endm
691 #endif
692         
693 /*
694  * Exception entry point. This expects an error code/orig_rax on the stack
695  * and the exception handler in %rax.   
696  */                                             
697 ENTRY(error_entry)
698         _frame RDI
699         /* rdi slot contains rax, oldrax contains error code */
700         cld     
701         subq  $14*8,%rsp
702         CFI_ADJUST_CFA_OFFSET   (14*8)
703         movq %rsi,13*8(%rsp)
704         CFI_REL_OFFSET  rsi,RSI
705         movq 14*8(%rsp),%rsi    /* load rax from rdi slot */
706         movq %rdx,12*8(%rsp)
707         CFI_REL_OFFSET  rdx,RDX
708         movq %rcx,11*8(%rsp)
709         CFI_REL_OFFSET  rcx,RCX
710         movq %rsi,10*8(%rsp)    /* store rax */ 
711         CFI_REL_OFFSET  rax,RAX
712         movq %r8, 9*8(%rsp)
713         CFI_REL_OFFSET  r8,R8
714         movq %r9, 8*8(%rsp)
715         CFI_REL_OFFSET  r9,R9
716         movq %r10,7*8(%rsp)
717         CFI_REL_OFFSET  r10,R10
718         movq %r11,6*8(%rsp)
719         CFI_REL_OFFSET  r11,R11
720         movq %rbx,5*8(%rsp) 
721         CFI_REL_OFFSET  rbx,RBX
722         movq %rbp,4*8(%rsp) 
723         CFI_REL_OFFSET  rbp,RBP
724         movq %r12,3*8(%rsp) 
725         CFI_REL_OFFSET  r12,R12
726         movq %r13,2*8(%rsp) 
727         CFI_REL_OFFSET  r13,R13
728         movq %r14,1*8(%rsp) 
729         CFI_REL_OFFSET  r14,R14
730         movq %r15,(%rsp) 
731         CFI_REL_OFFSET  r15,R15
732 #if 0        
733         cmpl $__KERNEL_CS,CS(%rsp)
734         je  error_kernelspace
735 #endif        
736 error_call_handler:
737         movq %rdi, RDI(%rsp)            
738         movq %rsp,%rdi
739         movq ORIG_RAX(%rsp),%rsi        # get error code 
740         movq $-1,ORIG_RAX(%rsp)
741         call *%rax
742 error_exit:             
743         RESTORE_REST
744 /*      cli */
745         XEN_BLOCK_EVENTS(%rsi)          
746         GET_THREAD_INFO(%rcx)   
747         testb $3,CS-ARGOFFSET(%rsp)
748         jz retint_kernel
749         movl  threadinfo_flags(%rcx),%edx
750         movl  $_TIF_WORK_MASK,%edi      
751         andl  %edi,%edx
752         jnz   retint_careful
753         jmp   retint_restore_args
754
755 error_kernelspace:
756          /*
757          * We need to re-write the logic here because we don't do iretq to 
758          * to return to user mode. It's still possible that we get trap/fault
759          * in the kernel (when accessing buffers pointed to by system calls, 
760          * for example).
761          *
762          */           
763 #if 0
764         incl %ebx
765        /* There are two places in the kernel that can potentially fault with
766           usergs. Handle them here. The exception handlers after
767            iret run with kernel gs again, so don't set the user space flag.
768            B stepping K8s sometimes report an truncated RIP for IRET 
769            exceptions returning to compat mode. Check for these here too. */
770         leaq iret_label(%rip),%rbp
771         cmpq %rbp,RIP(%rsp) 
772         je   error_swapgs
773         movl %ebp,%ebp  /* zero extend */
774         cmpq %rbp,RIP(%rsp) 
775         je   error_swapgs
776         cmpq $gs_change,RIP(%rsp)
777         je   error_swapgs
778         jmp  error_sti
779 #endif        
780         
781 ENTRY(hypervisor_callback)
782         zeroentry do_hypervisor_callback
783         
784 /*
785  * Copied from arch/xen/i386/kernel/entry.S
786  */               
787 # A note on the "critical region" in our callback handler.
788 # We want to avoid stacking callback handlers due to events occurring
789 # during handling of the last event. To do this, we keep events disabled
790 # until we've done all processing. HOWEVER, we must enable events before
791 # popping the stack frame (can't be done atomically) and so it would still
792 # be possible to get enough handler activations to overflow the stack.
793 # Although unlikely, bugs of that kind are hard to track down, so we'd
794 # like to avoid the possibility.
795 # So, on entry to the handler we detect whether we interrupted an
796 # existing activation in its critical region -- if so, we pop the current
797 # activation and restart the handler using the previous one.
798 ENTRY(do_hypervisor_callback)   # do_hypervisor_callback(struct *pt_regs)
799 # Since we don't modify %rdi, evtchn_do_upall(struct *pt_regs) will
800 # see the correct pointer to the pt_regs
801         movq %rdi, %rsp            # we don't return, adjust the stack frame
802 11:     movq %gs:pda_irqstackptr,%rax
803         incl %gs:pda_irqcount
804         cmovzq %rax,%rsp
805         pushq %rdi
806         call evtchn_do_upcall
807         popq %rsp
808         decl %gs:pda_irqcount
809         jmp  error_exit
810
811 #ifdef CONFIG_X86_LOCAL_APIC
812 KPROBE_ENTRY(nmi)
813         zeroentry do_nmi_callback
814 ENTRY(do_nmi_callback)
815         addq $8, %rsp
816         call do_nmi
817         orl  $NMI_MASK,EFLAGS(%rsp)
818         RESTORE_REST
819         XEN_BLOCK_EVENTS(%rsi)
820         GET_THREAD_INFO(%rcx)
821         jmp  retint_restore_args
822         .previous .text
823 #endif
824
825         ALIGN
826 restore_all_enable_events:  
827         XEN_UNBLOCK_EVENTS(%rsi)        # %rsi is already set up...
828
829 scrit:  /**** START OF CRITICAL REGION ****/
830         XEN_TEST_PENDING(%rsi)
831         jnz  14f                        # process more events if necessary...
832         XEN_PUT_VCPU_INFO(%rsi)
833         RESTORE_ARGS 0,8,0
834         HYPERVISOR_IRET 0
835         
836 14:     XEN_LOCKED_BLOCK_EVENTS(%rsi)
837         XEN_PUT_VCPU_INFO(%rsi)
838         SAVE_REST
839         movq %rsp,%rdi                  # set the argument again
840         jmp  11b
841 ecrit:  /**** END OF CRITICAL REGION ****/
842 # At this point, unlike on x86-32, we don't do the fixup to simplify the 
843 # code and the stack frame is more complex on x86-64.
844 # When the kernel is interrupted in the critical section, the kernel 
845 # will do IRET in that case, and everything will be restored at that point, 
846 # i.e. it just resumes from the next instruction interrupted with the same context. 
847
848 # Hypervisor uses this for application faults while it executes.
849 # We get here for two reasons:
850 #  1. Fault while reloading DS, ES, FS or GS
851 #  2. Fault while executing IRET
852 # Category 1 we do not need to fix up as Xen has already reloaded all segment
853 # registers that could be reloaded and zeroed the others.
854 # Category 2 we fix up by killing the current process. We cannot use the
855 # normal Linux return path in this case because if we use the IRET hypercall
856 # to pop the stack frame we end up in an infinite loop of failsafe callbacks.
857 # We distinguish between categories by comparing each saved segment register
858 # with its current contents: any discrepancy means we in category 1.
859 ENTRY(failsafe_callback)
860         movw %ds,%cx
861         cmpw %cx,0x10(%rsp)
862         jne 1f
863         movw %es,%cx
864         cmpw %cx,0x18(%rsp)
865         jne 1f
866         movw %fs,%cx
867         cmpw %cx,0x20(%rsp)
868         jne 1f
869         movw %gs,%cx
870         cmpw %cx,0x28(%rsp)
871         jne 1f
872         /* All segments match their saved values => Category 2 (Bad IRET). */
873         movq (%rsp),%rcx
874         movq 8(%rsp),%r11
875         addq $0x30,%rsp
876         movq $-9999,%rdi        /* better code? */
877         jmp do_exit                     
878 1:      /* Segment mismatch => Category 1 (Bad segment). Retry the IRET. */
879         movq (%rsp),%rcx
880         movq 8(%rsp),%r11
881         addq $0x30,%rsp
882         pushq $0
883         SAVE_ALL
884         jmp error_exit
885 #if 0         
886         .section __ex_table,"a"
887         .align 8
888         .quad gs_change,bad_gs
889         .previous
890         .section .fixup,"ax"
891         /* running with kernelgs */
892 bad_gs: 
893 /*      swapgs          */      /* switch back to user gs */
894         xorl %eax,%eax
895         movl %eax,%gs
896         jmp  2b
897         .previous       
898 #endif
899         
900 /*
901  * Create a kernel thread.
902  *
903  * C extern interface:
904  *      extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
905  *
906  * asm input arguments:
907  *      rdi: fn, rsi: arg, rdx: flags
908  */
909 ENTRY(kernel_thread)
910         CFI_STARTPROC
911         FAKE_STACK_FRAME $child_rip
912         SAVE_ALL
913
914         # rdi: flags, rsi: usp, rdx: will be &pt_regs
915         movq %rdx,%rdi
916         orq  kernel_thread_flags(%rip),%rdi
917         movq $-1, %rsi
918         movq %rsp, %rdx
919
920         xorl %r8d,%r8d
921         xorl %r9d,%r9d
922         
923         # clone now
924         call do_fork
925         movq %rax,RAX(%rsp)
926         xorl %edi,%edi
927
928         /*
929          * It isn't worth to check for reschedule here,
930          * so internally to the x86_64 port you can rely on kernel_thread()
931          * not to reschedule the child before returning, this avoids the need
932          * of hacks for example to fork off the per-CPU idle tasks.
933          * [Hopefully no generic code relies on the reschedule -AK]     
934          */
935         RESTORE_ALL
936         UNFAKE_STACK_FRAME
937         ret
938         CFI_ENDPROC
939
940         
941 child_rip:
942         /*
943          * Here we are in the child and the registers are set as they were
944          * at kernel_thread() invocation in the parent.
945          */
946         movq %rdi, %rax
947         movq %rsi, %rdi
948         call *%rax
949         # exit
950         xorl %edi, %edi
951         call do_exit
952
953 /*
954  * execve(). This function needs to use IRET, not SYSRET, to set up all state properly.
955  *
956  * C extern interface:
957  *       extern long execve(char *name, char **argv, char **envp)
958  *
959  * asm input arguments:
960  *      rdi: name, rsi: argv, rdx: envp
961  *
962  * We want to fallback into:
963  *      extern long sys_execve(char *name, char **argv,char **envp, struct pt_regs regs)
964  *
965  * do_sys_execve asm fallback arguments:
966  *      rdi: name, rsi: argv, rdx: envp, fake frame on the stack
967  */
968 ENTRY(execve)
969         CFI_STARTPROC
970         FAKE_STACK_FRAME $0
971         SAVE_ALL        
972         call sys_execve
973         movq %rax, RAX(%rsp)    
974         RESTORE_REST
975         testq %rax,%rax
976         jne 1f
977         jmp int_ret_from_sys_call
978 1:      RESTORE_ARGS
979         UNFAKE_STACK_FRAME
980         ret
981         CFI_ENDPROC
982
983 KPROBE_ENTRY(page_fault)
984         errorentry do_page_fault
985         .previous .text
986
987 ENTRY(coprocessor_error)
988         zeroentry do_coprocessor_error
989
990 ENTRY(simd_coprocessor_error)
991         zeroentry do_simd_coprocessor_error     
992
993 ENTRY(device_not_available)
994         zeroentry math_state_restore
995
996         /* runs on exception stack */
997 KPROBE_ENTRY(debug)
998         INTR_FRAME
999 /*      pushq $0
1000         CFI_ADJUST_CFA_OFFSET 8 */
1001         zeroentry do_debug
1002 /*      jmp paranoid_exit */
1003         CFI_ENDPROC
1004         .previous .text
1005
1006 #if 0
1007         /* runs on exception stack */   
1008 KPROBE_ENTRY(nmi)
1009         INTR_FRAME
1010         pushq $-1
1011         CFI_ADJUST_CFA_OFFSET 8
1012         paranoidentry do_nmi
1013         /*
1014          * "Paranoid" exit path from exception stack.
1015          * Paranoid because this is used by NMIs and cannot take
1016          * any kernel state for granted.
1017          * We don't do kernel preemption checks here, because only
1018          * NMI should be common and it does not enable IRQs and
1019          * cannot get reschedule ticks.
1020          */
1021         /* ebx: no swapgs flag */
1022 paranoid_exit:
1023         testl %ebx,%ebx                         /* swapgs needed? */
1024         jnz paranoid_restore
1025         testl $3,CS(%rsp)
1026         jnz   paranoid_userspace
1027 paranoid_swapgs:        
1028         swapgs
1029 paranoid_restore:       
1030         RESTORE_ALL 8
1031         iretq
1032 paranoid_userspace:     
1033         GET_THREAD_INFO(%rcx)
1034         movl threadinfo_flags(%rcx),%ebx
1035         andl $_TIF_WORK_MASK,%ebx
1036         jz paranoid_swapgs
1037         movq %rsp,%rdi                  /* &pt_regs */
1038         call sync_regs
1039         movq %rax,%rsp                  /* switch stack for scheduling */
1040         testl $_TIF_NEED_RESCHED,%ebx
1041         jnz paranoid_schedule
1042         movl %ebx,%edx                  /* arg3: thread flags */
1043         sti
1044         xorl %esi,%esi                  /* arg2: oldset */
1045         movq %rsp,%rdi                  /* arg1: &pt_regs */
1046         call do_notify_resume
1047         cli
1048         jmp paranoid_userspace
1049 paranoid_schedule:
1050         sti
1051         call schedule
1052         cli
1053         jmp paranoid_userspace
1054         CFI_ENDPROC
1055         .previous .text
1056 #endif        
1057
1058 KPROBE_ENTRY(int3)
1059         INTR_FRAME
1060 /*      pushq $0
1061         CFI_ADJUST_CFA_OFFSET 8 */
1062         zeroentry do_int3
1063 /*      jmp paranoid_exit */
1064         CFI_ENDPROC
1065         .previous .text
1066
1067 ENTRY(overflow)
1068         zeroentry do_overflow
1069
1070 ENTRY(bounds)
1071         zeroentry do_bounds
1072
1073 ENTRY(invalid_op)
1074         zeroentry do_invalid_op 
1075
1076 ENTRY(coprocessor_segment_overrun)
1077         zeroentry do_coprocessor_segment_overrun
1078
1079 ENTRY(reserved)
1080         zeroentry do_reserved
1081
1082 #if 0
1083         /* runs on exception stack */
1084 ENTRY(double_fault)
1085         XCPT_FRAME
1086         paranoidentry do_double_fault
1087         jmp paranoid_exit
1088         CFI_ENDPROC
1089 #endif
1090
1091 ENTRY(invalid_TSS)
1092         errorentry do_invalid_TSS
1093
1094 ENTRY(segment_not_present)
1095         errorentry do_segment_not_present
1096
1097         /* runs on exception stack */
1098 ENTRY(stack_segment)
1099         XCPT_FRAME
1100         errorentry do_stack_segment
1101         CFI_ENDPROC
1102
1103 KPROBE_ENTRY(general_protection)
1104         errorentry do_general_protection
1105         .previous .text
1106
1107 ENTRY(alignment_check)
1108         errorentry do_alignment_check
1109
1110 ENTRY(divide_error)
1111         zeroentry do_divide_error
1112
1113 ENTRY(spurious_interrupt_bug)
1114         zeroentry do_spurious_interrupt_bug
1115
1116 #ifdef CONFIG_X86_MCE
1117         /* runs on exception stack */
1118 ENTRY(machine_check)
1119         INTR_FRAME
1120         pushq $0
1121         CFI_ADJUST_CFA_OFFSET 8 
1122         paranoidentry do_machine_check
1123         jmp paranoid_exit
1124         CFI_ENDPROC
1125 #endif
1126
1127 ENTRY(call_softirq)
1128         CFI_STARTPROC
1129         movq %gs:pda_irqstackptr,%rax
1130         movq %rsp,%rdx
1131         CFI_DEF_CFA_REGISTER    rdx
1132         incl %gs:pda_irqcount
1133         cmove %rax,%rsp
1134         pushq %rdx
1135         /*todo CFI_DEF_CFA_EXPRESSION ...*/
1136         call __do_softirq
1137         popq %rsp
1138         CFI_DEF_CFA_REGISTER    rsp
1139         decl %gs:pda_irqcount
1140         ret
1141         CFI_ENDPROC