Skip to content

Commit

Permalink
x86/idt: Switch early trap init to IDT tables
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Thomas Gleixner authored and Ingo Molnar committed Aug 29, 2017
1 parent 3318e97 commit 433f892
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 29 deletions.
53 changes: 53 additions & 0 deletions arch/x86/kernel/idt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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
*/
Expand Down
4 changes: 2 additions & 2 deletions arch/x86/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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)
Expand Down
27 changes: 0 additions & 27 deletions arch/x86/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 433f892

Please sign in to comment.