Skip to content

Commit e5a0fc4

Browse files
committed
Merge tag 'x86-apic-2021-06-28' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 exception handling updates from Ingo Molnar: - Clean up & simplify AP exception handling setup. - Consolidate the disjoint IDT setup code living in idt_setup_traps() and idt_setup_ist_traps() into a single idt_setup_traps() initialization function and call it before cpu_init(). * tag 'x86-apic-2021-06-28' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/idt: Rework IDT setup for boot CPU x86/cpu: Init AP exception handling from cpu_init_secondary()
2 parents 9269d27 + 1dcc917 commit e5a0fc4

6 files changed

Lines changed: 32 additions & 51 deletions

File tree

arch/x86/include/asm/desc.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -421,10 +421,8 @@ extern bool idt_is_f00f_address(unsigned long address);
421421

422422
#ifdef CONFIG_X86_64
423423
extern void idt_setup_early_pf(void);
424-
extern void idt_setup_ist_traps(void);
425424
#else
426425
static inline void idt_setup_early_pf(void) { }
427-
static inline void idt_setup_ist_traps(void) { }
428426
#endif
429427

430428
extern void idt_invalidate(void *addr);

arch/x86/include/asm/processor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,7 @@ extern void load_direct_gdt(int);
663663
extern void load_fixmap_gdt(int);
664664
extern void load_percpu_segment(int);
665665
extern void cpu_init(void);
666+
extern void cpu_init_secondary(void);
666667
extern void cpu_init_exception_handling(void);
667668
extern void cr4_init(void);
668669

arch/x86/kernel/cpu/common.c

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1938,13 +1938,12 @@ void cpu_init_exception_handling(void)
19381938

19391939
/*
19401940
* cpu_init() initializes state that is per-CPU. Some data is already
1941-
* initialized (naturally) in the bootstrap process, such as the GDT
1942-
* and IDT. We reload them nevertheless, this function acts as a
1943-
* 'CPU state barrier', nothing should get across.
1941+
* initialized (naturally) in the bootstrap process, such as the GDT. We
1942+
* reload it nevertheless, this function acts as a 'CPU state barrier',
1943+
* nothing should get across.
19441944
*/
19451945
void cpu_init(void)
19461946
{
1947-
struct tss_struct *tss = this_cpu_ptr(&cpu_tss_rw);
19481947
struct task_struct *cur = current;
19491948
int cpu = raw_smp_processor_id();
19501949

@@ -1957,8 +1956,6 @@ void cpu_init(void)
19571956
early_cpu_to_node(cpu) != NUMA_NO_NODE)
19581957
set_numa_node(early_cpu_to_node(cpu));
19591958
#endif
1960-
setup_getcpu(cpu);
1961-
19621959
pr_debug("Initializing CPU#%d\n", cpu);
19631960

