lkml.org 
[lkml]   [2017]   [Nov]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 09/43] x86/entry: Move SYSENTER_stack to the beginning of struct tss_struct
    Date
    From: Andy Lutomirski <luto@kernel.org>

    SYSENTER_stack should have reliable overflow detection, which
    means that it needs to be at the bottom of a page, not the top.
    Move it to the beginning of struct tss_struct and page-align it.

    Also add an assertion to make sure that the fixed hardware TSS
    doesn't cross a page boundary.

    Signed-off-by: Andy Lutomirski <luto@kernel.org>
    Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
    Cc: Borislav Petkov <bp@alien8.de>
    Cc: Borislav Petkov <bpetkov@suse.de>
    Cc: Brian Gerst <brgerst@gmail.com>
    Cc: Dave Hansen <dave.hansen@intel.com>
    Cc: Denys Vlasenko <dvlasenk@redhat.com>
    Cc: H. Peter Anvin <hpa@zytor.com>
    Cc: Josh Poimboeuf <jpoimboe@redhat.com>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Link: http://lkml.kernel.org/r/8de9901e7c3a6aa8fac95b37b9c7b96f1900f11a.1511497875.git.luto@kernel.org
    Signed-off-by: Ingo Molnar <mingo@kernel.org>
    ---
    arch/x86/include/asm/processor.h | 21 ++++++++++++---------
    arch/x86/kernel/cpu/common.c | 21 +++++++++++++++++++++
    2 files changed, 33 insertions(+), 9 deletions(-)

    diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
    index c24456429c7d..48d44fae3d27 100644
    --- a/arch/x86/include/asm/processor.h
    +++ b/arch/x86/include/asm/processor.h
    @@ -328,7 +328,16 @@ struct x86_hw_tss {

    struct tss_struct {
    /*
    - * The hardware state:
    + * Space for the temporary SYSENTER stack, used for SYSENTER
    + * and the entry trampoline as well.
    + */
    + unsigned long SYSENTER_stack_canary;
    + unsigned long SYSENTER_stack[64];
    +
    + /*
    + * The fixed hardware portion. This must not cross a page boundary
    + * at risk of violating the SDM's advice and potentially triggering
    + * errata.
    */
    struct x86_hw_tss x86_tss;

    @@ -339,15 +348,9 @@ struct tss_struct {
    * be within the limit.
    */
    unsigned long io_bitmap[IO_BITMAP_LONGS + 1];
    +} __aligned(PAGE_SIZE);

    - /*
    - * Space for the temporary SYSENTER stack.
    - */
    - unsigned long SYSENTER_stack_canary;
    - unsigned long SYSENTER_stack[64];
    -} ____cacheline_aligned;
    -
    -DECLARE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss);
    +DECLARE_PER_CPU_PAGE_ALIGNED(struct tss_struct, cpu_tss);

    /*
    * sizeof(unsigned long) coming from an extra "long" at the end
    diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
    index 62cdc10a7d94..d173f6013467 100644
    --- a/arch/x86/kernel/cpu/common.c
    +++ b/arch/x86/kernel/cpu/common.c
    @@ -511,6 +511,27 @@ static inline void setup_cpu_entry_area(int cpu)
    #endif

    __set_fixmap(get_cpu_entry_area_index(cpu, gdt), get_cpu_gdt_paddr(cpu), gdt_prot);
    +
    + /*
    + * The Intel SDM says (Volume 3, 7.2.1):
    + *
    + * Avoid placing a page boundary in the part of the TSS that the
    + * processor reads during a task switch (the first 104 bytes). The
    + * processor may not correctly perform address translations if a
    + * boundary occurs in this area. During a task switch, the processor
    + * reads and writes into the first 104 bytes of each TSS (using
    + * contiguous physical addresses beginning with the physical address
    + * of the first byte of the TSS). So, after TSS access begins, if
    + * part of the 104 bytes is not physically contiguous, the processor
    + * will access incorrect information without generating a page-fault
    + * exception.
    + *
    + * There are also a lot of errata involving the TSS spanning a page
    + * boundary. Assert that we're not doing that.
    + */
    + BUILD_BUG_ON((offsetof(struct tss_struct, x86_tss) ^
    + offsetofend(struct tss_struct, x86_tss)) & PAGE_MASK);
    +
    }

    /* Load the original GDT from the per-cpu structure */
    --
    2.14.1
    \
     
     \ /
      Last update: 2017-11-24 10:26    [W:2.664 / U:0.364 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site