lkml.org 
[lkml]   [2017]   [Nov]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 07/18] x86/asm: Fix assumptions that the HW TSS is at the beginning of cpu_tss
    Date
    I'm going to move SYSENTER_stack to the beginning of cpu_tss to help
    detect overflow. Before this can happen, I need to fix several code
    paths that hardcode assumptions about the old layout.

    Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
    Signed-off-by: Andy Lutomirski <luto@kernel.org>
    ---
    arch/x86/include/asm/desc.h | 2 +-
    arch/x86/include/asm/processor.h | 4 ++--
    arch/x86/kernel/cpu/common.c | 8 ++++----
    arch/x86/kernel/doublefault.c | 36 +++++++++++++++++-------------------
    arch/x86/power/cpu.c | 13 +++++++------
    5 files changed, 31 insertions(+), 32 deletions(-)

    diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
    index 194ffab00ebe..aab4fe9f49f8 100644
    --- a/arch/x86/include/asm/desc.h
    +++ b/arch/x86/include/asm/desc.h
    @@ -178,7 +178,7 @@ static inline void set_tssldt_descriptor(void *d, unsigned long addr,
    #endif
    }

    -static inline void __set_tss_desc(unsigned cpu, unsigned int entry, void *addr)
    +static inline void __set_tss_desc(unsigned cpu, unsigned int entry, struct x86_hw_tss *addr)
    {
    struct desc_struct *d = get_cpu_gdt_rw(cpu);
    tss_desc tss;
    diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
    index 789dad5da20f..d32a3c88a968 100644
    --- a/arch/x86/include/asm/processor.h
    +++ b/arch/x86/include/asm/processor.h
    @@ -162,7 +162,7 @@ enum cpuid_regs_idx {
    extern struct cpuinfo_x86 boot_cpu_data;
    extern struct cpuinfo_x86 new_cpu_data;

    -extern struct tss_struct doublefault_tss;
    +extern struct x86_hw_tss doublefault_tss;
    extern __u32 cpu_caps_cleared[NCAPINTS];
    extern __u32 cpu_caps_set[NCAPINTS];

    @@ -322,7 +322,7 @@ struct x86_hw_tss {
    #define IO_BITMAP_BITS 65536
    #define IO_BITMAP_BYTES (IO_BITMAP_BITS/8)
    #define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long))
    -#define IO_BITMAP_OFFSET offsetof(struct tss_struct, io_bitmap)
    +#define IO_BITMAP_OFFSET (offsetof(struct tss_struct, io_bitmap) - offsetof(struct tss_struct, x86_tss))
    #define INVALID_IO_BITMAP_OFFSET 0x8000

    struct tss_struct {
    diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
    index 1e0843d15e64..099fca92f6be 100644
    --- a/arch/x86/kernel/cpu/common.c
    +++ b/arch/x86/kernel/cpu/common.c
    @@ -1580,7 +1580,7 @@ void cpu_init(void)
    }
    }

    - t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap);
    + t->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET;

    /*
    * <= is required because the CPU will access up to
    @@ -1599,7 +1599,7 @@ void cpu_init(void)
    * Initialize the TSS. Don't bother initializing sp0, as the initial
    * task never enters user mode.
    */
    - set_tss_desc(cpu, t);
    + set_tss_desc(cpu, &t->x86_tss);
    load_TR_desc();

    load_mm_ldt(&init_mm);
    @@ -1657,12 +1657,12 @@ void cpu_init(void)
    * Initialize the TSS. Don't bother initializing sp0, as the initial
    * task never enters user mode.
    */
    - set_tss_desc(cpu, t);
    + set_tss_desc(cpu, &t->x86_tss);
    load_TR_desc();

    load_mm_ldt(&init_mm);

    - t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap);
    + t->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET;

    #ifdef CONFIG_DOUBLEFAULT
    /* Set up doublefault TSS pointer in the GDT */
    diff --git a/arch/x86/kernel/doublefault.c b/arch/x86/kernel/doublefault.c
    index 0e662c55ae90..0b8cedb20d6d 100644
    --- a/arch/x86/kernel/doublefault.c
    +++ b/arch/x86/kernel/doublefault.c
    @@ -50,25 +50,23 @@ static void doublefault_fn(void)
    cpu_relax();
    }

    -struct tss_struct doublefault_tss __cacheline_aligned = {
    - .x86_tss = {
    - .sp0 = STACK_START,
    - .ss0 = __KERNEL_DS,
    - .ldt = 0,
    - .io_bitmap_base = INVALID_IO_BITMAP_OFFSET,
    -
    - .ip = (unsigned long) doublefault_fn,
    - /* 0x2 bit is always set */
    - .flags = X86_EFLAGS_SF | 0x2,
    - .sp = STACK_START,
    - .es = __USER_DS,
    - .cs = __KERNEL_CS,
    - .ss = __KERNEL_DS,
    - .ds = __USER_DS,
    - .fs = __KERNEL_PERCPU,
    -
    - .__cr3 = __pa_nodebug(swapper_pg_dir),
    - }
    +struct x86_hw_tss doublefault_tss __cacheline_aligned = {
    + .sp0 = STACK_START,
    + .ss0 = __KERNEL_DS,
    + .ldt = 0,
    + .io_bitmap_base = INVALID_IO_BITMAP_OFFSET,
    +
    + .ip = (unsigned long) doublefault_fn,
    + /* 0x2 bit is always set */
    + .flags = X86_EFLAGS_SF | 0x2,
    + .sp = STACK_START,
    + .es = __USER_DS,
    + .cs = __KERNEL_CS,
    + .ss = __KERNEL_DS,
    + .ds = __USER_DS,
    + .fs = __KERNEL_PERCPU,
    +
    + .__cr3 = __pa_nodebug(swapper_pg_dir),
    };

    /* dummy for do_double_fault() call */
    diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
    index 84fcfde53f8f..50593e138281 100644
    --- a/arch/x86/power/cpu.c
    +++ b/arch/x86/power/cpu.c
    @@ -165,12 +165,13 @@ static void fix_processor_context(void)
    struct desc_struct *desc = get_cpu_gdt_rw(cpu);
    tss_desc tss;
    #endif
    - set_tss_desc(cpu, t); /*
    - * This just modifies memory; should not be
    - * necessary. But... This is necessary, because
    - * 386 hardware has concept of busy TSS or some
    - * similar stupidity.
    - */
    +
    + /*
    + * This just modifies memory; should not be necessary. But... This is
    + * necessary, because 386 hardware has concept of busy TSS or some
    + * similar stupidity.
    + */
    + set_tss_desc(cpu, &t->x86_tss);

    #ifdef CONFIG_X86_64
    memcpy(&tss, &desc[GDT_ENTRY_TSS], sizeof(tss_desc));
    --
    2.13.6
    \
     
     \ /
      Last update: 2017-11-22 05:48    [W:4.044 / U:0.284 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site