lkml.org 
[lkml]   [2014]   [Dec]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.16.y-ckt 050/168] x86_64, traps: Stop using IST for #SS
    Date
    3.16.7-ckt3 -stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Andy Lutomirski <luto@amacapital.net>

    commit 6f442be2fb22be02cafa606f1769fa1e6f894441 upstream.

    On a 32-bit kernel, this has no effect, since there are no IST stacks.

    On a 64-bit kernel, #SS can only happen in user code, on a failed iret
    to user space, a canonical violation on access via RSP or RBP, or a
    genuine stack segment violation in 32-bit kernel code. The first two
    cases don't need IST, and the latter two cases are unlikely fatal bugs,
    and promoting them to double faults would be fine.

    This fixes a bug in which the espfix64 code mishandles a stack segment
    violation.

    This saves 4k of memory per CPU and a tiny bit of code.

    Signed-off-by: Andy Lutomirski <luto@amacapital.net>
    Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
    ---
    arch/x86/include/asm/page_32_types.h | 1 -
    arch/x86/include/asm/page_64_types.h | 11 +++++------
    arch/x86/include/asm/traps.h | 1 +
    arch/x86/kernel/dumpstack_64.c | 1 -
    arch/x86/kernel/entry_64.S | 2 +-
    arch/x86/kernel/traps.c | 18 +-----------------
    6 files changed, 8 insertions(+), 26 deletions(-)

    diff --git a/arch/x86/include/asm/page_32_types.h b/arch/x86/include/asm/page_32_types.h
    index f48b17df4224..3a52ee0e726d 100644
    --- a/arch/x86/include/asm/page_32_types.h
    +++ b/arch/x86/include/asm/page_32_types.h
    @@ -20,7 +20,6 @@
    #define THREAD_SIZE_ORDER 1
    #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)

    -#define STACKFAULT_STACK 0
    #define DOUBLEFAULT_STACK 1
    #define NMI_STACK 0
    #define DEBUG_STACK 0
    diff --git a/arch/x86/include/asm/page_64_types.h b/arch/x86/include/asm/page_64_types.h
    index 678205195ae1..75450b2c7be4 100644
    --- a/arch/x86/include/asm/page_64_types.h
    +++ b/arch/x86/include/asm/page_64_types.h
    @@ -14,12 +14,11 @@
    #define IRQ_STACK_ORDER 2
    #define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER)

    -#define STACKFAULT_STACK 1
    -#define DOUBLEFAULT_STACK 2
    -#define NMI_STACK 3
    -#define DEBUG_STACK 4
    -#define MCE_STACK 5
    -#define N_EXCEPTION_STACKS 5 /* hw limit: 7 */
    +#define DOUBLEFAULT_STACK 1
    +#define NMI_STACK 2
    +#define DEBUG_STACK 3
    +#define MCE_STACK 4
    +#define N_EXCEPTION_STACKS 4 /* hw limit: 7 */

    #define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT)
    #define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1))
    diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h
    index bc8352e7010a..707adc6549d8 100644
    --- a/arch/x86/include/asm/traps.h
    +++ b/arch/x86/include/asm/traps.h
    @@ -39,6 +39,7 @@ asmlinkage void simd_coprocessor_error(void);

    #ifdef CONFIG_TRACING
    asmlinkage void trace_page_fault(void);
    +#define trace_stack_segment stack_segment
    #define trace_divide_error divide_error
    #define trace_bounds bounds
    #define trace_invalid_op invalid_op
    diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c
    index 1abcb50b48ae..ff86f19b5758 100644
    --- a/arch/x86/kernel/dumpstack_64.c
    +++ b/arch/x86/kernel/dumpstack_64.c
    @@ -24,7 +24,6 @@ static char x86_stack_ids[][8] = {
    [ DEBUG_STACK-1 ] = "#DB",
    [ NMI_STACK-1 ] = "NMI",
    [ DOUBLEFAULT_STACK-1 ] = "#DF",
    - [ STACKFAULT_STACK-1 ] = "#SS",
    [ MCE_STACK-1 ] = "#MC",
    #if DEBUG_STKSZ > EXCEPTION_STKSZ
    [ N_EXCEPTION_STACKS ...
    diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
    index c844f0816ab8..1b1d9ab375a5 100644
    --- a/arch/x86/kernel/entry_64.S
    +++ b/arch/x86/kernel/entry_64.S
    @@ -1303,7 +1303,7 @@ apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \

    idtentry debug do_debug has_error_code=0 paranoid=1 shift_ist=DEBUG_STACK
    idtentry int3 do_int3 has_error_code=0 paranoid=1 shift_ist=DEBUG_STACK
    -idtentry stack_segment do_stack_segment has_error_code=1 paranoid=1
    +idtentry stack_segment do_stack_segment has_error_code=1
    #ifdef CONFIG_XEN
    idtentry xen_debug do_debug has_error_code=0
    idtentry xen_int3 do_int3 has_error_code=0
    diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
    index 0d0e922fafc1..0eafe9ea2494 100644
    --- a/arch/x86/kernel/traps.c
    +++ b/arch/x86/kernel/traps.c
    @@ -233,27 +233,11 @@ DO_ERROR(X86_TRAP_UD, SIGILL, "invalid opcode", invalid_op)
    DO_ERROR(X86_TRAP_OLD_MF, SIGFPE, "coprocessor segment overrun",coprocessor_segment_overrun)
    DO_ERROR(X86_TRAP_TS, SIGSEGV, "invalid TSS", invalid_TSS)
    DO_ERROR(X86_TRAP_NP, SIGBUS, "segment not present", segment_not_present)
    -#ifdef CONFIG_X86_32
    DO_ERROR(X86_TRAP_SS, SIGBUS, "stack segment", stack_segment)
    -#endif
    DO_ERROR(X86_TRAP_AC, SIGBUS, "alignment check", alignment_check)

    #ifdef CONFIG_X86_64
    /* Runs on IST stack */
    -dotraplinkage void do_stack_segment(struct pt_regs *regs, long error_code)
    -{
    - enum ctx_state prev_state;
    -
    - prev_state = exception_enter();
    - if (notify_die(DIE_TRAP, "stack segment", regs, error_code,
    - X86_TRAP_SS, SIGBUS) != NOTIFY_STOP) {
    - preempt_conditional_sti(regs);
    - do_trap(X86_TRAP_SS, SIGBUS, "stack segment", regs, error_code, NULL);
    - preempt_conditional_cli(regs);
    - }
    - exception_exit(prev_state);
    -}
    -
    dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code)
    {
    static const char str[] = "double fault";
    @@ -778,7 +762,7 @@ void __init trap_init(void)
    set_intr_gate(X86_TRAP_OLD_MF, coprocessor_segment_overrun);
    set_intr_gate(X86_TRAP_TS, invalid_TSS);
    set_intr_gate(X86_TRAP_NP, segment_not_present);
    - set_intr_gate_ist(X86_TRAP_SS, &stack_segment, STACKFAULT_STACK);
    + set_intr_gate(X86_TRAP_SS, stack_segment);
    set_intr_gate(X86_TRAP_GP, general_protection);
    set_intr_gate(X86_TRAP_SPURIOUS, spurious_interrupt_bug);
    set_intr_gate(X86_TRAP_MF, coprocessor_error);
    --
    2.1.3


    \
     
     \ /
      Last update: 2014-12-15 16:41    [W:2.759 / U:0.100 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site