x86/idt: Switch early trap init to IDT tables
Add the initialization table for the early trap setup and replace the early trap init code. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Andy Lutomirski <luto@kernel.org> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.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> Cc: Steven Rostedt <rostedt@goodmis.org> Link: http://lkml.kernel.org/r/20170828064958.929139008@linutronix.de Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
Родитель
3318e97442
Коммит
433f8924fa
|
@ -48,6 +48,28 @@ struct idt_data {
|
|||
#define TSKG(_vector, _gdt) \
|
||||
G(_vector, NULL, DEFAULT_STACK, GATE_TASK, DPL0, _gdt << 3)
|
||||
|
||||
/*
|
||||
* Early traps running on the DEFAULT_STACK because the other interrupt
|
||||
* stacks work only after cpu_init().
|
||||
*/
|
||||
static const __initdata struct idt_data early_idts[] = {
|
||||
INTG(X86_TRAP_DB, debug),
|
||||
SYSG(X86_TRAP_BP, int3),
|
||||
#ifdef CONFIG_X86_32
|
||||
INTG(X86_TRAP_PF, page_fault),
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
/*
|
||||
* Early traps running on the DEFAULT_STACK because the other interrupt
|
||||
* stacks work only after cpu_init().
|
||||
*/
|
||||
static const __initdata struct idt_data early_pf_idts[] = {
|
||||
INTG(X86_TRAP_PF, page_fault),
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Must be page-aligned because the real IDT is used in a fixmap. */
|
||||
gate_desc idt_table[IDT_ENTRIES] __page_aligned_bss;
|
||||
|
||||
|
@ -92,6 +114,37 @@ idt_setup_from_table(gate_desc *idt, const struct idt_data *t, int size)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* idt_setup_early_traps - Initialize the idt table with early traps
|
||||
*
|
||||
* On X8664 these traps do not use interrupt stacks as they can't work
|
||||
* before cpu_init() is invoked and sets up TSS. The IST variants are
|
||||
* installed after that.
|
||||
*/
|
||||
void __init idt_setup_early_traps(void)
|
||||
{
|
||||
idt_setup_from_table(idt_table, early_idts, ARRAY_SIZE(early_idts));
|
||||
load_idt(&idt_descr);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
/**
|
||||
* idt_setup_early_pf - Initialize the idt table with early pagefault handler
|
||||
*
|
||||
* On X8664 this does not use interrupt stacks as they can't work before
|
||||
* cpu_init() is invoked and sets up TSS. The IST variant is installed
|
||||
* after that.
|
||||
*
|
||||
* FIXME: Why is 32bit and 64bit installing the PF handler at different
|
||||
* places in the early setup code?
|
||||
*/
|
||||
void __init idt_setup_early_pf(void)
|
||||
{
|
||||
idt_setup_from_table(idt_table, early_pf_idts,
|
||||
ARRAY_SIZE(early_pf_idts));
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* idt_setup_early_handler - Initializes the idt table with early handlers
|
||||
*/
|
||||
|
|
|
@ -891,7 +891,7 @@ void __init setup_arch(char **cmdline_p)
|
|||
*/
|
||||
olpc_ofw_detect();
|
||||
|
||||
early_trap_init();
|
||||
idt_setup_early_traps();
|
||||
early_cpu_init();
|
||||
early_ioremap_init();
|
||||
|
||||
|
@ -1162,7 +1162,7 @@ void __init setup_arch(char **cmdline_p)
|
|||
|
||||
init_mem_mapping();
|
||||
|
||||
early_trap_pf_init();
|
||||
idt_setup_early_pf();
|
||||
|
||||
/*
|
||||
* Update mmu_cr4_features (and, indirectly, trampoline_cr4_features)
|
||||
|
|
|
@ -923,33 +923,6 @@ dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Set of traps needed for early debugging. */
|
||||
void __init early_trap_init(void)
|
||||
{
|
||||
/*
|
||||
* Don't use IST to set DEBUG_STACK as it doesn't work until TSS
|
||||
* is ready in cpu_init() <-- trap_init(). Before trap_init(),
|
||||
* CPU runs at ring 0 so it is impossible to hit an invalid
|
||||
* stack. Using the original stack works well enough at this
|
||||
* early stage. DEBUG_STACK will be equipped after cpu_init() in
|
||||
* trap_init().
|
||||
*/
|
||||
set_intr_gate(X86_TRAP_DB, debug);
|
||||
/* int3 can be called from all */
|
||||
set_system_intr_gate(X86_TRAP_BP, &int3);
|
||||
#ifdef CONFIG_X86_32
|
||||
set_intr_gate(X86_TRAP_PF, page_fault);
|
||||
#endif
|
||||
load_idt(&idt_descr);
|
||||
}
|
||||
|
||||
void __init early_trap_pf_init(void)
|
||||
{
|
||||
#ifdef CONFIG_X86_64
|
||||
set_intr_gate(X86_TRAP_PF, page_fault);
|
||||
#endif
|
||||
}
|
||||
|
||||
void __init trap_init(void)
|
||||
{
|
||||
int i;
|
||||
|
|
Загрузка…
Ссылка в новой задаче