lkml.org 
[lkml]   [2020]   [Sep]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v7 67/72] x86/smpboot: Load TSS and getcpu GDT entry before loading IDT
    Date
    From: Joerg Roedel <jroedel@suse.de>

    The IDT on 64bit contains vectors which use paranoid_entry() and/or IST
    stacks. To make these vectors work the TSS and the getcpu GDT entry need
    to be set up before the IDT is loaded.

    Signed-off-by: Joerg Roedel <jroedel@suse.de>
    ---
    arch/x86/include/asm/processor.h | 1 +
    arch/x86/kernel/cpu/common.c | 23 +++++++++++++++++++++++
    arch/x86/kernel/smpboot.c | 2 +-
    3 files changed, 25 insertions(+), 1 deletion(-)

    diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
    index d8a82e650810..5ac507586769 100644
    --- a/arch/x86/include/asm/processor.h
    +++ b/arch/x86/include/asm/processor.h
    @@ -696,6 +696,7 @@ extern void load_direct_gdt(int);
    extern void load_fixmap_gdt(int);
    extern void load_percpu_segment(int);
    extern void cpu_init(void);
    +extern void cpu_init_exception_handling(void);
    extern void cr4_init(void);

    static inline unsigned long get_debugctlmsr(void)
    diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
    index 1d65365363a1..a9527c0c38fb 100644
    --- a/arch/x86/kernel/cpu/common.c
    +++ b/arch/x86/kernel/cpu/common.c
    @@ -1854,6 +1854,29 @@ static inline void tss_setup_io_bitmap(struct tss_struct *tss)
    #endif
    }

    +/*
    + * Setup everything needed to handle exceptions from the IDT, including the IST
    + * exceptions which use paranoid_entry()
    + */
    +void cpu_init_exception_handling(void)
    +{
    + struct tss_struct *tss = this_cpu_ptr(&cpu_tss_rw);
    + int cpu = raw_smp_processor_id();
    +
    + /* paranoid_entry() gets the CPU number from the GDT */
    + setup_getcpu(cpu);
    +
    + /* IST vectors need TSS to be set up. */
    + tss_setup_ist(tss);
    + tss_setup_io_bitmap(tss);
    + set_tss_desc(cpu, &get_cpu_entry_area(cpu)->tss.x86_tss);
    +
    + load_TR_desc();
    +
    + /* Finally load the IDT */
    + load_current_idt();
    +}
    +
    /*
    * cpu_init() initializes state that is per-CPU. Some data is already
    * initialized (naturally) in the bootstrap process, such as the GDT
    diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
    index f5ef689dd62a..de776b2e6046 100644
    --- a/arch/x86/kernel/smpboot.c
    +++ b/arch/x86/kernel/smpboot.c
    @@ -227,7 +227,7 @@ static void notrace start_secondary(void *unused)
    load_cr3(swapper_pg_dir);
    __flush_tlb_all();
    #endif
    - load_current_idt();
    + cpu_init_exception_handling();
    cpu_init();
    x86_cpuinit.early_percpu_clock_init();
    preempt_disable();
    --
    2.28.0
    \
     
     \ /
      Last update: 2020-09-07 19:31    [W:2.517 / U:2.224 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site