lkml.org 
[lkml]   [2015]   [Jul]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v5 10/17] x86/entry/64: Really create an error-entry-from-usermode code path
    Date
    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 <luto@kernel.org>
    ---
    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 141a5d49dddc..ccfcba90de6e 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)


    --
    2.4.3


    \
     
     \ /
      Last update: 2015-07-03 22:21    [W:2.419 / U:0.052 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site