Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8a9949bc authored by Andy Lutomirski's avatar Andy Lutomirski Committed by Ingo Molnar
Browse files

x86/xen/64: Rearrange the SYSCALL entries



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: default avatarJuergen Gross <jgross@suse.com>
Signed-off-by: default avatarAndy Lutomirski <luto@kernel.org>
Reviewed-by: default avatarJuergen 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: default avatarIngo Molnar <mingo@kernel.org>
parent 1d0f49e1
Loading
Loading
Loading
Loading
+2 −7
Original line number Diff line number Diff line
@@ -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 */
+3 −4
Original line number Diff line number Diff line
@@ -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 */
+9 −14
Original line number Diff line number Diff line
@@ -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)