lkml.org 
[lkml]   [2015]   [Dec]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.16.y-ckt 069/126] x86/cpu: Call verify_cpu() after having entered long mode too
    Date
    3.16.7-ckt21 -stable review patch.  If anyone has any objections, please let me know.

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

    From: Borislav Petkov <bp@suse.de>

    commit 04633df0c43d710e5f696b06539c100898678235 upstream.

    When we get loaded by a 64-bit bootloader, kernel entry point is
    startup_64 in head_64.S. We don't trust any and all bootloaders because
    some will fiddle with CPU configuration so we go ahead and massage each
    CPU into sanity again.

    For example, some dell BIOSes have this XD disable feature which set
    IA32_MISC_ENABLE[34] and disable NX. This might be some dumb workaround
    for other OSes but Linux sure doesn't need it.

    A similar thing is present in the Surface 3 firmware - see
    https://bugzilla.kernel.org/show_bug.cgi?id=106051 - which sets this bit
    only on the BSP:

    # rdmsr -a 0x1a0
    400850089
    850089
    850089
    850089

    I know, right?!

    There's not even an off switch in there.

    So fix all those cases by sanitizing the 64-bit entry point too. For
    that, make verify_cpu() callable in 64-bit mode also.

    Requested-and-debugged-by: "H. Peter Anvin" <hpa@zytor.com>
    Reported-and-tested-by: Bastien Nocera <bugzilla@hadess.net>
    Signed-off-by: Borislav Petkov <bp@suse.de>
    Cc: Matt Fleming <matt@codeblueprint.co.uk>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Link: http://lkml.kernel.org/r/1446739076-21303-1-git-send-email-bp@alien8.de
    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
    ---
    arch/x86/kernel/head_64.S | 8 ++++++++
    arch/x86/kernel/verify_cpu.S | 12 +++++++-----
    2 files changed, 15 insertions(+), 5 deletions(-)

    diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
    index a2dc0add72ed..761fd69df6d9 100644
    --- a/arch/x86/kernel/head_64.S
    +++ b/arch/x86/kernel/head_64.S
    @@ -65,6 +65,9 @@ startup_64:
    * tables and then reload them.
    */

    + /* Sanitize CPU configuration */
    + call verify_cpu
    +
    /*
    * Compute the delta between the address I am compiled to run at and the
    * address I am actually running at.
    @@ -174,6 +177,9 @@ ENTRY(secondary_startup_64)
    * after the boot processor executes this code.
    */

    + /* Sanitize CPU configuration */
    + call verify_cpu
    +
    movq $(init_level4_pgt - __START_KERNEL_map), %rax
    1:

    @@ -288,6 +294,8 @@ ENTRY(secondary_startup_64)
    pushq %rax # target address in negative space
    lretq

    +#include "verify_cpu.S"
    +
    #ifdef CONFIG_HOTPLUG_CPU
    /*
    * Boot CPU0 entry point. It's called from play_dead(). Everything has been set
    diff --git a/arch/x86/kernel/verify_cpu.S b/arch/x86/kernel/verify_cpu.S
    index b9242bacbe59..4cf401f581e7 100644
    --- a/arch/x86/kernel/verify_cpu.S
    +++ b/arch/x86/kernel/verify_cpu.S
    @@ -34,10 +34,11 @@
    #include <asm/msr-index.h>

    verify_cpu:
    - pushfl # Save caller passed flags
    - pushl $0 # Kill any dangerous flags
    - popfl
    + pushf # Save caller passed flags
    + push $0 # Kill any dangerous flags
    + popf

    +#ifndef __x86_64__
    pushfl # standard way to check for cpuid
    popl %eax
    movl %eax,%ebx
    @@ -48,6 +49,7 @@ verify_cpu:
    popl %eax
    cmpl %eax,%ebx
    jz verify_cpu_no_longmode # cpu has no cpuid
    +#endif

    movl $0x0,%eax # See if cpuid 1 is implemented
    cpuid
    @@ -130,10 +132,10 @@ verify_cpu_sse_test:
    jmp verify_cpu_sse_test # try again

    verify_cpu_no_longmode:
    - popfl # Restore caller passed flags
    + popf # Restore caller passed flags
    movl $1,%eax
    ret
    verify_cpu_sse_ok:
    - popfl # Restore caller passed flags
    + popf # Restore caller passed flags
    xorl %eax, %eax
    ret

    \
     
     \ /
      Last update: 2015-12-09 11:41    [W:2.365 / U:0.512 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site