diff options
author | Alexander van Heukelum <heukelum@mailshack.com> | 2008-11-21 10:41:55 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-11-21 13:02:54 -0500 |
commit | c002a1e6b6b6f07ae04e68987054bf1f2150ae48 (patch) | |
tree | b8d0e2dbbba95876f26243ce4a425481ed9d4094 /arch/x86/kernel/entry_64.S | |
parent | 14ae22ba2b8bb3d53fb795f9b8074aa39ef7b6cd (diff) |
x86: introduce save_rest and restructure the PTREGSCALL macro in entry_64.S
Impact: cleanup
The save_rest function completes a partial stack frame for use
by the PTREGSCALL macro. This also avoids the indirect call in
PTREGSCALLs.
This adds the macro movq_cfi_restore to hide the CFI_RESTORE
annotation when restoring a register from the stack frame.
Signed-off-by: Alexander van Heukelum <heukelum@fastmail.fm>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/entry_64.S')
-rw-r--r-- | arch/x86/kernel/entry_64.S | 91 |
1 files changed, 53 insertions, 38 deletions
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 92c5e18340db..ef95c45b9269 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
@@ -78,6 +78,11 @@ | |||
78 | CFI_REL_OFFSET \reg, \offset | 78 | CFI_REL_OFFSET \reg, \offset |
79 | .endm | 79 | .endm |
80 | 80 | ||
81 | .macro movq_cfi_restore offset reg | ||
82 | movq \offset(%rsp), %\reg | ||
83 | CFI_RESTORE \reg | ||
84 | .endm | ||
85 | |||
81 | #ifdef CONFIG_FUNCTION_TRACER | 86 | #ifdef CONFIG_FUNCTION_TRACER |
82 | #ifdef CONFIG_DYNAMIC_FTRACE | 87 | #ifdef CONFIG_DYNAMIC_FTRACE |
83 | ENTRY(mcount) | 88 | ENTRY(mcount) |
@@ -186,21 +191,21 @@ ENTRY(native_usergs_sysret64) | |||
186 | */ | 191 | */ |
187 | 192 | ||
188 | /* %rsp:at FRAMEEND */ | 193 | /* %rsp:at FRAMEEND */ |
189 | .macro FIXUP_TOP_OF_STACK tmp | 194 | .macro FIXUP_TOP_OF_STACK tmp offset=0 |
190 | movq %gs:pda_oldrsp,\tmp | 195 | movq %gs:pda_oldrsp,\tmp |
191 | movq \tmp,RSP(%rsp) | 196 | movq \tmp,RSP+\offset(%rsp) |
192 | movq $__USER_DS,SS(%rsp) | 197 | movq $__USER_DS,SS+\offset(%rsp) |
193 | movq $__USER_CS,CS(%rsp) | 198 | movq $__USER_CS,CS+\offset(%rsp) |
194 | movq $-1,RCX(%rsp) | 199 | movq $-1,RCX+\offset(%rsp) |
195 | movq R11(%rsp),\tmp /* get eflags */ | 200 | movq R11+\offset(%rsp),\tmp /* get eflags */ |
196 | movq \tmp,EFLAGS(%rsp) | 201 | movq \tmp,EFLAGS+\offset(%rsp) |
197 | .endm | 202 | .endm |
198 | 203 | ||
199 | .macro RESTORE_TOP_OF_STACK tmp,offset=0 | 204 | .macro RESTORE_TOP_OF_STACK tmp offset=0 |
200 | movq RSP-\offset(%rsp),\tmp | 205 | movq RSP+\offset(%rsp),\tmp |
201 | movq \tmp,%gs:pda_oldrsp | 206 | movq \tmp,%gs:pda_oldrsp |
202 | movq EFLAGS-\offset(%rsp),\tmp | 207 | movq EFLAGS+\offset(%rsp),\tmp |
203 | movq \tmp,R11-\offset(%rsp) | 208 | movq \tmp,R11+\offset(%rsp) |
204 | .endm | 209 | .endm |
205 | 210 | ||
206 | .macro FAKE_STACK_FRAME child_rip | 211 | .macro FAKE_STACK_FRAME child_rip |
@@ -333,6 +338,21 @@ ENTRY(save_args) | |||
333 | CFI_ENDPROC | 338 | CFI_ENDPROC |
334 | END(save_args) | 339 | END(save_args) |
335 | 340 | ||
341 | ENTRY(save_rest) | ||
342 | PARTIAL_FRAME 1 REST_SKIP+8 | ||
343 | movq 5*8+16(%rsp), %r11 /* save return address */ | ||
344 | movq_cfi rbx, RBX+16 | ||
345 | movq_cfi rbp, RBP+16 | ||
346 | movq_cfi r12, R12+16 | ||
347 | movq_cfi r13, R13+16 | ||
348 | movq_cfi r14, R14+16 | ||
349 | movq_cfi r15, R15+16 | ||
350 | movq %r11, 8(%rsp) /* return address */ | ||
351 | FIXUP_TOP_OF_STACK %r11, 16 | ||
352 | ret | ||
353 | CFI_ENDPROC | ||
354 | END(save_rest) | ||
355 | |||
336 | /* | 356 | /* |
337 | * A newly forked process directly context switches into this. | 357 | * A newly forked process directly context switches into this. |
338 | */ | 358 | */ |
@@ -353,7 +373,7 @@ rff_action: | |||
353 | je int_ret_from_sys_call | 373 | je int_ret_from_sys_call |
354 | testl $_TIF_IA32,TI_flags(%rcx) | 374 | testl $_TIF_IA32,TI_flags(%rcx) |
355 | jnz int_ret_from_sys_call | 375 | jnz int_ret_from_sys_call |
356 | RESTORE_TOP_OF_STACK %rdi,ARGOFFSET | 376 | RESTORE_TOP_OF_STACK %rdi, -ARGOFFSET |
357 | jmp ret_from_sys_call | 377 | jmp ret_from_sys_call |
358 | rff_trace: | 378 | rff_trace: |
359 | movq %rsp,%rdi | 379 | movq %rsp,%rdi |
@@ -626,18 +646,20 @@ END(system_call) | |||
626 | /* | 646 | /* |
627 | * Certain special system calls that need to save a complete full stack frame. | 647 | * Certain special system calls that need to save a complete full stack frame. |
628 | */ | 648 | */ |
629 | |||
630 | .macro PTREGSCALL label,func,arg | 649 | .macro PTREGSCALL label,func,arg |
631 | .globl \label | 650 | ENTRY(\label) |
632 | \label: | 651 | PARTIAL_FRAME 1 8 /* offset 8: return address */ |
633 | leaq \func(%rip),%rax | 652 | subq $REST_SKIP, %rsp |
634 | leaq -ARGOFFSET+8(%rsp),\arg /* 8 for return address */ | 653 | CFI_ADJUST_CFA_OFFSET REST_SKIP |
635 | jmp ptregscall_common | 654 | call save_rest |
655 | DEFAULT_FRAME 0 8 /* offset 8: return address */ | ||
656 | leaq 8(%rsp), \arg /* pt_regs pointer */ | ||
657 | call \func | ||
658 | jmp ptregscall_common | ||
659 | CFI_ENDPROC | ||
636 | END(\label) | 660 | END(\label) |
637 | .endm | 661 | .endm |
638 | 662 | ||
639 | CFI_STARTPROC | ||
640 | |||
641 | PTREGSCALL stub_clone, sys_clone, %r8 | 663 | PTREGSCALL stub_clone, sys_clone, %r8 |
642 | PTREGSCALL stub_fork, sys_fork, %rdi | 664 | PTREGSCALL stub_fork, sys_fork, %rdi |
643 | PTREGSCALL stub_vfork, sys_vfork, %rdi | 665 | PTREGSCALL stub_vfork, sys_vfork, %rdi |
@@ -645,22 +667,15 @@ END(\label) | |||
645 | PTREGSCALL stub_iopl, sys_iopl, %rsi | 667 | PTREGSCALL stub_iopl, sys_iopl, %rsi |
646 | 668 | ||
647 | ENTRY(ptregscall_common) | 669 | ENTRY(ptregscall_common) |
648 | popq %r11 | 670 | DEFAULT_FRAME 1 8 /* offset 8: return address */ |
649 | CFI_ADJUST_CFA_OFFSET -8 | 671 | RESTORE_TOP_OF_STACK %r11, 8 |
650 | CFI_REGISTER rip, r11 | 672 | movq_cfi_restore R15+8, r15 |
651 | SAVE_REST | 673 | movq_cfi_restore R14+8, r14 |
652 | movq %r11, %r15 | 674 | movq_cfi_restore R13+8, r13 |
653 | CFI_REGISTER rip, r15 | 675 | movq_cfi_restore R12+8, r12 |
654 | FIXUP_TOP_OF_STACK %r11 | 676 | movq_cfi_restore RBP+8, rbp |
655 | call *%rax | 677 | movq_cfi_restore RBX+8, rbx |
656 | RESTORE_TOP_OF_STACK %r11 | 678 | ret $REST_SKIP /* pop extended registers */ |
657 | movq %r15, %r11 | ||
658 | CFI_REGISTER rip, r11 | ||
659 | RESTORE_REST | ||
660 | pushq %r11 | ||
661 | CFI_ADJUST_CFA_OFFSET 8 | ||
662 | CFI_REL_OFFSET rip, 0 | ||
663 | ret | ||
664 | CFI_ENDPROC | 679 | CFI_ENDPROC |
665 | END(ptregscall_common) | 680 | END(ptregscall_common) |
666 | 681 | ||