From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753694AbbBXSwW (ORCPT ); Tue, 24 Feb 2015 13:52:22 -0500 Received: from mx1.redhat.com ([209.132.183.28]:58554 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753145AbbBXSwU (ORCPT ); Tue, 24 Feb 2015 13:52:20 -0500 From: Denys Vlasenko To: Andy Lutomirski Cc: Denys Vlasenko , Linus Torvalds , Steven Rostedt , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" , Oleg Nesterov , Frederic Weisbecker , Alexei Starovoitov , Will Drewry , Kees Cook , x86@kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/4] x86: entry.S: tidy up several suboptimal insns Date: Tue, 24 Feb 2015 19:51:32 +0100 Message-Id: <1424803895-4420-1-git-send-email-dvlasenk@redhat.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In all three 32-bit entry points, %eax is zero-extended to %rax. It is safe to do 32-bit compare when checking that syscall# is not too large. The last instance of "mysterious" SS+8 constant is replaced by SIZEOF_PTREGS. The $AUDIT_ARCH_X86_64 parameter to syscall_trace_enter_phase1/2 is a 32-bit constant, loading it with 64-bit MOV produces 10-byte insn instead of 5-byte one. After TEST insn, JE anctually means "jump of zero", let's use JZ mnemonic instead. At irq_return_via_sysret: * avoid redundant load of %r11 (it is already loaded a few instructions before). * do not needlessly increment %rsp - we are going to return to userspace via SYSRET, this insn doesn't use stack for return. Signed-off-by: Denys Vlasenko CC: Linus Torvalds CC: Steven Rostedt CC: Ingo Molnar CC: Borislav Petkov CC: "H. Peter Anvin" CC: Andy Lutomirski CC: Oleg Nesterov CC: Frederic Weisbecker CC: Alexei Starovoitov CC: Will Drewry CC: Kees Cook CC: x86@kernel.org CC: linux-kernel@vger.kernel.org --- arch/x86/ia32/ia32entry.S | 14 +++++++------- arch/x86/include/asm/calling.h | 3 +++ arch/x86/kernel/entry_64.S | 13 ++++++------- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index 6dcd372..01eca80 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S @@ -163,8 +163,8 @@ sysenter_flags_fixed: orl $TS_COMPAT,TI_status+THREAD_INFO(%rsp,RIP) testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP) CFI_REMEMBER_STATE - jnz sysenter_tracesys - cmpq $(IA32_NR_syscalls-1),%rax + jnz sysenter_tracesys + cmpl $(IA32_NR_syscalls-1),%eax ja ia32_badsys sysenter_do_call: /* 32bit syscall -> 64bit C ABI argument conversion */ @@ -350,9 +350,9 @@ ENTRY(ia32_cstar_target) orl $TS_COMPAT,TI_status+THREAD_INFO(%rsp,RIP) testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP) CFI_REMEMBER_STATE - jnz cstar_tracesys - cmpq $IA32_NR_syscalls-1,%rax - ja ia32_badsys + jnz cstar_tracesys + cmpl $(IA32_NR_syscalls-1),%eax + ja ia32_badsys cstar_do_call: /* 32bit syscall -> 64bit C ABI argument conversion */ movl %edi,%r8d /* arg5 */ @@ -473,7 +473,7 @@ ENTRY(ia32_syscall) orl $TS_COMPAT,TI_status+THREAD_INFO(%rsp,RIP) testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP) jnz ia32_tracesys - cmpq $(IA32_NR_syscalls-1),%rax + cmpl $(IA32_NR_syscalls-1),%eax ja ia32_badsys ia32_do_call: /* 32bit syscall -> 64bit C ABI argument conversion */ @@ -536,7 +536,7 @@ ia32_ptregs_common: CFI_ENDPROC CFI_STARTPROC32 simple CFI_SIGNAL_FRAME - CFI_DEF_CFA rsp,SS+8 + CFI_DEF_CFA rsp,SIZEOF_PTREGS CFI_REL_OFFSET rax,RAX CFI_REL_OFFSET rcx,RCX CFI_REL_OFFSET rdx,RDX diff --git a/arch/x86/include/asm/calling.h b/arch/x86/include/asm/calling.h index 3374235..f1a962f 100644 --- a/arch/x86/include/asm/calling.h +++ b/arch/x86/include/asm/calling.h @@ -176,6 +176,9 @@ For 32-bit we have the following conventions - kernel is built with .macro RESTORE_C_REGS_EXCEPT_RCX RESTORE_C_REGS_HELPER 1,0,1,1,1 .endm + .macro RESTORE_C_REGS_EXCEPT_R11 + RESTORE_C_REGS_HELPER 1,1,0,1,1 + .endm .macro RESTORE_RSI_RDI RESTORE_C_REGS_HELPER 0,0,0,0,0 .endm diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 64f2fd3..b93f3a2 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -312,7 +312,7 @@ int_ret_from_sys_call_fixup: /* Do syscall tracing */ tracesys: movq %rsp, %rdi - movq $AUDIT_ARCH_X86_64, %rsi + movl $AUDIT_ARCH_X86_64, %esi call syscall_trace_enter_phase1 test %rax, %rax jnz tracesys_phase2 /* if needed, run the slow path */ @@ -323,7 +323,7 @@ tracesys_phase2: SAVE_EXTRA_REGS FIXUP_TOP_OF_STACK %rdi movq %rsp, %rdi - movq $AUDIT_ARCH_X86_64, %rsi + movl $AUDIT_ARCH_X86_64, %esi movq %rax,%rdx call syscall_trace_enter_phase2 @@ -686,7 +686,7 @@ ret_from_intr: exit_intr: GET_THREAD_INFO(%rcx) testl $3,CS(%rsp) - je retint_kernel + jz retint_kernel /* Interrupt came from user space */ /* @@ -742,7 +742,7 @@ retint_swapgs: /* return to user-space */ cmpq %r11,EFLAGS(%rsp) /* R11 == RFLAGS */ jne opportunistic_sysret_failed - testq $X86_EFLAGS_RF,%r11 /* sysret can't restore RF */ + testl $X86_EFLAGS_RF,%r11d /* sysret can't restore RF */ jnz opportunistic_sysret_failed /* nothing to check for RSP */ @@ -756,9 +756,8 @@ retint_swapgs: /* return to user-space */ */ irq_return_via_sysret: CFI_REMEMBER_STATE - RESTORE_C_REGS - REMOVE_PT_GPREGS_FROM_STACK 8 - movq (RSP-RIP)(%rsp),%rsp + RESTORE_C_REGS_EXCEPT_R11 + movq RSP(%rsp),%rsp USERGS_SYSRET64 CFI_RESTORE_STATE -- 1.8.1.4