#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) \
G(_vector, _addr, _ist + 1, GATE_INTERRUPT, DPL0, __KERNEL_CS) #else #define ISTG(_vector, _addr, _ist) INTG(_vector, _addr) #endif
/* * Early traps running on the DEFAULT_STACK because the other interrupt * stacks work only after cpu_init().
*/ staticconst __initconst struct idt_data early_idts[] = {
INTG(X86_TRAP_DB, asm_exc_debug),
SYSG(X86_TRAP_BP, asm_exc_int3),
#ifdef CONFIG_X86_32 /* * Not possible on 64-bit. See idt_setup_early_pf() for details.
*/
INTG(X86_TRAP_PF, asm_exc_page_fault), #endif #ifdef CONFIG_INTEL_TDX_GUEST
INTG(X86_TRAP_VE, asm_exc_virtualization_exception), #endif
};
/* * 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.
*/ staticconst __initconst struct idt_data def_idts[] = {
INTG(X86_TRAP_DE, asm_exc_divide_error),
ISTG(X86_TRAP_NMI, asm_exc_nmi, IST_INDEX_NMI),
INTG(X86_TRAP_BR, asm_exc_bounds),
INTG(X86_TRAP_UD, asm_exc_invalid_op),
INTG(X86_TRAP_NM, asm_exc_device_not_available),
INTG(X86_TRAP_OLD_MF, asm_exc_coproc_segment_overrun),
INTG(X86_TRAP_TS, asm_exc_invalid_tss),
INTG(X86_TRAP_NP, asm_exc_segment_not_present),
INTG(X86_TRAP_SS, asm_exc_stack_segment),
INTG(X86_TRAP_GP, asm_exc_general_protection),
INTG(X86_TRAP_SPURIOUS, asm_exc_spurious_interrupt_bug),
INTG(X86_TRAP_MF, asm_exc_coprocessor_error),
INTG(X86_TRAP_AC, asm_exc_alignment_check),
INTG(X86_TRAP_XF, asm_exc_simd_coprocessor_error),
/** * 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), true);
load_idt(&idt_descr);
}
/** * idt_setup_traps - Initialize the idt table with default traps
*/ void __init idt_setup_traps(void)
{
idt_setup_from_table(idt_table, def_idts, ARRAY_SIZE(def_idts), true);
if (ia32_enabled())
idt_setup_from_table(idt_table, ia32_idt, ARRAY_SIZE(ia32_idt), true);
}
#ifdef CONFIG_X86_64 /* * Early traps running on the DEFAULT_STACK because the other interrupt * stacks work only after cpu_init().
*/ staticconst __initconst struct idt_data early_pf_idts[] = {
INTG(X86_TRAP_PF, asm_exc_page_fault),
};
/** * 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)
{
idt_setup_from_table(idt_table, early_pf_idts,
ARRAY_SIZE(early_pf_idts), true);
} #endif
staticvoid __init idt_map_in_cea(void)
{ /* * Set the IDT descriptor to a fixed read-only location in the cpu * entry area, so that the "sidt" instruction will not leak the * location of the kernel, and to defend the IDT against arbitrary * memory write vulnerabilities.
*/
cea_set_pte(CPU_ENTRY_AREA_RO_IDT_VADDR, __pa_symbol(idt_table),
PAGE_KERNEL_RO);
idt_descr.address = CPU_ENTRY_AREA_RO_IDT;
}
/** * idt_setup_apic_and_irq_gates - Setup APIC/SMP and normal interrupt gates
*/ void __init idt_setup_apic_and_irq_gates(void)
{ int i = FIRST_EXTERNAL_VECTOR; void *entry;
#ifdef CONFIG_X86_LOCAL_APIC
for_each_clear_bit_from(i, system_vectors, NR_VECTORS) { /* * Don't set the non assigned system vectors in the * system_vectors bitmap. Otherwise they show up in * /proc/interrupts.
*/
entry = spurious_entries_start + IDT_ALIGN * (i - FIRST_SYSTEM_VECTOR);
set_intr_gate(i, entry);
} #endif /* Map IDT into CPU entry area and reload it. */
idt_map_in_cea();
load_idt(&idt_descr);
/* Make the IDT table read only */
set_memory_ro((unsignedlong)&idt_table, 1);
idt_setup_done = true;
}
/** * idt_setup_early_handler - Initializes the idt table with early handlers
*/ void __init idt_setup_early_handler(void)
{ int i;
for (i = 0; i < NUM_EXCEPTION_VECTORS; i++)
set_intr_gate(i, early_idt_handler_array[i]); #ifdef CONFIG_X86_32 for ( ; i < NR_VECTORS; i++)
set_intr_gate(i, early_ignore_irq); #endif
load_idt(&idt_descr);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.