19641961
if (IS_ENABLED(CONFIG_X86_64) || cpu_feature_enabled(X86_FEATURE_VME) ||
@@ -1970,7 +1967,6 @@ void cpu_init(void)
19701967
* and set up the GDT descriptor:
19711968
*/
19721969
switch_to_new_gdt(cpu);
1973-
load_current_idt();
19741970

19751971
if (IS_ENABLED(CONFIG_X86_64)) {
19761972
loadsegment(fs, 0);
@@ -1990,12 +1986,6 @@ void cpu_init(void)
19901986
initialize_tlbstate_and_flush();
19911987
enter_lazy_tlb(&init_mm, cur);
19921988

1993-
/* Initialize the TSS. */
1994-
tss_setup_ist(tss);
1995-
tss_setup_io_bitmap(tss);
1996-
set_tss_desc(cpu, &get_cpu_entry_area(cpu)->tss.x86_tss);
1997-
1998-
load_TR_desc();
19991989
/*
20001990
* sp0 points to the entry trampoline stack regardless of what task
20011991
* is running.
@@ -2017,6 +2007,18 @@ void cpu_init(void)
20172007
load_fixmap_gdt(cpu);
20182008
}
20192009

2010+
#ifdef CONFIG_SMP
2011+
void cpu_init_secondary(void)
2012+
{
2013+
/*
2014+
* Relies on the BP having set-up the IDT tables, which are loaded
2015+
* on this CPU in cpu_init_exception_handling().
2016+
*/
2017+
cpu_init_exception_handling();
2018+
cpu_init();
2019+
}
2020+
#endif
2021+
20202022
/*
20212023
* The microcode loader calls this upon late microcode load to recheck features,
20222024
* only when microcode has been updated. Caller holds microcode_mutex and CPU

arch/x86/kernel/idt.c

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,16 @@
3535
#define SYSG(_vector, _addr) \
3636
G(_vector, _addr, DEFAULT_STACK, GATE_INTERRUPT, DPL3, __KERNEL_CS)
3737

38+
#ifdef CONFIG_X86_64
3839
/*
3940
* Interrupt gate with interrupt stack. The _ist index is the index in
4041
* the tss.ist[] array, but for the descriptor it needs to start at 1.
4142
*/
4243
#define ISTG(_vector, _addr, _ist) \
4344
G(_vector, _addr, _ist + 1, GATE_INTERRUPT, DPL0, __KERNEL_CS)
45+
#else
46+
#define ISTG(_vector, _addr, _ist) INTG(_vector, _addr)
47+
#endif
4448

4549
/* Task gate */
4650
#define TSKG(_vector, _gdt) \
@@ -74,7 +78,7 @@ static const __initconst struct idt_data early_idts[] = {
7478
*/
7579
static const __initconst struct idt_data def_idts[] = {
7680
INTG(X86_TRAP_DE, asm_exc_divide_error),
77-
INTG(X86_TRAP_NMI, asm_exc_nmi),
81+
ISTG(X86_TRAP_NMI, asm_exc_nmi, IST_INDEX_NMI),
7882
INTG(X86_TRAP_BR, asm_exc_bounds),
7983
INTG(X86_TRAP_UD, asm_exc_invalid_op),
8084
INTG(X86_TRAP_NM, asm_exc_device_not_available),
@@ -91,12 +95,16 @@ static const __initconst struct idt_data def_idts[] = {
9195
#ifdef CONFIG_X86_32
9296
TSKG(X86_TRAP_DF, GDT_ENTRY_DOUBLEFAULT_TSS),
9397
#else
94-
INTG(X86_TRAP_DF, asm_exc_double_fault),
98+
ISTG(X86_TRAP_DF, asm_exc_double_fault, IST_INDEX_DF),
9599
#endif
96-
INTG(X86_TRAP_DB, asm_exc_debug),
100+
ISTG(X86_TRAP_DB, asm_exc_debug, IST_INDEX_DB),
97101

98102
#ifdef CONFIG_X86_MCE
99-
INTG(X86_TRAP_MC, asm_exc_machine_check),
103+
ISTG(X86_TRAP_MC, asm_exc_machine_check, IST_INDEX_MCE),
104+
#endif
105+
106+
#ifdef CONFIG_AMD_MEM_ENCRYPT
107+
ISTG(X86_TRAP_VC, asm_exc_vmm_communication, IST_INDEX_VC),
100108
#endif
101109

102110
SYSG(X86_TRAP_OF, asm_exc_overflow),
@@ -221,22 +229,6 @@ static const __initconst struct idt_data early_pf_idts[] = {
221229
INTG(X86_TRAP_PF, asm_exc_page_fault),
222230
};
223231

224-
/*
225-
* The exceptions which use Interrupt stacks. They are setup after
226-
* cpu_init() when the TSS has been initialized.
227-
*/
228-
static const __initconst struct idt_data ist_idts[] = {
229-
ISTG(X86_TRAP_DB, asm_exc_debug, IST_INDEX_DB),
230-
ISTG(X86_TRAP_NMI, asm_exc_nmi, IST_INDEX_NMI),
231-
ISTG(X86_TRAP_DF, asm_exc_double_fault, IST_INDEX_DF),
232-
#ifdef CONFIG_X86_MCE
233-
ISTG(X86_TRAP_MC, asm_exc_machine_check, IST_INDEX_MCE),
234-
#endif
235-
#ifdef CONFIG_AMD_MEM_ENCRYPT
236-
ISTG(X86_TRAP_VC, asm_exc_vmm_communication, IST_INDEX_VC),
237-
#endif
238-
};
239-
240232
/**
241233
* idt_setup_early_pf - Initialize the idt table with early pagefault handler
242234
*
@@ -254,14 +246,6 @@ void __init idt_setup_early_pf(void)
254246
idt_setup_from_table(idt_table, early_pf_idts,
255247
ARRAY_SIZE(early_pf_idts), true);
256248
}
257-
258-
/**
259-
* idt_setup_ist_traps - Initialize the idt table with traps using IST
260-
*/
261-
void __init idt_setup_ist_traps(void)
262-
{
263-
idt_setup_from_table(idt_table, ist_idts, ARRAY_SIZE(ist_idts), true);
264-
}
265249
#endif
266250

267251
static void __init idt_map_in_cea(void)

arch/x86/kernel/smpboot.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,8 +232,7 @@ static void notrace start_secondary(void *unused)
232232
load_cr3(swapper_pg_dir);
233233
__flush_tlb_all();
234234
#endif
235-
cpu_init_exception_handling();
236-
cpu_init();
235+
cpu_init_secondary();
237236
rcu_cpu_starting(raw_smp_processor_id());
238237
x86_cpuinit.early_percpu_clock_init();
239238
smp_callin();

arch/x86/kernel/traps.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,12 +1160,9 @@ void __init trap_init(void)
11601160
/* Init GHCB memory pages when running as an SEV-ES guest */
11611161
sev_es_init_vc_handling();
11621162

1163+
/* Initialize TSS before setting up traps so ISTs work */
1164+
cpu_init_exception_handling();
1165+
/* Setup traps as cpu_init() might #GP */
11631166
idt_setup_traps();
1164-
1165-
/*
1166-
* Should be a barrier for any external CPU state:
1167-
*/
11681167
cpu_init();
1169-
1170-
idt_setup_ist_traps();
11711168
}

0 commit comments

Comments
 (0)