lkml.org 
[lkml]   [2014]   [Jul]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.15 82/84] x86, espfix: Make it possible to disable 16-bit support
    Date
    3.15-stable review patch.  If anyone has any objections, please let me know.

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

    From: "H. Peter Anvin" <hpa@zytor.com>

    commit 34273f41d57ee8d854dcd2a1d754cbb546cb548f upstream.

    Embedded systems, which may be very memory-size-sensitive, are
    extremely unlikely to ever encounter any 16-bit software, so make it
    a CONFIG_EXPERT option to turn off support for any 16-bit software
    whatsoever.

    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
    Link: http://lkml.kernel.org/r/1398816946-3351-1-git-send-email-hpa@linux.intel.com
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    arch/x86/Kconfig | 23 ++++++++++++++++++-----
    arch/x86/kernel/entry_32.S | 12 ++++++++++++
    arch/x86/kernel/entry_64.S | 8 ++++++++
    arch/x86/kernel/ldt.c | 5 +++++
    4 files changed, 43 insertions(+), 5 deletions(-)

    --- a/arch/x86/Kconfig
    +++ b/arch/x86/Kconfig
    @@ -909,14 +909,27 @@ config VM86
    default y
    depends on X86_32
    ---help---
    - This option is required by programs like DOSEMU to run 16-bit legacy
    - code on X86 processors. It also may be needed by software like
    - XFree86 to initialize some video cards via BIOS. Disabling this
    - option saves about 6k.
    + This option is required by programs like DOSEMU to run
    + 16-bit real mode legacy code on x86 processors. It also may
    + be needed by software like XFree86 to initialize some video
    + cards via BIOS. Disabling this option saves about 6K.
    +
    +config X86_16BIT
    + bool "Enable support for 16-bit segments" if EXPERT
    + default y
    + ---help---
    + This option is required by programs like Wine to run 16-bit
    + protected mode legacy code on x86 processors. Disabling
    + this option saves about 300 bytes on i386, or around 6K text
    + plus 16K runtime memory on x86-64,
    +
    +config X86_ESPFIX32
    + def_bool y
    + depends on X86_16BIT && X86_32

    config X86_ESPFIX64
    def_bool y
    - depends on X86_64
    + depends on X86_16BIT && X86_64

    config TOSHIBA
    tristate "Toshiba Laptop support"
    --- a/arch/x86/kernel/entry_32.S
    +++ b/arch/x86/kernel/entry_32.S
    @@ -528,6 +528,7 @@ syscall_exit:
    restore_all:
    TRACE_IRQS_IRET
    restore_all_notrace:
    +#ifdef CONFIG_X86_ESPFIX32
    movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
    # Warning: PT_OLDSS(%esp) contains the wrong/random values if we
    # are returning to the kernel.
    @@ -538,6 +539,7 @@ restore_all_notrace:
    cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax
    CFI_REMEMBER_STATE
    je ldt_ss # returning to user-space with LDT SS
    +#endif
    restore_nocheck:
    RESTORE_REGS 4 # skip orig_eax/error_code
    irq_return:
    @@ -550,6 +552,7 @@ ENTRY(iret_exc)
    .previous
    _ASM_EXTABLE(irq_return,iret_exc)

    +#ifdef CONFIG_X86_ESPFIX32
    CFI_RESTORE_STATE
    ldt_ss:
    #ifdef CONFIG_PARAVIRT
    @@ -593,6 +596,7 @@ ldt_ss:
    lss (%esp), %esp /* switch to espfix segment */
    CFI_ADJUST_CFA_OFFSET -8
    jmp restore_nocheck
    +#endif
    CFI_ENDPROC
    ENDPROC(system_call)

    @@ -705,6 +709,7 @@ END(syscall_badsys)
    * the high word of the segment base from the GDT and swiches to the
    * normal stack and adjusts ESP with the matching offset.
    */
    +#ifdef CONFIG_X86_ESPFIX32
    /* fixup the stack */
    mov GDT_ESPFIX_SS + 4, %al /* bits 16..23 */
    mov GDT_ESPFIX_SS + 7, %ah /* bits 24..31 */
    @@ -714,8 +719,10 @@ END(syscall_badsys)
    pushl_cfi %eax
    lss (%esp), %esp /* switch to the normal stack segment */
    CFI_ADJUST_CFA_OFFSET -8
    +#endif
    .endm
    .macro UNWIND_ESPFIX_STACK
    +#ifdef CONFIG_X86_ESPFIX32
    movl %ss, %eax
    /* see if on espfix stack */
    cmpw $__ESPFIX_SS, %ax
    @@ -726,6 +733,7 @@ END(syscall_badsys)
    /* switch to normal stack */
    FIXUP_ESPFIX_STACK
    27:
    +#endif
    .endm

    /*
    @@ -1356,11 +1364,13 @@ END(debug)
    ENTRY(nmi)
    RING0_INT_FRAME
    ASM_CLAC
    +#ifdef CONFIG_X86_ESPFIX32
    pushl_cfi %eax
    movl %ss, %eax
    cmpw $__ESPFIX_SS, %ax
    popl_cfi %eax
    je nmi_espfix_stack
    +#endif
    cmpl $ia32_sysenter_target,(%esp)
    je nmi_stack_fixup
    pushl_cfi %eax
    @@ -1400,6 +1410,7 @@ nmi_debug_stack_check:
    FIX_STACK 24, nmi_stack_correct, 1
    jmp nmi_stack_correct

    +#ifdef CONFIG_X86_ESPFIX32
    nmi_espfix_stack:
    /* We have a RING0_INT_FRAME here.
    *
    @@ -1421,6 +1432,7 @@ nmi_espfix_stack:
    lss 12+4(%esp), %esp # back to espfix stack
    CFI_ADJUST_CFA_OFFSET -24
    jmp irq_return
    +#endif
    CFI_ENDPROC
    END(nmi)

    --- a/arch/x86/kernel/entry_64.S
    +++ b/arch/x86/kernel/entry_64.S
    @@ -1045,8 +1045,10 @@ irq_return:
    * Are we returning to a stack segment from the LDT? Note: in
    * 64-bit mode SS:RSP on the exception stack is always valid.
    */
    +#ifdef CONFIG_X86_ESPFIX64
    testb $4,(SS-RIP)(%rsp)
    jnz irq_return_ldt
    +#endif

    irq_return_iret:
    INTERRUPT_RETURN
    @@ -1058,6 +1060,7 @@ ENTRY(native_iret)
    _ASM_EXTABLE(native_iret, bad_iret)
    #endif

    +#ifdef CONFIG_X86_ESPFIX64
    irq_return_ldt:
    pushq_cfi %rax
    pushq_cfi %rdi
    @@ -1081,6 +1084,7 @@ irq_return_ldt:
    movq %rax,%rsp
    popq_cfi %rax
    jmp irq_return_iret
    +#endif

    .section .fixup,"ax"
    bad_iret:
    @@ -1152,6 +1156,7 @@ END(common_interrupt)
    * modify the stack to make it look like we just entered
    * the #GP handler from user space, similar to bad_iret.
    */
    +#ifdef CONFIG_X86_ESPFIX64
    ALIGN
    __do_double_fault:
    XCPT_FRAME 1 RDI+8
    @@ -1177,6 +1182,9 @@ __do_double_fault:
    retq
    CFI_ENDPROC
    END(__do_double_fault)
    +#else
    +# define __do_double_fault do_double_fault
    +#endif

    /*
    * End of kprobes section
    --- a/arch/x86/kernel/ldt.c
    +++ b/arch/x86/kernel/ldt.c
    @@ -229,6 +229,11 @@ static int write_ldt(void __user *ptr, u
    }
    }

    + if (!IS_ENABLED(CONFIG_X86_16BIT) && !ldt_info.seg_32bit) {
    + error = -EINVAL;
    + goto out_unlock;
    + }
    +
    fill_ldt(&ldt, &ldt_info);
    if (oldmode)
    ldt.avl = 0;



    \
     
     \ /
      Last update: 2014-07-16 02:21    [W:4.235 / U:0.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site