Skip to content

Commit 520d030

Browse files
joergroedelsuryasaimadhu
authored andcommitted
x86/smpboot: Load TSS and getcpu GDT entry before loading IDT
The IDT on 64-bit 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> Signed-off-by: Borislav Petkov <bp@suse.de> Link: https://lkml.kernel.org/r/20200907131613.12703-68-joro@8bytes.org
1 parent 8940ac9 commit 520d030

3 files changed

Lines changed: 25 additions & 1 deletion

File tree

arch/x86/include/asm/processor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,7 @@ extern void load_direct_gdt(int);
696696
extern void load_fixmap_gdt(int);
697697
extern void load_percpu_segment(int);
698698
extern void cpu_init(void);
699+
extern void cpu_init_exception_handling(void);
699700
extern void cr4_init(void);
700701

701702
static inline unsigned long get_debugctlmsr(void)

arch/x86/kernel/cpu/common.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1862,6 +1862,29 @@ static inline void tss_setup_io_bitmap(struct tss_struct *tss)
18621862
#endif
18631863
}
18641864

1865+
/*
1866+
* Setup everything needed to handle exceptions from the IDT, including the IST
1867+
* exceptions which use paranoid_entry().
1868+
*/
1869+
void cpu_init_exception_handling(void)
1870+
{
1871+
struct tss_struct *tss = this_cpu_ptr(&cpu_tss_rw);
1872+
int cpu = raw_smp_processor_id();
1873+
1874+
/* paranoid_entry() gets the CPU number from the GDT */
1875+
setup_getcpu(cpu);
1876+
1877+
/* IST vectors need TSS to be set up. */
1878+
tss_setup_ist(tss);
1879+
tss_setup_io_bitmap(tss);
1880+
set_tss_desc(cpu, &get_cpu_entry_area(cpu)->tss.x86_tss);
1881+
1882+
load_TR_desc();
1883+
1884+
/* Finally load the IDT */
1885+
load_current_idt();
1886+
}
1887+
18651888
/*
18661889
* cpu_init() initializes state that is per-CPU. Some data is already
18671890
* initialized (naturally) in the bootstrap process, such as the GDT

arch/x86/kernel/smpboot.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ static void notrace start_secondary(void *unused)
227227
load_cr3(swapper_pg_dir);
228228
__flush_tlb_all();
229229
#endif
230-
load_current_idt();
230+
cpu_init_exception_handling();
231231
cpu_init();
232232
x86_cpuinit.early_percpu_clock_init();
233233
preempt_disable();

0 commit comments

Comments
 (0)