diff options
Diffstat (limited to 'arch/x86_64/kernel/entry.S')
-rw-r--r-- | arch/x86_64/kernel/entry.S | 63 |
1 files changed, 39 insertions, 24 deletions
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S index aa8d8939abc1..2802524104f3 100644 --- a/arch/x86_64/kernel/entry.S +++ b/arch/x86_64/kernel/entry.S | |||
@@ -4,8 +4,6 @@ | |||
4 | * Copyright (C) 1991, 1992 Linus Torvalds | 4 | * Copyright (C) 1991, 1992 Linus Torvalds |
5 | * Copyright (C) 2000, 2001, 2002 Andi Kleen SuSE Labs | 5 | * Copyright (C) 2000, 2001, 2002 Andi Kleen SuSE Labs |
6 | * Copyright (C) 2000 Pavel Machek <pavel@suse.cz> | 6 | * Copyright (C) 2000 Pavel Machek <pavel@suse.cz> |
7 | * | ||
8 | * $Id$ | ||
9 | */ | 7 | */ |
10 | 8 | ||
11 | /* | 9 | /* |
@@ -22,15 +20,25 @@ | |||
22 | * at the top of the kernel process stack. | 20 | * at the top of the kernel process stack. |
23 | * - partial stack frame: partially saved registers upto R11. | 21 | * - partial stack frame: partially saved registers upto R11. |
24 | * - full stack frame: Like partial stack frame, but all register saved. | 22 | * - full stack frame: Like partial stack frame, but all register saved. |
25 | * | 23 | * |
26 | * TODO: | 24 | * Some macro usage: |
27 | * - schedule it carefully for the final hardware. | 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. | ||
28 | */ | 38 | */ |
29 | 39 | ||
30 | #define ASSEMBLY 1 | ||
31 | #include <linux/linkage.h> | 40 | #include <linux/linkage.h> |
32 | #include <asm/segment.h> | 41 | #include <asm/segment.h> |
33 | #include <asm/smp.h> | ||
34 | #include <asm/cache.h> | 42 | #include <asm/cache.h> |
35 | #include <asm/errno.h> | 43 | #include <asm/errno.h> |
36 | #include <asm/dwarf2.h> | 44 | #include <asm/dwarf2.h> |
@@ -115,6 +123,7 @@ | |||
115 | .macro CFI_DEFAULT_STACK start=1 | 123 | .macro CFI_DEFAULT_STACK start=1 |
116 | .if \start | 124 | .if \start |
117 | CFI_STARTPROC simple | 125 | CFI_STARTPROC simple |
126 | CFI_SIGNAL_FRAME | ||
118 | CFI_DEF_CFA rsp,SS+8 | 127 | CFI_DEF_CFA rsp,SS+8 |
119 | .else | 128 | .else |
120 | CFI_DEF_CFA_OFFSET SS+8 | 129 | CFI_DEF_CFA_OFFSET SS+8 |
@@ -146,6 +155,10 @@ | |||
146 | /* rdi: prev */ | 155 | /* rdi: prev */ |
147 | ENTRY(ret_from_fork) | 156 | ENTRY(ret_from_fork) |
148 | CFI_DEFAULT_STACK | 157 | CFI_DEFAULT_STACK |
158 | push kernel_eflags(%rip) | ||
159 | CFI_ADJUST_CFA_OFFSET 4 | ||
160 | popf # reset kernel eflags | ||
161 | CFI_ADJUST_CFA_OFFSET -4 | ||
149 | call schedule_tail | 162 | call schedule_tail |
150 | GET_THREAD_INFO(%rcx) | 163 | GET_THREAD_INFO(%rcx) |
151 | testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),threadinfo_flags(%rcx) | 164 | testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),threadinfo_flags(%rcx) |
@@ -199,6 +212,7 @@ END(ret_from_fork) | |||
199 | 212 | ||
200 | ENTRY(system_call) | 213 | ENTRY(system_call) |
201 | CFI_STARTPROC simple | 214 | CFI_STARTPROC simple |
215 | CFI_SIGNAL_FRAME | ||
202 | CFI_DEF_CFA rsp,PDA_STACKOFFSET | 216 | CFI_DEF_CFA rsp,PDA_STACKOFFSET |
203 | CFI_REGISTER rip,rcx | 217 | CFI_REGISTER rip,rcx |
204 | /*CFI_REGISTER rflags,r11*/ | 218 | /*CFI_REGISTER rflags,r11*/ |
@@ -316,6 +330,7 @@ END(system_call) | |||
316 | */ | 330 | */ |
317 | ENTRY(int_ret_from_sys_call) | 331 | ENTRY(int_ret_from_sys_call) |
318 | CFI_STARTPROC simple | 332 | CFI_STARTPROC simple |
333 | CFI_SIGNAL_FRAME | ||
319 | CFI_DEF_CFA rsp,SS+8-ARGOFFSET | 334 | CFI_DEF_CFA rsp,SS+8-ARGOFFSET |
320 | /*CFI_REL_OFFSET ss,SS-ARGOFFSET*/ | 335 | /*CFI_REL_OFFSET ss,SS-ARGOFFSET*/ |
321 | CFI_REL_OFFSET rsp,RSP-ARGOFFSET | 336 | CFI_REL_OFFSET rsp,RSP-ARGOFFSET |
@@ -476,6 +491,7 @@ END(stub_rt_sigreturn) | |||
476 | */ | 491 | */ |
477 | .macro _frame ref | 492 | .macro _frame ref |
478 | CFI_STARTPROC simple | 493 | CFI_STARTPROC simple |
494 | CFI_SIGNAL_FRAME | ||
479 | CFI_DEF_CFA rsp,SS+8-\ref | 495 | CFI_DEF_CFA rsp,SS+8-\ref |
480 | /*CFI_REL_OFFSET ss,SS-\ref*/ | 496 | /*CFI_REL_OFFSET ss,SS-\ref*/ |
481 | CFI_REL_OFFSET rsp,RSP-\ref | 497 | CFI_REL_OFFSET rsp,RSP-\ref |
@@ -511,7 +527,12 @@ END(stub_rt_sigreturn) | |||
511 | testl $3,CS(%rdi) | 527 | testl $3,CS(%rdi) |
512 | je 1f | 528 | je 1f |
513 | swapgs | 529 | swapgs |
514 | 1: incl %gs:pda_irqcount # RED-PEN should check preempt count | 530 | /* irqcount is used to check if a CPU is already on an interrupt |
531 | stack or not. While this is essentially redundant with preempt_count | ||
532 | it is a little cheaper to use a separate counter in the PDA | ||
533 | (short of moving irq_enter into assembly, which would be too | ||
534 | much work) */ | ||
535 | 1: incl %gs:pda_irqcount | ||
515 | cmoveq %gs:pda_irqstackptr,%rsp | 536 | cmoveq %gs:pda_irqstackptr,%rsp |
516 | push %rbp # backlink for old unwinder | 537 | push %rbp # backlink for old unwinder |
517 | /* | 538 | /* |
@@ -619,8 +640,7 @@ retint_signal: | |||
619 | #ifdef CONFIG_PREEMPT | 640 | #ifdef CONFIG_PREEMPT |
620 | /* Returning to kernel space. Check if we need preemption */ | 641 | /* Returning to kernel space. Check if we need preemption */ |
621 | /* rcx: threadinfo. interrupts off. */ | 642 | /* rcx: threadinfo. interrupts off. */ |
622 | .p2align | 643 | ENTRY(retint_kernel) |
623 | retint_kernel: | ||
624 | cmpl $0,threadinfo_preempt_count(%rcx) | 644 | cmpl $0,threadinfo_preempt_count(%rcx) |
625 | jnz retint_restore_args | 645 | jnz retint_restore_args |
626 | bt $TIF_NEED_RESCHED,threadinfo_flags(%rcx) | 646 | bt $TIF_NEED_RESCHED,threadinfo_flags(%rcx) |
@@ -679,7 +699,6 @@ ENTRY(call_function_interrupt) | |||
679 | END(call_function_interrupt) | 699 | END(call_function_interrupt) |
680 | #endif | 700 | #endif |
681 | 701 | ||
682 | #ifdef CONFIG_X86_LOCAL_APIC | ||
683 | ENTRY(apic_timer_interrupt) | 702 | ENTRY(apic_timer_interrupt) |
684 | apicinterrupt LOCAL_TIMER_VECTOR,smp_apic_timer_interrupt | 703 | apicinterrupt LOCAL_TIMER_VECTOR,smp_apic_timer_interrupt |
685 | END(apic_timer_interrupt) | 704 | END(apic_timer_interrupt) |
@@ -691,7 +710,6 @@ END(error_interrupt) | |||
691 | ENTRY(spurious_interrupt) | 710 | ENTRY(spurious_interrupt) |
692 | apicinterrupt SPURIOUS_APIC_VECTOR,smp_spurious_interrupt | 711 | apicinterrupt SPURIOUS_APIC_VECTOR,smp_spurious_interrupt |
693 | END(spurious_interrupt) | 712 | END(spurious_interrupt) |
694 | #endif | ||
695 | 713 | ||
696 | /* | 714 | /* |
697 | * Exception entry points. | 715 | * Exception entry points. |
@@ -768,7 +786,9 @@ paranoid_exit\trace: | |||
768 | testl $3,CS(%rsp) | 786 | testl $3,CS(%rsp) |
769 | jnz paranoid_userspace\trace | 787 | jnz paranoid_userspace\trace |
770 | paranoid_swapgs\trace: | 788 | paranoid_swapgs\trace: |
789 | .if \trace | ||
771 | TRACE_IRQS_IRETQ 0 | 790 | TRACE_IRQS_IRETQ 0 |
791 | .endif | ||
772 | swapgs | 792 | swapgs |
773 | paranoid_restore\trace: | 793 | paranoid_restore\trace: |
774 | RESTORE_ALL 8 | 794 | RESTORE_ALL 8 |
@@ -814,7 +834,7 @@ paranoid_schedule\trace: | |||
814 | * Exception entry point. This expects an error code/orig_rax on the stack | 834 | * Exception entry point. This expects an error code/orig_rax on the stack |
815 | * and the exception handler in %rax. | 835 | * and the exception handler in %rax. |
816 | */ | 836 | */ |
817 | ENTRY(error_entry) | 837 | KPROBE_ENTRY(error_entry) |
818 | _frame RDI | 838 | _frame RDI |
819 | /* rdi slot contains rax, oldrax contains error code */ | 839 | /* rdi slot contains rax, oldrax contains error code */ |
820 | cld | 840 | cld |
@@ -898,7 +918,7 @@ error_kernelspace: | |||
898 | cmpq $gs_change,RIP(%rsp) | 918 | cmpq $gs_change,RIP(%rsp) |
899 | je error_swapgs | 919 | je error_swapgs |
900 | jmp error_sti | 920 | jmp error_sti |
901 | END(error_entry) | 921 | KPROBE_END(error_entry) |
902 | 922 | ||
903 | /* Reload gs selector with exception handling */ | 923 | /* Reload gs selector with exception handling */ |
904 | /* edi: new selector */ | 924 | /* edi: new selector */ |
@@ -1020,8 +1040,7 @@ ENDPROC(execve) | |||
1020 | 1040 | ||
1021 | KPROBE_ENTRY(page_fault) | 1041 | KPROBE_ENTRY(page_fault) |
1022 | errorentry do_page_fault | 1042 | errorentry do_page_fault |
1023 | END(page_fault) | 1043 | KPROBE_END(page_fault) |
1024 | .previous .text | ||
1025 | 1044 | ||
1026 | ENTRY(coprocessor_error) | 1045 | ENTRY(coprocessor_error) |
1027 | zeroentry do_coprocessor_error | 1046 | zeroentry do_coprocessor_error |
@@ -1042,8 +1061,7 @@ KPROBE_ENTRY(debug) | |||
1042 | CFI_ADJUST_CFA_OFFSET 8 | 1061 | CFI_ADJUST_CFA_OFFSET 8 |
1043 | paranoidentry do_debug, DEBUG_STACK | 1062 | paranoidentry do_debug, DEBUG_STACK |
1044 | paranoidexit | 1063 | paranoidexit |
1045 | END(debug) | 1064 | KPROBE_END(debug) |
1046 | .previous .text | ||
1047 | 1065 | ||
1048 | /* runs on exception stack */ | 1066 | /* runs on exception stack */ |
1049 | KPROBE_ENTRY(nmi) | 1067 | KPROBE_ENTRY(nmi) |
@@ -1057,8 +1075,7 @@ KPROBE_ENTRY(nmi) | |||
1057 | jmp paranoid_exit1 | 1075 | jmp paranoid_exit1 |
1058 | CFI_ENDPROC | 1076 | CFI_ENDPROC |
1059 | #endif | 1077 | #endif |
1060 | END(nmi) | 1078 | KPROBE_END(nmi) |
1061 | .previous .text | ||
1062 | 1079 | ||
1063 | KPROBE_ENTRY(int3) | 1080 | KPROBE_ENTRY(int3) |
1064 | INTR_FRAME | 1081 | INTR_FRAME |
@@ -1067,8 +1084,7 @@ KPROBE_ENTRY(int3) | |||
1067 | paranoidentry do_int3, DEBUG_STACK | 1084 | paranoidentry do_int3, DEBUG_STACK |
1068 | jmp paranoid_exit1 | 1085 | jmp paranoid_exit1 |
1069 | CFI_ENDPROC | 1086 | CFI_ENDPROC |
1070 | END(int3) | 1087 | KPROBE_END(int3) |
1071 | .previous .text | ||
1072 | 1088 | ||
1073 | ENTRY(overflow) | 1089 | ENTRY(overflow) |
1074 | zeroentry do_overflow | 1090 | zeroentry do_overflow |
@@ -1116,8 +1132,7 @@ END(stack_segment) | |||
1116 | 1132 | ||
1117 | KPROBE_ENTRY(general_protection) | 1133 | KPROBE_ENTRY(general_protection) |
1118 | errorentry do_general_protection | 1134 | errorentry do_general_protection |
1119 | END(general_protection) | 1135 | KPROBE_END(general_protection) |
1120 | .previous .text | ||
1121 | 1136 | ||
1122 | ENTRY(alignment_check) | 1137 | ENTRY(alignment_check) |
1123 | errorentry do_alignment_check | 1138 | errorentry do_alignment_check |