Commit-ID:  cb6f64ed5a04036eef07e70b57dd5dd78f2fbcef
Gitweb:     http://git.kernel.org/tip/cb6f64ed5a04036eef07e70b57dd5dd78f2fbcef
Author:     Andy Lutomirski <[email protected]>
AuthorDate: Fri, 3 Jul 2015 12:44:27 -0700
Committer:  Ingo Molnar <[email protected]>
CommitDate: Tue, 7 Jul 2015 10:59:07 +0200

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

In 539f51136500 ("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: Andy Lutomirski <[email protected]>
Cc: Andy Lutomirski <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Brian Gerst <[email protected]>
Cc: Denys Vlasenko <[email protected]>
Cc: Denys Vlasenko <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Kees Cook <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Oleg Nesterov <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Rik van Riel <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: [email protected]
Link: 
http://lkml.kernel.org/r/91e17891e49fa3d61357eadc451529ad48143ee1.1435952415.git.l...@kernel.org
Signed-off-by: Ingo Molnar <[email protected]>
---
 arch/x86/entry/entry_64.S | 28 ++++++++++++++++------------
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 141a5d4..ccfcba9 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -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)
 
 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
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