diff options
author | Denys Vlasenko <[email protected]> | 2015-06-03 14:56:09 +0200 |
---|---|---|
committer | Ingo Molnar <[email protected]> | 2015-06-05 13:22:22 +0200 |
commit | 53e9accf0f7682d717c7b578b6e01fd297ba6630 (patch) | |
tree | 30e8111df4f19caf9ca798e18d121c87044da0ce | |
parent | 73cbf687914fd5f4ef88a42a55784fd28b7450cf (diff) |
x86/asm/entry/32: Do not use R9 in SYSCALL32 entry point
SYSENTER and SYSCALL 32-bit entry points differ in handling of
arg2 and arg6.
SYSENTER:
* ecx arg2
* ebp user stack
* 0(%ebp) arg6
SYSCALL:
* ebp arg2
* esp user stack
* 0(%esp) arg6
Sysenter code loads 0(%ebp) to %ebp right away.
(This destroys %ebp. It means we do not preserve it on return.
It's not causing problems since userspace VDSO code does not
depend on it, and SYSENTER insn can't be sanely used outside of
VDSO).
Syscall code loads 0(%ebp) to %r9. This allows to eliminate one
MOV insn (r9 is a register where arg6 should be for 64-bit ABI),
but on audit/ptrace code paths this requires juggling of r9 and
ebp: (1) ptrace expects arg6 to be in pt_regs->bp;
(2) r9 is callee-clobbered register and needs to be
saved/restored around calls to C functions.
This patch changes syscall code to load 0(%ebp) to %ebp, making
it more similar to sysenter code. It's a bit smaller:
text data bss dec hex filename
1407 0 0 1407 57f ia32entry.o.before
1391 0 0 1391 56f ia32entry.o
To preserve ABI compat, we restore ebp on exit.
Run-tested.
Signed-off-by: Denys Vlasenko <[email protected]>
Cc: Alexei Starovoitov <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Andy Lutomirski <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Brian Gerst <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Kees Cook <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Oleg Nesterov <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Steven Rostedt <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Will Drewry <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
-rw-r--r-- | arch/x86/entry/ia32entry.S | 19 |
1 files changed, 8 insertions, 11 deletions
diff --git a/arch/x86/entry/ia32entry.S b/arch/x86/entry/ia32entry.S index 56f819e99258..63219154087e 100644 --- a/arch/x86/entry/ia32entry.S +++ b/arch/x86/entry/ia32entry.S @@ -323,7 +323,7 @@ ENTRY(ia32_cstar_target) * 32bit zero extended */ ASM_STAC -1: movl (%r8),%r9d +1: movl (%r8),%ebp _ASM_EXTABLE(1b,ia32_badarg) ASM_CLAC orl $TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS) @@ -333,7 +333,7 @@ ENTRY(ia32_cstar_target) cstar_do_call: /* 32bit syscall -> 64bit C ABI argument conversion */ movl %edi,%r8d /* arg5 */ - /* r9 already loaded */ /* arg6 */ + movl %ebp,%r9d /* arg6 */ xchg %ecx,%esi /* rsi:arg2, rcx:arg4 */ movl %ebx,%edi /* arg1 */ movl %edx,%edx /* arg3 (zero extension) */ @@ -349,6 +349,7 @@ cstar_dispatch: jnz sysretl_audit sysretl_from_sys_call: andl $~TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS) + movl RCX(%rsp), %ebp RESTORE_RSI_RDI_RDX movl RIP(%rsp),%ecx movl EFLAGS(%rsp),%r11d @@ -375,9 +376,8 @@ sysretl_from_sys_call: #ifdef CONFIG_AUDITSYSCALL cstar_auditsys: - movl %r9d,R9(%rsp) /* register to be clobbered by call */ auditsys_entry_common - movl R9(%rsp),%r9d /* reload 6th syscall arg */ + movl %ebp, %r9d /* reload 6th syscall arg */ jmp cstar_dispatch sysretl_audit: @@ -389,16 +389,14 @@ cstar_tracesys: testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT), ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS) jz cstar_auditsys #endif - xchgl %r9d,%ebp SAVE_EXTRA_REGS xorl %eax, %eax /* do not leak kernel information */ movq %rax, R11(%rsp) movq %rax, R10(%rsp) - movq %r9, R9(%rsp) + movq %rax, R9(%rsp) movq %rax, R8(%rsp) - movq %rsp,%rdi /* &pt_regs -> arg1 */ - call syscall_trace_enter - movl R9(%rsp),%r9d + movq %rsp, %rdi /* &pt_regs -> arg1 */ + call syscall_trace_enter /* Reload arg registers from stack. (see sysenter_tracesys) */ movl RCX(%rsp), %ecx @@ -408,8 +406,7 @@ cstar_tracesys: movl %eax, %eax /* zero extension */ RESTORE_EXTRA_REGS - xchgl %ebp,%r9d - jmp cstar_do_call + jmp cstar_do_call END(ia32_cstar_target) ia32_badarg: |