提交 cb6f64ed 编写于 作者: A Andy Lutomirski 提交者: Ingo Molnar

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: NAndy 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.orgSigned-off-by: NIngo Molnar <mingo@kernel.org>
上级 c5c46f59
...@@ -1143,12 +1143,17 @@ ENTRY(error_entry) ...@@ -1143,12 +1143,17 @@ ENTRY(error_entry)
SAVE_EXTRA_REGS 8 SAVE_EXTRA_REGS 8
xorl %ebx, %ebx xorl %ebx, %ebx
testb $3, CS+8(%rsp) 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 SWAPGS
error_entry_done: .Lerror_entry_from_usermode_after_swapgs:
.Lerror_entry_done:
TRACE_IRQS_OFF TRACE_IRQS_OFF
ret ret
...@@ -1158,31 +1163,30 @@ error_entry_done: ...@@ -1158,31 +1163,30 @@ error_entry_done:
* truncated RIP for IRET exceptions returning to compat mode. Check * truncated RIP for IRET exceptions returning to compat mode. Check
* for these here too. * for these here too.
*/ */
error_kernelspace: .Lerror_kernelspace:
incl %ebx incl %ebx
leaq native_irq_return_iret(%rip), %rcx leaq native_irq_return_iret(%rip), %rcx
cmpq %rcx, RIP+8(%rsp) cmpq %rcx, RIP+8(%rsp)
je error_bad_iret je .Lerror_bad_iret
movl %ecx, %eax /* zero extend */ movl %ecx, %eax /* zero extend */
cmpq %rax, RIP+8(%rsp) cmpq %rax, RIP+8(%rsp)
je bstep_iret je .Lbstep_iret
cmpq $gs_change, RIP+8(%rsp) 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 * 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 * gsbase and proceed. We'll fix up the exception and land in
* gs_change's error handler with kernel gsbase. * gs_change's error handler with kernel gsbase.
*/ */
SWAPGS jmp .Lerror_entry_from_usermode_swapgs
jmp error_entry_done
bstep_iret: .Lbstep_iret:
/* Fix truncated RIP */ /* Fix truncated RIP */
movq %rcx, RIP+8(%rsp) movq %rcx, RIP+8(%rsp)
/* fall through */ /* fall through */
error_bad_iret: .Lerror_bad_iret:
/* /*
* We came from an IRET to user mode, so we have user gsbase. * We came from an IRET to user mode, so we have user gsbase.
* Switch to kernel gsbase: * Switch to kernel gsbase:
...@@ -1198,7 +1202,7 @@ error_bad_iret: ...@@ -1198,7 +1202,7 @@ error_bad_iret:
call fixup_bad_iret call fixup_bad_iret
mov %rax, %rsp mov %rax, %rsp
decl %ebx decl %ebx
jmp error_entry_done jmp .Lerror_entry_from_usermode_after_swapgs
END(error_entry) END(error_entry)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册