1 /* 2 * Interrupt descriptor table related code 3 * 4 * This file is licensed under the GPL V2 5 */ 6 #include <linux/interrupt.h> 7 8 #include <asm/traps.h> 9 #include <asm/proto.h> 10 #include <asm/desc.h> 11 12 struct idt_data { 13 unsigned int vector; 14 unsigned int segment; 15 struct idt_bits bits; 16 const void *addr; 17 }; 18 19 #define DPL0 0x0 20 #define DPL3 0x3 21 22 #define DEFAULT_STACK 0 23 24 #define G(_vector, _addr, _ist, _type, _dpl, _segment) \ 25 { \ 26 .vector = _vector, \ 27 .bits.ist = _ist, \ 28 .bits.type = _type, \ 29 .bits.dpl = _dpl, \ 30 .bits.p = 1, \ 31 .addr = _addr, \ 32 .segment = _segment, \ 33 } 34 35 /* Interrupt gate */ 36 #define INTG(_vector, _addr) \ 37 G(_vector, _addr, DEFAULT_STACK, GATE_INTERRUPT, DPL0, __KERNEL_CS) 38 39 /* System interrupt gate */ 40 #define SYSG(_vector, _addr) \ 41 G(_vector, _addr, DEFAULT_STACK, GATE_INTERRUPT, DPL3, __KERNEL_CS) 42 43 /* Interrupt gate with interrupt stack */ 44 #define ISTG(_vector, _addr, _ist) \ 45 G(_vector, _addr, _ist, GATE_INTERRUPT, DPL0, __KERNEL_CS) 46 47 /* Task gate */ 48 #define TSKG(_vector, _gdt) \ 49 G(_vector, NULL, DEFAULT_STACK, GATE_TASK, DPL0, _gdt << 3) 50 51 /* 52 * Early traps running on the DEFAULT_STACK because the other interrupt 53 * stacks work only after cpu_init(). 54 */ 55 static const __initdata struct idt_data early_idts[] = { 56 INTG(X86_TRAP_DB, debug), 57 SYSG(X86_TRAP_BP, int3), 58 #ifdef CONFIG_X86_32 59 INTG(X86_TRAP_PF, page_fault), 60 #endif 61 }; 62 63 /* 64 * The default IDT entries which are set up in trap_init() before 65 * cpu_init() is invoked. Interrupt stacks cannot be used at that point and 66 * the traps which use them are reinitialized with IST after cpu_init() has 67 * set up TSS. 68 */ 69 static const __initdata struct idt_data def_idts[] = { 70 INTG(X86_TRAP_DE, divide_error), 71 INTG(X86_TRAP_NMI, nmi), 72 INTG(X86_TRAP_BR, bounds), 73 INTG(X86_TRAP_UD, invalid_op), 74 INTG(X86_TRAP_NM, device_not_available), 75 INTG(X86_TRAP_OLD_MF, coprocessor_segment_overrun), 76 INTG(X86_TRAP_TS, invalid_TSS), 77 INTG(X86_TRAP_NP, segment_not_present), 78 INTG(X86_TRAP_SS, stack_segment), 79 INTG(X86_TRAP_GP, general_protection), 80 INTG(X86_TRAP_SPURIOUS, spurious_interrupt_bug), 81 INTG(X86_TRAP_MF, coprocessor_error), 82 INTG(X86_TRAP_AC, alignment_check), 83 INTG(X86_TRAP_XF, simd_coprocessor_error), 84 85 #ifdef CONFIG_X86_32 86 TSKG(X86_TRAP_DF, GDT_ENTRY_DOUBLEFAULT_TSS), 87 #else 88 INTG(X86_TRAP_DF, double_fault), 89 #endif 90 INTG(X86_TRAP_DB, debug), 91 INTG(X86_TRAP_NMI, nmi), 92 INTG(X86_TRAP_BP, int3), 93 94 #ifdef CONFIG_X86_MCE 95 INTG(X86_TRAP_MC, &machine_check), 96 #endif 97 98 SYSG(X86_TRAP_OF, overflow), 99 #if defined(CONFIG_IA32_EMULATION) 100 SYSG(IA32_SYSCALL_VECTOR, entry_INT80_compat), 101 #elif defined(CONFIG_X86_32) 102 SYSG(IA32_SYSCALL_VECTOR, entry_INT80_32), 103 #endif 104 }; 105 106 /* 107 * The APIC and SMP idt entries 108 */ 109 static const __initdata struct idt_data apic_idts[] = { 110 #ifdef CONFIG_SMP 111 INTG(RESCHEDULE_VECTOR, reschedule_interrupt), 112 INTG(CALL_FUNCTION_VECTOR, call_function_interrupt), 113 INTG(CALL_FUNCTION_SINGLE_VECTOR, call_function_single_interrupt), 114 INTG(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt), 115 INTG(REBOOT_VECTOR, reboot_interrupt), 116 #endif 117 118 #ifdef CONFIG_X86_THERMAL_VECTOR 119 INTG(THERMAL_APIC_VECTOR, thermal_interrupt), 120 #endif 121 122 #ifdef CONFIG_X86_MCE_THRESHOLD 123 INTG(THRESHOLD_APIC_VECTOR, threshold_interrupt), 124 #endif 125 126 #ifdef CONFIG_X86_MCE_AMD 127 INTG(DEFERRED_ERROR_VECTOR, deferred_error_interrupt), 128 #endif 129 130 #ifdef CONFIG_X86_LOCAL_APIC 131 INTG(LOCAL_TIMER_VECTOR, apic_timer_interrupt), 132 INTG(X86_PLATFORM_IPI_VECTOR, x86_platform_ipi), 133 # ifdef CONFIG_HAVE_KVM 134 INTG(POSTED_INTR_VECTOR, kvm_posted_intr_ipi), 135 INTG(POSTED_INTR_WAKEUP_VECTOR, kvm_posted_intr_wakeup_ipi), 136 INTG(POSTED_INTR_NESTED_VECTOR, kvm_posted_intr_nested_ipi), 137 # endif 138 # ifdef CONFIG_IRQ_WORK 139 INTG(IRQ_WORK_VECTOR, irq_work_interrupt), 140 # endif 141 INTG(SPURIOUS_APIC_VECTOR, spurious_interrupt), 142 INTG(ERROR_APIC_VECTOR, error_interrupt), 143 #endif 144 }; 145 146 #ifdef CONFIG_X86_64 147 /* 148 * Early traps running on the DEFAULT_STACK because the other interrupt 149 * stacks work only after cpu_init(). 150 */ 151 static const __initdata struct idt_data early_pf_idts[] = { 152 INTG(X86_TRAP_PF, page_fault), 153 }; 154 155 /* 156 * Override for the debug_idt. Same as the default, but with interrupt 157 * stack set to DEFAULT_STACK (0). Required for NMI trap handling. 158 */ 159 static const __initdata struct idt_data dbg_idts[] = { 160 INTG(X86_TRAP_DB, debug), 161 INTG(X86_TRAP_BP, int3), 162 }; 163 #endif 164 165 /* Must be page-aligned because the real IDT is used in a fixmap. */ 166 gate_desc idt_table[IDT_ENTRIES] __page_aligned_bss; 167 168 struct desc_ptr idt_descr __ro_after_init = { 169 .size = (IDT_ENTRIES * 2 * sizeof(unsigned long)) - 1, 170 .address = (unsigned long) idt_table, 171 }; 172 173 #ifdef CONFIG_X86_64 174 /* No need to be aligned, but done to keep all IDTs defined the same way. */ 175 gate_desc debug_idt_table[IDT_ENTRIES] __page_aligned_bss; 176 177 /* 178 * The exceptions which use Interrupt stacks. They are setup after 179 * cpu_init() when the TSS has been initialized. 180 */ 181 static const __initdata struct idt_data ist_idts[] = { 182 ISTG(X86_TRAP_DB, debug, DEBUG_STACK), 183 ISTG(X86_TRAP_NMI, nmi, NMI_STACK), 184 ISTG(X86_TRAP_BP, int3, DEBUG_STACK), 185 ISTG(X86_TRAP_DF, double_fault, DOUBLEFAULT_STACK), 186 #ifdef CONFIG_X86_MCE 187 ISTG(X86_TRAP_MC, &machine_check, MCE_STACK), 188 #endif 189 }; 190 191 /* 192 * Override for the debug_idt. Same as the default, but with interrupt 193 * stack set to DEFAULT_STACK (0). Required for NMI trap handling. 194 */ 195 const struct desc_ptr debug_idt_descr = { 196 .size = IDT_ENTRIES * 16 - 1, 197 .address = (unsigned long) debug_idt_table, 198 }; 199 #endif 200 201 static inline void idt_init_desc(gate_desc *gate, const struct idt_data *d) 202 { 203 unsigned long addr = (unsigned long) d->addr; 204 205 gate->offset_low = (u16) addr; 206 gate->segment = (u16) d->segment; 207 gate->bits = d->bits; 208 gate->offset_middle = (u16) (addr >> 16); 209 #ifdef CONFIG_X86_64 210 gate->offset_high = (u32) (addr >> 32); 211 gate->reserved = 0; 212 #endif 213 } 214 215 static __init void 216 idt_setup_from_table(gate_desc *idt, const struct idt_data *t, int size) 217 { 218 gate_desc desc; 219 220 for (; size > 0; t++, size--) { 221 idt_init_desc(&desc, t); 222 set_bit(t->vector, used_vectors); 223 write_idt_entry(idt, t->vector, &desc); 224 } 225 } 226 227 /** 228 * idt_setup_early_traps - Initialize the idt table with early traps 229 * 230 * On X8664 these traps do not use interrupt stacks as they can't work 231 * before cpu_init() is invoked and sets up TSS. The IST variants are 232 * installed after that. 233 */ 234 void __init idt_setup_early_traps(void) 235 { 236 idt_setup_from_table(idt_table, early_idts, ARRAY_SIZE(early_idts)); 237 load_idt(&idt_descr); 238 } 239 240 /** 241 * idt_setup_traps - Initialize the idt table with default traps 242 */ 243 void __init idt_setup_traps(void) 244 { 245 idt_setup_from_table(idt_table, def_idts, ARRAY_SIZE(def_idts)); 246 } 247 248 #ifdef CONFIG_X86_64 249 /** 250 * idt_setup_early_pf - Initialize the idt table with early pagefault handler 251 * 252 * On X8664 this does not use interrupt stacks as they can't work before 253 * cpu_init() is invoked and sets up TSS. The IST variant is installed 254 * after that. 255 * 256 * FIXME: Why is 32bit and 64bit installing the PF handler at different 257 * places in the early setup code? 258 */ 259 void __init idt_setup_early_pf(void) 260 { 261 idt_setup_from_table(idt_table, early_pf_idts, 262 ARRAY_SIZE(early_pf_idts)); 263 } 264 265 /** 266 * idt_setup_ist_traps - Initialize the idt table with traps using IST 267 */ 268 void __init idt_setup_ist_traps(void) 269 { 270 idt_setup_from_table(idt_table, ist_idts, ARRAY_SIZE(ist_idts)); 271 } 272 273 /** 274 * idt_setup_debugidt_traps - Initialize the debug idt table with debug traps 275 */ 276 void __init idt_setup_debugidt_traps(void) 277 { 278 memcpy(&debug_idt_table, &idt_table, IDT_ENTRIES * 16); 279 280 idt_setup_from_table(debug_idt_table, dbg_idts, ARRAY_SIZE(dbg_idts)); 281 } 282 #endif 283 284 /** 285 * idt_setup_apic_and_irq_gates - Setup APIC/SMP and normal interrupt gates 286 */ 287 void __init idt_setup_apic_and_irq_gates(void) 288 { 289 idt_setup_from_table(idt_table, apic_idts, ARRAY_SIZE(apic_idts)); 290 } 291 292 /** 293 * idt_setup_early_handler - Initializes the idt table with early handlers 294 */ 295 void __init idt_setup_early_handler(void) 296 { 297 int i; 298 299 for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) 300 set_intr_gate(i, early_idt_handler_array[i]); 301 #ifdef CONFIG_X86_32 302 for ( ; i < NR_VECTORS; i++) 303 set_intr_gate(i, early_ignore_irq); 304 #endif 305 load_idt(&idt_descr); 306 } 307 308 /** 309 * idt_invalidate - Invalidate interrupt descriptor table 310 * @addr: The virtual address of the 'invalid' IDT 311 */ 312 void idt_invalidate(void *addr) 313 { 314 struct desc_ptr idt = { .address = (unsigned long) addr, .size = 0 }; 315 316 load_idt(&idt); 317 } 318