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 <dvlas...@redhat.com>
CC: Linus Torvalds <torva...@linux-foundation.org>
CC: Steven Rostedt <rost...@goodmis.org>
CC: Ingo Molnar <mi...@kernel.org>
CC: Borislav Petkov <b...@alien8.de>
CC: "H. Peter Anvin" <h...@zytor.com>
CC: Andy Lutomirski <l...@amacapital.net>
CC: Oleg Nesterov <o...@redhat.com>
CC: Frederic Weisbecker <fweis...@gmail.com>
CC: Alexei Starovoitov <a...@plumgrid.com>
CC: Will Drewry <w...@chromium.org>
CC: Kees Cook <keesc...@chromium.org>
CC: x...@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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to