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