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

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

x86/entry/64: Really create an error-entry-from-usermode code path



In 539f5113 ("x86/asm/entry/64: Disentangle error_entry/exit
gsbase/ebx/usermode code"), I arranged the code slightly wrong
-- IRET faults would skip the code path that was intended to
execute on all error entries from user mode.  Fix it up.

While we're at it, make all the labels in error_entry local.

This does not fix a bug, but we'll need it, and it slightly
shrinks the code.

Signed-off-by: default avatarAndy Lutomirski <luto@kernel.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Denys Vlasenko <vda.linux@googlemail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rik van Riel <riel@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: paulmck@linux.vnet.ibm.com
Link: http://lkml.kernel.org/r/91e17891e49fa3d61357eadc451529ad48143ee1.1435952415.git.luto@kernel.org


Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent c5c46f59
Loading
Loading
Loading
Loading
+16 −12
Original line number Diff line number Diff line
@@ -1143,12 +1143,17 @@ ENTRY(error_entry)
	SAVE_EXTRA_REGS 8
	xorl	%ebx, %ebx
	testb	$3, CS+8(%rsp)
	jz	error_kernelspace
	jz	.Lerror_kernelspace

	/* We entered from user mode */
.Lerror_entry_from_usermode_swapgs:
	/*
	 * We entered from user mode or we're pretending to have entered
	 * from user mode due to an IRET fault.
	 */
	SWAPGS

error_entry_done:
.Lerror_entry_from_usermode_after_swapgs:
.Lerror_entry_done:
	TRACE_IRQS_OFF
	ret

@@ -1158,31 +1163,30 @@ error_entry_done:
	 * truncated RIP for IRET exceptions returning to compat mode. Check
	 * for these here too.
	 */
error_kernelspace:
.Lerror_kernelspace:
	incl	%ebx
	leaq	native_irq_return_iret(%rip), %rcx
	cmpq	%rcx, RIP+8(%rsp)
	je	error_bad_iret
	je	.Lerror_bad_iret
	movl	%ecx, %eax			/* zero extend */
	cmpq	%rax, RIP+8(%rsp)
	je	bstep_iret
	je	.Lbstep_iret
	cmpq	$gs_change, RIP+8(%rsp)
	jne	error_entry_done
	jne	.Lerror_entry_done

	/*
	 * hack: gs_change can fail with user gsbase.  If this happens, fix up
	 * gsbase and proceed.  We'll fix up the exception and land in
	 * gs_change's error handler with kernel gsbase.
	 */
	SWAPGS
	jmp	error_entry_done
	jmp	.Lerror_entry_from_usermode_swapgs

bstep_iret:
.Lbstep_iret:
	/* Fix truncated RIP */
	movq	%rcx, RIP+8(%rsp)
	/* fall through */

error_bad_iret:
.Lerror_bad_iret:
	/*
	 * We came from an IRET to user mode, so we have user gsbase.
	 * Switch to kernel gsbase:
@@ -1198,7 +1202,7 @@ error_bad_iret:
	call	fixup_bad_iret
	mov	%rax, %rsp
	decl	%ebx
	jmp	error_entry_done
	jmp	.Lerror_entry_from_usermode_after_swapgs
END(error_entry)