This change swaps a few instructions in final register restoring/zeroing
section of SYSENTER fast path, and adds/deletes a few empty lines.

After this, the difference between SYSENTER and SYCALL fast paths
(after the prologue which saved pt_regs) is very small:
they differ merely in the choice of register to hold arg6 (EBP or R9)
and in the value of EDX on exit: SYSENTER ABI doesn't need to preserve it,
so it is zeroed. SYSCALL preserves it:

       |(prologue is different)
       |        orl     $TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, 
SIZEOF_PTREGS)
       |        testl   $_TIF_WORK_SYSCALL_ENTRY, ASM_THREAD_INFO(TI_flags, 
%rsp, SIZEOF_PTREGS)
       |-       jnz     sysenter_tracesys
       |+       jnz     cstar_tracesys
       |
       |-sysenter_do_call:
       |+cstar_do_call:
       |        /* 32-bit syscall -> 64-bit C ABI argument conversion */
       |        movl    %edi, %r8d              /* arg5 */
       |-       movl    %ebp, %r9d              /* arg6 */
       |+       /* r9 already loaded */         /* arg6 */
       |        xchg    %ecx, %esi              /* rsi:arg2, rcx:arg4 */
       |        movl    %ebx, %edi              /* arg1 */
       |        movl    %edx, %edx              /* arg3 (zero extension) */
       |
       |-sysenter_dispatch:
       |+cstar_dispatch:
       |        cmpq    $(IA32_NR_syscalls-1), %rax
       |        ja      1f
       |        call    *ia32_sys_call_table(, %rax, 8)
       |@@ -19,15 +19,15 @@
       |        DISABLE_INTERRUPTS(CLBR_NONE)
       |        TRACE_IRQS_OFF
       |        testl   $_TIF_ALLWORK_MASK, ASM_THREAD_INFO(TI_flags, %rsp, 
SIZEOF_PTREGS)
       |-       jnz     sysexit_audit
       |+       jnz     sysretl_audit
       |
       |-sysexit_from_sys_call:
       |+sysretl_from_sys_call:
       |        andl    $~TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, 
SIZEOF_PTREGS)
       |+       movl    RDX(%rsp), %edx
       |        movl    RSI(%rsp), %esi
       |        movl    RDI(%rsp), %edi
       |        movl    RIP(%rsp), %ecx
       |        movl    EFLAGS(%rsp), %r11d
       |-       xorl    %edx, %edx
       |        xorq    %r10, %r10
       |        xorq    %r9, %r9
       |        xorq    %r8, %r8
       |(the rest of fast path, up to final SYSRET32, is identical)

This is a preparatory change which allows to drop most of SYSENTER machinery
and make SYSENTER reuse SYSCALL code.

Signed-off-by: Denys Vlasenko <dvlas...@redhat.com>
CC: Ingo Molnar <mi...@kernel.org>
CC: Linus Torvalds <torva...@linux-foundation.org>
CC: Krzysztof A. Sobiecki <sob...@gmail.com>
CC: Steven Rostedt <rost...@goodmis.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/entry/entry_64_compat.S | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S
index 8997383..9f9dfa5 100644
--- a/arch/x86/entry/entry_64_compat.S
+++ b/arch/x86/entry/entry_64_compat.S
@@ -117,6 +117,7 @@ sysenter_do_call:
        xchg    %ecx, %esi              /* rsi:arg2, rcx:arg4 */
        movl    %ebx, %edi              /* arg1 */
        movl    %edx, %edx              /* arg3 (zero extension) */
+
 sysenter_dispatch:
        cmpq    $(IA32_NR_syscalls-1), %rax
        ja      1f
@@ -127,6 +128,7 @@ sysenter_dispatch:
        TRACE_IRQS_OFF
        testl   $_TIF_ALLWORK_MASK, ASM_THREAD_INFO(TI_flags, %rsp, 
SIZEOF_PTREGS)
        jnz     sysexit_audit
+
 sysexit_from_sys_call:
        /*
         * NB: SYSEXIT is not obviously safe for 64-bit kernels -- an
@@ -139,14 +141,14 @@ sysexit_from_sys_call:
         * with 'sysenter' and it uses the SYSENTER calling convention.
         */
        andl    $~TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)
-       movl    RIP(%rsp), %ecx         /* User %eip */
        movl    RSI(%rsp), %esi
        movl    RDI(%rsp), %edi
+       movl    RIP(%rsp), %ecx         /* User %eip */
+       movl    EFLAGS(%rsp), %r11d     /* User eflags */
        xorl    %edx, %edx              /* Do not leak kernel information */
-       xorq    %r8, %r8
-       xorq    %r9, %r9
        xorq    %r10, %r10
-       movl    EFLAGS(%rsp), %r11d     /* User eflags */
+       xorq    %r9, %r9
+       xorq    %r8, %r8
        TRACE_IRQS_ON
 
        /*
@@ -340,6 +342,7 @@ ENTRY(entry_SYSCALL_compat)
 1:     movl    (%r8), %r9d
        _ASM_EXTABLE(1b, ia32_badarg)
        ASM_CLAC
+
        orl     $TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)
        testl   $_TIF_WORK_SYSCALL_ENTRY, ASM_THREAD_INFO(TI_flags, %rsp, 
SIZEOF_PTREGS)
        jnz     cstar_tracesys
@@ -355,7 +358,6 @@ cstar_do_call:
 cstar_dispatch:
        cmpq    $(IA32_NR_syscalls-1), %rax
        ja      1f
-
        call    *ia32_sys_call_table(, %rax, 8)
        movq    %rax, RAX(%rsp)
 1:
-- 
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