diff options
Diffstat (limited to 'arch/x86/kernel/entry_64.S')
-rw-r--r-- | arch/x86/kernel/entry_64.S | 72 |
1 files changed, 35 insertions, 37 deletions
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index a1346217e43c..83d1836b9467 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
@@ -48,10 +48,11 @@ | |||
48 | #include <asm/unistd.h> | 48 | #include <asm/unistd.h> |
49 | #include <asm/thread_info.h> | 49 | #include <asm/thread_info.h> |
50 | #include <asm/hw_irq.h> | 50 | #include <asm/hw_irq.h> |
51 | #include <asm/page.h> | 51 | #include <asm/page_types.h> |
52 | #include <asm/irqflags.h> | 52 | #include <asm/irqflags.h> |
53 | #include <asm/paravirt.h> | 53 | #include <asm/paravirt.h> |
54 | #include <asm/ftrace.h> | 54 | #include <asm/ftrace.h> |
55 | #include <asm/percpu.h> | ||
55 | 56 | ||
56 | /* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */ | 57 | /* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */ |
57 | #include <linux/elf-em.h> | 58 | #include <linux/elf-em.h> |
@@ -76,20 +77,17 @@ ENTRY(ftrace_caller) | |||
76 | movq 8(%rbp), %rsi | 77 | movq 8(%rbp), %rsi |
77 | subq $MCOUNT_INSN_SIZE, %rdi | 78 | subq $MCOUNT_INSN_SIZE, %rdi |
78 | 79 | ||
79 | .globl ftrace_call | 80 | GLOBAL(ftrace_call) |
80 | ftrace_call: | ||
81 | call ftrace_stub | 81 | call ftrace_stub |
82 | 82 | ||
83 | MCOUNT_RESTORE_FRAME | 83 | MCOUNT_RESTORE_FRAME |
84 | 84 | ||
85 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 85 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
86 | .globl ftrace_graph_call | 86 | GLOBAL(ftrace_graph_call) |
87 | ftrace_graph_call: | ||
88 | jmp ftrace_stub | 87 | jmp ftrace_stub |
89 | #endif | 88 | #endif |
90 | 89 | ||
91 | .globl ftrace_stub | 90 | GLOBAL(ftrace_stub) |
92 | ftrace_stub: | ||
93 | retq | 91 | retq |
94 | END(ftrace_caller) | 92 | END(ftrace_caller) |
95 | 93 | ||
@@ -109,8 +107,7 @@ ENTRY(mcount) | |||
109 | jnz ftrace_graph_caller | 107 | jnz ftrace_graph_caller |
110 | #endif | 108 | #endif |
111 | 109 | ||
112 | .globl ftrace_stub | 110 | GLOBAL(ftrace_stub) |
113 | ftrace_stub: | ||
114 | retq | 111 | retq |
115 | 112 | ||
116 | trace: | 113 | trace: |
@@ -147,9 +144,7 @@ ENTRY(ftrace_graph_caller) | |||
147 | retq | 144 | retq |
148 | END(ftrace_graph_caller) | 145 | END(ftrace_graph_caller) |
149 | 146 | ||
150 | 147 | GLOBAL(return_to_handler) | |
151 | .globl return_to_handler | ||
152 | return_to_handler: | ||
153 | subq $80, %rsp | 148 | subq $80, %rsp |
154 | 149 | ||
155 | movq %rax, (%rsp) | 150 | movq %rax, (%rsp) |
@@ -187,6 +182,7 @@ return_to_handler: | |||
187 | ENTRY(native_usergs_sysret64) | 182 | ENTRY(native_usergs_sysret64) |
188 | swapgs | 183 | swapgs |
189 | sysretq | 184 | sysretq |
185 | ENDPROC(native_usergs_sysret64) | ||
190 | #endif /* CONFIG_PARAVIRT */ | 186 | #endif /* CONFIG_PARAVIRT */ |
191 | 187 | ||
192 | 188 | ||
@@ -209,7 +205,7 @@ ENTRY(native_usergs_sysret64) | |||
209 | 205 | ||
210 | /* %rsp:at FRAMEEND */ | 206 | /* %rsp:at FRAMEEND */ |
211 | .macro FIXUP_TOP_OF_STACK tmp offset=0 | 207 | .macro FIXUP_TOP_OF_STACK tmp offset=0 |
212 | movq %gs:pda_oldrsp,\tmp | 208 | movq PER_CPU_VAR(old_rsp),\tmp |
213 | movq \tmp,RSP+\offset(%rsp) | 209 | movq \tmp,RSP+\offset(%rsp) |
214 | movq $__USER_DS,SS+\offset(%rsp) | 210 | movq $__USER_DS,SS+\offset(%rsp) |
215 | movq $__USER_CS,CS+\offset(%rsp) | 211 | movq $__USER_CS,CS+\offset(%rsp) |
@@ -220,7 +216,7 @@ ENTRY(native_usergs_sysret64) | |||
220 | 216 | ||
221 | .macro RESTORE_TOP_OF_STACK tmp offset=0 | 217 | .macro RESTORE_TOP_OF_STACK tmp offset=0 |
222 | movq RSP+\offset(%rsp),\tmp | 218 | movq RSP+\offset(%rsp),\tmp |
223 | movq \tmp,%gs:pda_oldrsp | 219 | movq \tmp,PER_CPU_VAR(old_rsp) |
224 | movq EFLAGS+\offset(%rsp),\tmp | 220 | movq EFLAGS+\offset(%rsp),\tmp |
225 | movq \tmp,R11+\offset(%rsp) | 221 | movq \tmp,R11+\offset(%rsp) |
226 | .endm | 222 | .endm |
@@ -336,15 +332,15 @@ ENTRY(save_args) | |||
336 | je 1f | 332 | je 1f |
337 | SWAPGS | 333 | SWAPGS |
338 | /* | 334 | /* |
339 | * irqcount is used to check if a CPU is already on an interrupt stack | 335 | * irq_count is used to check if a CPU is already on an interrupt stack |
340 | * or not. While this is essentially redundant with preempt_count it is | 336 | * or not. While this is essentially redundant with preempt_count it is |
341 | * a little cheaper to use a separate counter in the PDA (short of | 337 | * a little cheaper to use a separate counter in the PDA (short of |
342 | * moving irq_enter into assembly, which would be too much work) | 338 | * moving irq_enter into assembly, which would be too much work) |
343 | */ | 339 | */ |
344 | 1: incl %gs:pda_irqcount | 340 | 1: incl PER_CPU_VAR(irq_count) |
345 | jne 2f | 341 | jne 2f |
346 | popq_cfi %rax /* move return address... */ | 342 | popq_cfi %rax /* move return address... */ |
347 | mov %gs:pda_irqstackptr,%rsp | 343 | mov PER_CPU_VAR(irq_stack_ptr),%rsp |
348 | EMPTY_FRAME 0 | 344 | EMPTY_FRAME 0 |
349 | pushq_cfi %rbp /* backlink for unwinder */ | 345 | pushq_cfi %rbp /* backlink for unwinder */ |
350 | pushq_cfi %rax /* ... to the new stack */ | 346 | pushq_cfi %rax /* ... to the new stack */ |
@@ -409,6 +405,8 @@ END(save_paranoid) | |||
409 | ENTRY(ret_from_fork) | 405 | ENTRY(ret_from_fork) |
410 | DEFAULT_FRAME | 406 | DEFAULT_FRAME |
411 | 407 | ||
408 | LOCK ; btr $TIF_FORK,TI_flags(%r8) | ||
409 | |||
412 | push kernel_eflags(%rip) | 410 | push kernel_eflags(%rip) |
413 | CFI_ADJUST_CFA_OFFSET 8 | 411 | CFI_ADJUST_CFA_OFFSET 8 |
414 | popf # reset kernel eflags | 412 | popf # reset kernel eflags |
@@ -468,7 +466,7 @@ END(ret_from_fork) | |||
468 | ENTRY(system_call) | 466 | ENTRY(system_call) |
469 | CFI_STARTPROC simple | 467 | CFI_STARTPROC simple |
470 | CFI_SIGNAL_FRAME | 468 | CFI_SIGNAL_FRAME |
471 | CFI_DEF_CFA rsp,PDA_STACKOFFSET | 469 | CFI_DEF_CFA rsp,KERNEL_STACK_OFFSET |
472 | CFI_REGISTER rip,rcx | 470 | CFI_REGISTER rip,rcx |
473 | /*CFI_REGISTER rflags,r11*/ | 471 | /*CFI_REGISTER rflags,r11*/ |
474 | SWAPGS_UNSAFE_STACK | 472 | SWAPGS_UNSAFE_STACK |
@@ -479,8 +477,8 @@ ENTRY(system_call) | |||
479 | */ | 477 | */ |
480 | ENTRY(system_call_after_swapgs) | 478 | ENTRY(system_call_after_swapgs) |
481 | 479 | ||
482 | movq %rsp,%gs:pda_oldrsp | 480 | movq %rsp,PER_CPU_VAR(old_rsp) |
483 | movq %gs:pda_kernelstack,%rsp | 481 | movq PER_CPU_VAR(kernel_stack),%rsp |
484 | /* | 482 | /* |
485 | * No need to follow this irqs off/on section - it's straight | 483 | * No need to follow this irqs off/on section - it's straight |
486 | * and short: | 484 | * and short: |
@@ -523,7 +521,7 @@ sysret_check: | |||
523 | CFI_REGISTER rip,rcx | 521 | CFI_REGISTER rip,rcx |
524 | RESTORE_ARGS 0,-ARG_SKIP,1 | 522 | RESTORE_ARGS 0,-ARG_SKIP,1 |
525 | /*CFI_REGISTER rflags,r11*/ | 523 | /*CFI_REGISTER rflags,r11*/ |
526 | movq %gs:pda_oldrsp, %rsp | 524 | movq PER_CPU_VAR(old_rsp), %rsp |
527 | USERGS_SYSRET64 | 525 | USERGS_SYSRET64 |
528 | 526 | ||
529 | CFI_RESTORE_STATE | 527 | CFI_RESTORE_STATE |
@@ -630,16 +628,14 @@ tracesys: | |||
630 | * Syscall return path ending with IRET. | 628 | * Syscall return path ending with IRET. |
631 | * Has correct top of stack, but partial stack frame. | 629 | * Has correct top of stack, but partial stack frame. |
632 | */ | 630 | */ |
633 | .globl int_ret_from_sys_call | 631 | GLOBAL(int_ret_from_sys_call) |
634 | .globl int_with_check | ||
635 | int_ret_from_sys_call: | ||
636 | DISABLE_INTERRUPTS(CLBR_NONE) | 632 | DISABLE_INTERRUPTS(CLBR_NONE) |
637 | TRACE_IRQS_OFF | 633 | TRACE_IRQS_OFF |
638 | testl $3,CS-ARGOFFSET(%rsp) | 634 | testl $3,CS-ARGOFFSET(%rsp) |
639 | je retint_restore_args | 635 | je retint_restore_args |
640 | movl $_TIF_ALLWORK_MASK,%edi | 636 | movl $_TIF_ALLWORK_MASK,%edi |
641 | /* edi: mask to check */ | 637 | /* edi: mask to check */ |
642 | int_with_check: | 638 | GLOBAL(int_with_check) |
643 | LOCKDEP_SYS_EXIT_IRQ | 639 | LOCKDEP_SYS_EXIT_IRQ |
644 | GET_THREAD_INFO(%rcx) | 640 | GET_THREAD_INFO(%rcx) |
645 | movl TI_flags(%rcx),%edx | 641 | movl TI_flags(%rcx),%edx |
@@ -833,11 +829,11 @@ common_interrupt: | |||
833 | XCPT_FRAME | 829 | XCPT_FRAME |
834 | addq $-0x80,(%rsp) /* Adjust vector to [-256,-1] range */ | 830 | addq $-0x80,(%rsp) /* Adjust vector to [-256,-1] range */ |
835 | interrupt do_IRQ | 831 | interrupt do_IRQ |
836 | /* 0(%rsp): oldrsp-ARGOFFSET */ | 832 | /* 0(%rsp): old_rsp-ARGOFFSET */ |
837 | ret_from_intr: | 833 | ret_from_intr: |
838 | DISABLE_INTERRUPTS(CLBR_NONE) | 834 | DISABLE_INTERRUPTS(CLBR_NONE) |
839 | TRACE_IRQS_OFF | 835 | TRACE_IRQS_OFF |
840 | decl %gs:pda_irqcount | 836 | decl PER_CPU_VAR(irq_count) |
841 | leaveq | 837 | leaveq |
842 | CFI_DEF_CFA_REGISTER rsp | 838 | CFI_DEF_CFA_REGISTER rsp |
843 | CFI_ADJUST_CFA_OFFSET -8 | 839 | CFI_ADJUST_CFA_OFFSET -8 |
@@ -982,8 +978,10 @@ apicinterrupt IRQ_MOVE_CLEANUP_VECTOR \ | |||
982 | irq_move_cleanup_interrupt smp_irq_move_cleanup_interrupt | 978 | irq_move_cleanup_interrupt smp_irq_move_cleanup_interrupt |
983 | #endif | 979 | #endif |
984 | 980 | ||
981 | #ifdef CONFIG_X86_UV | ||
985 | apicinterrupt UV_BAU_MESSAGE \ | 982 | apicinterrupt UV_BAU_MESSAGE \ |
986 | uv_bau_message_intr1 uv_bau_message_interrupt | 983 | uv_bau_message_intr1 uv_bau_message_interrupt |
984 | #endif | ||
987 | apicinterrupt LOCAL_TIMER_VECTOR \ | 985 | apicinterrupt LOCAL_TIMER_VECTOR \ |
988 | apic_timer_interrupt smp_apic_timer_interrupt | 986 | apic_timer_interrupt smp_apic_timer_interrupt |
989 | 987 | ||
@@ -1073,10 +1071,10 @@ ENTRY(\sym) | |||
1073 | TRACE_IRQS_OFF | 1071 | TRACE_IRQS_OFF |
1074 | movq %rsp,%rdi /* pt_regs pointer */ | 1072 | movq %rsp,%rdi /* pt_regs pointer */ |
1075 | xorl %esi,%esi /* no error code */ | 1073 | xorl %esi,%esi /* no error code */ |
1076 | movq %gs:pda_data_offset, %rbp | 1074 | PER_CPU(init_tss, %rbp) |
1077 | subq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp) | 1075 | subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp) |
1078 | call \do_sym | 1076 | call \do_sym |
1079 | addq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp) | 1077 | addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp) |
1080 | jmp paranoid_exit /* %ebx: no swapgs flag */ | 1078 | jmp paranoid_exit /* %ebx: no swapgs flag */ |
1081 | CFI_ENDPROC | 1079 | CFI_ENDPROC |
1082 | END(\sym) | 1080 | END(\sym) |
@@ -1138,7 +1136,7 @@ ENTRY(native_load_gs_index) | |||
1138 | CFI_STARTPROC | 1136 | CFI_STARTPROC |
1139 | pushf | 1137 | pushf |
1140 | CFI_ADJUST_CFA_OFFSET 8 | 1138 | CFI_ADJUST_CFA_OFFSET 8 |
1141 | DISABLE_INTERRUPTS(CLBR_ANY | ~(CLBR_RDI)) | 1139 | DISABLE_INTERRUPTS(CLBR_ANY & ~CLBR_RDI) |
1142 | SWAPGS | 1140 | SWAPGS |
1143 | gs_change: | 1141 | gs_change: |
1144 | movl %edi,%gs | 1142 | movl %edi,%gs |
@@ -1260,14 +1258,14 @@ ENTRY(call_softirq) | |||
1260 | CFI_REL_OFFSET rbp,0 | 1258 | CFI_REL_OFFSET rbp,0 |
1261 | mov %rsp,%rbp | 1259 | mov %rsp,%rbp |
1262 | CFI_DEF_CFA_REGISTER rbp | 1260 | CFI_DEF_CFA_REGISTER rbp |
1263 | incl %gs:pda_irqcount | 1261 | incl PER_CPU_VAR(irq_count) |
1264 | cmove %gs:pda_irqstackptr,%rsp | 1262 | cmove PER_CPU_VAR(irq_stack_ptr),%rsp |
1265 | push %rbp # backlink for old unwinder | 1263 | push %rbp # backlink for old unwinder |
1266 | call __do_softirq | 1264 | call __do_softirq |
1267 | leaveq | 1265 | leaveq |
1268 | CFI_DEF_CFA_REGISTER rsp | 1266 | CFI_DEF_CFA_REGISTER rsp |
1269 | CFI_ADJUST_CFA_OFFSET -8 | 1267 | CFI_ADJUST_CFA_OFFSET -8 |
1270 | decl %gs:pda_irqcount | 1268 | decl PER_CPU_VAR(irq_count) |
1271 | ret | 1269 | ret |
1272 | CFI_ENDPROC | 1270 | CFI_ENDPROC |
1273 | END(call_softirq) | 1271 | END(call_softirq) |
@@ -1297,15 +1295,15 @@ ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs) | |||
1297 | movq %rdi, %rsp # we don't return, adjust the stack frame | 1295 | movq %rdi, %rsp # we don't return, adjust the stack frame |
1298 | CFI_ENDPROC | 1296 | CFI_ENDPROC |
1299 | DEFAULT_FRAME | 1297 | DEFAULT_FRAME |
1300 | 11: incl %gs:pda_irqcount | 1298 | 11: incl PER_CPU_VAR(irq_count) |
1301 | movq %rsp,%rbp | 1299 | movq %rsp,%rbp |
1302 | CFI_DEF_CFA_REGISTER rbp | 1300 | CFI_DEF_CFA_REGISTER rbp |
1303 | cmovzq %gs:pda_irqstackptr,%rsp | 1301 | cmovzq PER_CPU_VAR(irq_stack_ptr),%rsp |
1304 | pushq %rbp # backlink for old unwinder | 1302 | pushq %rbp # backlink for old unwinder |
1305 | call xen_evtchn_do_upcall | 1303 | call xen_evtchn_do_upcall |
1306 | popq %rsp | 1304 | popq %rsp |
1307 | CFI_DEF_CFA_REGISTER rsp | 1305 | CFI_DEF_CFA_REGISTER rsp |
1308 | decl %gs:pda_irqcount | 1306 | decl PER_CPU_VAR(irq_count) |
1309 | jmp error_exit | 1307 | jmp error_exit |
1310 | CFI_ENDPROC | 1308 | CFI_ENDPROC |
1311 | END(do_hypervisor_callback) | 1309 | END(do_hypervisor_callback) |