// SPDX-License-Identifier: GPL-2.0-only /* * Interrupt descriptor table related code */ #include <linux/interrupt.h> #include <asm/cpu_entry_area.h> #include <asm/set_memory.h> #include <asm/traps.h> #include <asm/proto.h> #include <asm/desc.h> #include <asm/hw_irq.h> #include <asm/ia32.h> #include <asm/idtentry.h> #define DPL0 … #define DPL3 … #define DEFAULT_STACK … #define G(_vector, _addr, _ist, _type, _dpl, _segment) … /* Interrupt gate */ #define INTG(_vector, _addr) … /* System interrupt gate */ #define SYSG(_vector, _addr) … #ifdef CONFIG_X86_64 /* * Interrupt gate with interrupt stack. The _ist index is the index in * the tss.ist[] array, but for the descriptor it needs to start at 1. */ #define ISTG(_vector, _addr, _ist) … #else #define ISTG … #endif /* Task gate */ #define TSKG(_vector, _gdt) … #define IDT_TABLE_SIZE … static bool idt_setup_done __initdata; /* * Early traps running on the DEFAULT_STACK because the other interrupt * stacks work only after cpu_init(). */ static const __initconst struct idt_data early_idts[] = …; /* * The default IDT entries which are set up in trap_init() before * cpu_init() is invoked. Interrupt stacks cannot be used at that point and * the traps which use them are reinitialized with IST after cpu_init() has * set up TSS. */ static const __initconst struct idt_data def_idts[] = …; static const struct idt_data ia32_idt[] __initconst = …; /* * The APIC and SMP idt entries */ static const __initconst struct idt_data apic_idts[] = …; /* Must be page-aligned because the real IDT is used in the cpu entry area */ static gate_desc idt_table[IDT_ENTRIES] __page_aligned_bss; static struct desc_ptr idt_descr __ro_after_init = …; void load_current_idt(void) { … } #ifdef CONFIG_X86_F00F_BUG bool idt_is_f00f_address(unsigned long address) { return ((address - idt_descr.address) >> 3) == 6; } #endif static __init void idt_setup_from_table(gate_desc *idt, const struct idt_data *t, int size, bool sys) { … } static __init void set_intr_gate(unsigned int n, const void *addr) { … } /** * 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_traps - Initialize the idt table with default traps */ void __init idt_setup_traps(void) { … } #ifdef CONFIG_X86_64 /* * Early traps running on the DEFAULT_STACK because the other interrupt * stacks work only after cpu_init(). */ static const __initconst struct idt_data early_pf_idts[] = …; /** * 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. * * Note, that X86_64 cannot install the real #PF handler in * idt_setup_early_traps() because the memory initialization needs the #PF * handler from the early_idt_handler_array to initialize the early page * tables. */ void __init idt_setup_early_pf(void) { … } #endif static void __init idt_map_in_cea(void) { … } /** * idt_setup_apic_and_irq_gates - Setup APIC/SMP and normal interrupt gates */ void __init idt_setup_apic_and_irq_gates(void) { … } /** * idt_setup_early_handler - Initializes the idt table with early handlers */ void __init idt_setup_early_handler(void) { … } /** * idt_invalidate - Invalidate interrupt descriptor table */ void idt_invalidate(void) { … } void __init idt_install_sysvec(unsigned int n, const void *function) { … }