diff options
Diffstat (limited to 'arch/x86/kernel/entry_64.S')
-rw-r--r-- | arch/x86/kernel/entry_64.S | 45 |
1 files changed, 24 insertions, 21 deletions
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index a1346217e43c..586bed677557 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
@@ -52,6 +52,7 @@ | |||
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> |
@@ -209,7 +210,7 @@ ENTRY(native_usergs_sysret64) | |||
209 | 210 | ||
210 | /* %rsp:at FRAMEEND */ | 211 | /* %rsp:at FRAMEEND */ |
211 | .macro FIXUP_TOP_OF_STACK tmp offset=0 | 212 | .macro FIXUP_TOP_OF_STACK tmp offset=0 |
212 | movq %gs:pda_oldrsp,\tmp | 213 | movq PER_CPU_VAR(old_rsp),\tmp |
213 | movq \tmp,RSP+\offset(%rsp) | 214 | movq \tmp,RSP+\offset(%rsp) |
214 | movq $__USER_DS,SS+\offset(%rsp) | 215 | movq $__USER_DS,SS+\offset(%rsp) |
215 | movq $__USER_CS,CS+\offset(%rsp) | 216 | movq $__USER_CS,CS+\offset(%rsp) |
@@ -220,7 +221,7 @@ ENTRY(native_usergs_sysret64) | |||
220 | 221 | ||
221 | .macro RESTORE_TOP_OF_STACK tmp offset=0 | 222 | .macro RESTORE_TOP_OF_STACK tmp offset=0 |
222 | movq RSP+\offset(%rsp),\tmp | 223 | movq RSP+\offset(%rsp),\tmp |
223 | movq \tmp,%gs:pda_oldrsp | 224 | movq \tmp,PER_CPU_VAR(old_rsp) |
224 | movq EFLAGS+\offset(%rsp),\tmp | 225 | movq EFLAGS+\offset(%rsp),\tmp |
225 | movq \tmp,R11+\offset(%rsp) | 226 | movq \tmp,R11+\offset(%rsp) |
226 | .endm | 227 | .endm |
@@ -336,15 +337,15 @@ ENTRY(save_args) | |||
336 | je 1f | 337 | je 1f |
337 | SWAPGS | 338 | SWAPGS |
338 | /* | 339 | /* |
339 | * irqcount is used to check if a CPU is already on an interrupt stack | 340 | * 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 | 341 | * 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 | 342 | * 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) | 343 | * moving irq_enter into assembly, which would be too much work) |
343 | */ | 344 | */ |
344 | 1: incl %gs:pda_irqcount | 345 | 1: incl PER_CPU_VAR(irq_count) |
345 | jne 2f | 346 | jne 2f |
346 | popq_cfi %rax /* move return address... */ | 347 | popq_cfi %rax /* move return address... */ |
347 | mov %gs:pda_irqstackptr,%rsp | 348 | mov PER_CPU_VAR(irq_stack_ptr),%rsp |
348 | EMPTY_FRAME 0 | 349 | EMPTY_FRAME 0 |
349 | pushq_cfi %rbp /* backlink for unwinder */ | 350 | pushq_cfi %rbp /* backlink for unwinder */ |
350 | pushq_cfi %rax /* ... to the new stack */ | 351 | pushq_cfi %rax /* ... to the new stack */ |
@@ -468,7 +469,7 @@ END(ret_from_fork) | |||
468 | ENTRY(system_call) | 469 | ENTRY(system_call) |
469 | CFI_STARTPROC simple | 470 | CFI_STARTPROC simple |
470 | CFI_SIGNAL_FRAME | 471 | CFI_SIGNAL_FRAME |
471 | CFI_DEF_CFA rsp,PDA_STACKOFFSET | 472 | CFI_DEF_CFA rsp,KERNEL_STACK_OFFSET |
472 | CFI_REGISTER rip,rcx | 473 | CFI_REGISTER rip,rcx |
473 | /*CFI_REGISTER rflags,r11*/ | 474 | /*CFI_REGISTER rflags,r11*/ |
474 | SWAPGS_UNSAFE_STACK | 475 | SWAPGS_UNSAFE_STACK |
@@ -479,8 +480,8 @@ ENTRY(system_call) | |||
479 | */ | 480 | */ |
480 | ENTRY(system_call_after_swapgs) | 481 | ENTRY(system_call_after_swapgs) |
481 | 482 | ||
482 | movq %rsp,%gs:pda_oldrsp | 483 | movq %rsp,PER_CPU_VAR(old_rsp) |
483 | movq %gs:pda_kernelstack,%rsp | 484 | movq PER_CPU_VAR(kernel_stack),%rsp |
484 | /* | 485 | /* |
485 | * No need to follow this irqs off/on section - it's straight | 486 | * No need to follow this irqs off/on section - it's straight |
486 | * and short: | 487 | * and short: |
@@ -523,7 +524,7 @@ sysret_check: | |||
523 | CFI_REGISTER rip,rcx | 524 | CFI_REGISTER rip,rcx |
524 | RESTORE_ARGS 0,-ARG_SKIP,1 | 525 | RESTORE_ARGS 0,-ARG_SKIP,1 |
525 | /*CFI_REGISTER rflags,r11*/ | 526 | /*CFI_REGISTER rflags,r11*/ |
526 | movq %gs:pda_oldrsp, %rsp | 527 | movq PER_CPU_VAR(old_rsp), %rsp |
527 | USERGS_SYSRET64 | 528 | USERGS_SYSRET64 |
528 | 529 | ||
529 | CFI_RESTORE_STATE | 530 | CFI_RESTORE_STATE |
@@ -833,11 +834,11 @@ common_interrupt: | |||
833 | XCPT_FRAME | 834 | XCPT_FRAME |
834 | addq $-0x80,(%rsp) /* Adjust vector to [-256,-1] range */ | 835 | addq $-0x80,(%rsp) /* Adjust vector to [-256,-1] range */ |
835 | interrupt do_IRQ | 836 | interrupt do_IRQ |
836 | /* 0(%rsp): oldrsp-ARGOFFSET */ | 837 | /* 0(%rsp): old_rsp-ARGOFFSET */ |
837 | ret_from_intr: | 838 | ret_from_intr: |
838 | DISABLE_INTERRUPTS(CLBR_NONE) | 839 | DISABLE_INTERRUPTS(CLBR_NONE) |
839 | TRACE_IRQS_OFF | 840 | TRACE_IRQS_OFF |
840 | decl %gs:pda_irqcount | 841 | decl PER_CPU_VAR(irq_count) |
841 | leaveq | 842 | leaveq |
842 | CFI_DEF_CFA_REGISTER rsp | 843 | CFI_DEF_CFA_REGISTER rsp |
843 | CFI_ADJUST_CFA_OFFSET -8 | 844 | CFI_ADJUST_CFA_OFFSET -8 |
@@ -982,8 +983,10 @@ apicinterrupt IRQ_MOVE_CLEANUP_VECTOR \ | |||
982 | irq_move_cleanup_interrupt smp_irq_move_cleanup_interrupt | 983 | irq_move_cleanup_interrupt smp_irq_move_cleanup_interrupt |
983 | #endif | 984 | #endif |
984 | 985 | ||
986 | #ifdef CONFIG_X86_UV | ||
985 | apicinterrupt UV_BAU_MESSAGE \ | 987 | apicinterrupt UV_BAU_MESSAGE \ |
986 | uv_bau_message_intr1 uv_bau_message_interrupt | 988 | uv_bau_message_intr1 uv_bau_message_interrupt |
989 | #endif | ||
987 | apicinterrupt LOCAL_TIMER_VECTOR \ | 990 | apicinterrupt LOCAL_TIMER_VECTOR \ |
988 | apic_timer_interrupt smp_apic_timer_interrupt | 991 | apic_timer_interrupt smp_apic_timer_interrupt |
989 | 992 | ||
@@ -1073,10 +1076,10 @@ ENTRY(\sym) | |||
1073 | TRACE_IRQS_OFF | 1076 | TRACE_IRQS_OFF |
1074 | movq %rsp,%rdi /* pt_regs pointer */ | 1077 | movq %rsp,%rdi /* pt_regs pointer */ |
1075 | xorl %esi,%esi /* no error code */ | 1078 | xorl %esi,%esi /* no error code */ |
1076 | movq %gs:pda_data_offset, %rbp | 1079 | PER_CPU(init_tss, %rbp) |
1077 | subq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp) | 1080 | subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp) |
1078 | call \do_sym | 1081 | call \do_sym |
1079 | addq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp) | 1082 | addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp) |
1080 | jmp paranoid_exit /* %ebx: no swapgs flag */ | 1083 | jmp paranoid_exit /* %ebx: no swapgs flag */ |
1081 | CFI_ENDPROC | 1084 | CFI_ENDPROC |
1082 | END(\sym) | 1085 | END(\sym) |
@@ -1138,7 +1141,7 @@ ENTRY(native_load_gs_index) | |||
1138 | CFI_STARTPROC | 1141 | CFI_STARTPROC |
1139 | pushf | 1142 | pushf |
1140 | CFI_ADJUST_CFA_OFFSET 8 | 1143 | CFI_ADJUST_CFA_OFFSET 8 |
1141 | DISABLE_INTERRUPTS(CLBR_ANY | ~(CLBR_RDI)) | 1144 | DISABLE_INTERRUPTS(CLBR_ANY & ~CLBR_RDI) |
1142 | SWAPGS | 1145 | SWAPGS |
1143 | gs_change: | 1146 | gs_change: |
1144 | movl %edi,%gs | 1147 | movl %edi,%gs |
@@ -1260,14 +1263,14 @@ ENTRY(call_softirq) | |||
1260 | CFI_REL_OFFSET rbp,0 | 1263 | CFI_REL_OFFSET rbp,0 |
1261 | mov %rsp,%rbp | 1264 | mov %rsp,%rbp |
1262 | CFI_DEF_CFA_REGISTER rbp | 1265 | CFI_DEF_CFA_REGISTER rbp |
1263 | incl %gs:pda_irqcount | 1266 | incl PER_CPU_VAR(irq_count) |
1264 | cmove %gs:pda_irqstackptr,%rsp | 1267 | cmove PER_CPU_VAR(irq_stack_ptr),%rsp |
1265 | push %rbp # backlink for old unwinder | 1268 | push %rbp # backlink for old unwinder |
1266 | call __do_softirq | 1269 | call __do_softirq |
1267 | leaveq | 1270 | leaveq |
1268 | CFI_DEF_CFA_REGISTER rsp | 1271 | CFI_DEF_CFA_REGISTER rsp |
1269 | CFI_ADJUST_CFA_OFFSET -8 | 1272 | CFI_ADJUST_CFA_OFFSET -8 |
1270 | decl %gs:pda_irqcount | 1273 | decl PER_CPU_VAR(irq_count) |
1271 | ret | 1274 | ret |
1272 | CFI_ENDPROC | 1275 | CFI_ENDPROC |
1273 | END(call_softirq) | 1276 | END(call_softirq) |
@@ -1297,15 +1300,15 @@ ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs) | |||
1297 | movq %rdi, %rsp # we don't return, adjust the stack frame | 1300 | movq %rdi, %rsp # we don't return, adjust the stack frame |
1298 | CFI_ENDPROC | 1301 | CFI_ENDPROC |
1299 | DEFAULT_FRAME | 1302 | DEFAULT_FRAME |
1300 | 11: incl %gs:pda_irqcount | 1303 | 11: incl PER_CPU_VAR(irq_count) |
1301 | movq %rsp,%rbp | 1304 | movq %rsp,%rbp |
1302 | CFI_DEF_CFA_REGISTER rbp | 1305 | CFI_DEF_CFA_REGISTER rbp |
1303 | cmovzq %gs:pda_irqstackptr,%rsp | 1306 | cmovzq PER_CPU_VAR(irq_stack_ptr),%rsp |
1304 | pushq %rbp # backlink for old unwinder | 1307 | pushq %rbp # backlink for old unwinder |
1305 | call xen_evtchn_do_upcall | 1308 | call xen_evtchn_do_upcall |
1306 | popq %rsp | 1309 | popq %rsp |
1307 | CFI_DEF_CFA_REGISTER rsp | 1310 | CFI_DEF_CFA_REGISTER rsp |
1308 | decl %gs:pda_irqcount | 1311 | decl PER_CPU_VAR(irq_count) |
1309 | jmp error_exit | 1312 | jmp error_exit |
1310 | CFI_ENDPROC | 1313 | CFI_ENDPROC |
1311 | END(do_hypervisor_callback) | 1314 | END(do_hypervisor_callback) |