x86/xen/64: Rearrange the SYSCALL entries
authorAndy Lutomirski <luto@kernel.org>
Tue, 8 Aug 2017 03:59:21 +0000 (20:59 -0700)
committerIngo Molnar <mingo@kernel.org>
Thu, 10 Aug 2017 11:14:32 +0000 (13:14 +0200)
Xen's raw SYSCALL entries are much less weird than native.  Rather
than fudging them to look like native entries, use the Xen-provided
stack frame directly.

This lets us eliminate entry_SYSCALL_64_after_swapgs and two uses of
the SWAPGS_UNSAFE_STACK paravirt hook.  The SYSENTER code would
benefit from similar treatment.

This makes one change to the native code path: the compat
instruction that clears the high 32 bits of %rax is moved slightly
later.  I'd be surprised if this affects performance at all.

Tested-by: Juergen Gross <jgross@suse.com>
Signed-off-by: Andy Lutomirski <luto@kernel.org>
Reviewed-by: Juergen Gross <jgross@suse.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: Borislav Petkov <bpetkov@suse.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: xen-devel@lists.xenproject.org
Link: http://lkml.kernel.org/r/7c88ed36805d36841ab03ec3b48b4122c4418d71.1502164668.git.luto@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
arch/x86/entry/entry_64.S
arch/x86/entry/entry_64_compat.S
arch/x86/xen/xen-asm_64.S

index 64b233ab7cad98b613df5b47de975fb8a77b75a0..4dbb336a1fdd1bacfbf294ffef2a4a43a81d924a 100644 (file)
@@ -142,14 +142,8 @@ ENTRY(entry_SYSCALL_64)
         * We do not frame this tiny irq-off block with TRACE_IRQS_OFF/ON,
         * it is too small to ever cause noticeable irq latency.
         */
-       SWAPGS_UNSAFE_STACK
-       /*
-        * A hypervisor implementation might want to use a label
-        * after the swapgs, so that it can do the swapgs
-        * for the guest and jump here on syscall.
-        */
-GLOBAL(entry_SYSCALL_64_after_swapgs)
 
+       swapgs
        movq    %rsp, PER_CPU_VAR(rsp_scratch)
        movq    PER_CPU_VAR(cpu_current_top_of_stack), %rsp
 
@@ -161,6 +155,7 @@ GLOBAL(entry_SYSCALL_64_after_swapgs)
        pushq   %r11                            /* pt_regs->flags */
        pushq   $__USER_CS                      /* pt_regs->cs */
        pushq   %rcx                            /* pt_regs->ip */
+GLOBAL(entry_SYSCALL_64_after_hwframe)
        pushq   %rax                            /* pt_regs->orig_ax */
        pushq   %rdi                            /* pt_regs->di */
        pushq   %rsi                            /* pt_regs->si */
index e1721dafbcb13fab9230cc20d598b18ebef8306b..5314d7b8e5ad4d8b2a1dff24b4e53efb132ced07 100644 (file)
@@ -183,21 +183,20 @@ ENDPROC(entry_SYSENTER_compat)
  */
 ENTRY(entry_SYSCALL_compat)
        /* Interrupts are off on entry. */
-       SWAPGS_UNSAFE_STACK
+       swapgs
 
        /* Stash user ESP and switch to the kernel stack. */
        movl    %esp, %r8d
        movq    PER_CPU_VAR(cpu_current_top_of_stack), %rsp
 
-       /* Zero-extending 32-bit regs, do not remove */
-       movl    %eax, %eax
-
        /* Construct struct pt_regs on stack */
        pushq   $__USER32_DS            /* pt_regs->ss */
        pushq   %r8                     /* pt_regs->sp */
        pushq   %r11                    /* pt_regs->flags */
        pushq   $__USER32_CS            /* pt_regs->cs */
        pushq   %rcx                    /* pt_regs->ip */
+GLOBAL(entry_SYSCALL_compat_after_hwframe)
+       movl    %eax, %eax              /* discard orig_ax high bits */
        pushq   %rax                    /* pt_regs->orig_ax */
        pushq   %rdi                    /* pt_regs->di */
        pushq   %rsi                    /* pt_regs->si */
index c3df43141e7064477b1d2da432e7f8d0d81ea3f2..a8a4f4c460a6cb5cf0b20329c356f0cde0ee1ca2 100644 (file)
@@ -82,34 +82,29 @@ RELOC(xen_sysret64, 1b+1)
  *     rip
  *     r11
  * rsp->rcx
- *
- * In all the entrypoints, we undo all that to make it look like a
- * CPU-generated syscall/sysenter and jump to the normal entrypoint.
  */
 
-.macro undo_xen_syscall
-       mov 0*8(%rsp), %rcx
-       mov 1*8(%rsp), %r11
-       mov 5*8(%rsp), %rsp
-.endm
-
 /* Normal 64-bit system call target */
 ENTRY(xen_syscall_target)
-       undo_xen_syscall
-       jmp entry_SYSCALL_64_after_swapgs
+       popq %rcx
+       popq %r11
+       jmp entry_SYSCALL_64_after_hwframe
 ENDPROC(xen_syscall_target)
 
 #ifdef CONFIG_IA32_EMULATION
 
 /* 32-bit compat syscall target */
 ENTRY(xen_syscall32_target)
-       undo_xen_syscall
-       jmp entry_SYSCALL_compat
+       popq %rcx
+       popq %r11
+       jmp entry_SYSCALL_compat_after_hwframe
 ENDPROC(xen_syscall32_target)
 
 /* 32-bit compat sysenter target */
 ENTRY(xen_sysenter_target)
-       undo_xen_syscall
+       mov 0*8(%rsp), %rcx
+       mov 1*8(%rsp), %r11
+       mov 5*8(%rsp), %rsp
        jmp entry_SYSENTER_compat
 ENDPROC(xen_sysenter_target)