|
5 | 5 | #include <linux/interrupt.h>
|
6 | 6 |
|
7 | 7 | #include <asm/cpu_entry_area.h>
|
| 8 | +#include <asm/set_memory.h> |
8 | 9 | #include <asm/traps.h>
|
9 | 10 | #include <asm/proto.h>
|
10 | 11 | #include <asm/desc.h>
|
@@ -156,37 +157,25 @@ static const __initconst struct idt_data apic_idts[] = {
|
156 | 157 | #endif
|
157 | 158 | };
|
158 | 159 |
|
159 |
| -#ifdef CONFIG_X86_64 |
160 |
| -/* |
161 |
| - * Early traps running on the DEFAULT_STACK because the other interrupt |
162 |
| - * stacks work only after cpu_init(). |
163 |
| - */ |
164 |
| -static const __initconst struct idt_data early_pf_idts[] = { |
165 |
| - INTG(X86_TRAP_PF, asm_exc_page_fault), |
166 |
| -}; |
167 |
| -#endif |
168 |
| - |
169 |
| -/* Must be page-aligned because the real IDT is used in a fixmap. */ |
170 |
| -gate_desc idt_table[IDT_ENTRIES] __page_aligned_bss; |
| 160 | +/* Must be page-aligned because the real IDT is used in the cpu entry area */ |
| 161 | +static gate_desc idt_table[IDT_ENTRIES] __page_aligned_bss; |
171 | 162 |
|
172 | 163 | struct desc_ptr idt_descr __ro_after_init = {
|
173 | 164 | .size = IDT_TABLE_SIZE - 1,
|
174 | 165 | .address = (unsigned long) idt_table,
|
175 | 166 | };
|
176 | 167 |
|
177 |
| -#ifdef CONFIG_X86_64 |
178 |
| -/* |
179 |
| - * The exceptions which use Interrupt stacks. They are setup after |
180 |
| - * cpu_init() when the TSS has been initialized. |
181 |
| - */ |
182 |
| -static const __initconst struct idt_data ist_idts[] = { |
183 |
| - ISTG(X86_TRAP_DB, asm_exc_debug, IST_INDEX_DB), |
184 |
| - ISTG(X86_TRAP_NMI, asm_exc_nmi, IST_INDEX_NMI), |
185 |
| - ISTG(X86_TRAP_DF, asm_exc_double_fault, IST_INDEX_DF), |
186 |
| -#ifdef CONFIG_X86_MCE |
187 |
| - ISTG(X86_TRAP_MC, asm_exc_machine_check, IST_INDEX_MCE), |
188 |
| -#endif |
189 |
| -}; |
| 168 | +void load_current_idt(void) |
| 169 | +{ |
| 170 | + lockdep_assert_irqs_disabled(); |
| 171 | + load_idt(&idt_descr); |
| 172 | +} |
| 173 | + |
| 174 | +#ifdef CONFIG_X86_F00F_BUG |
| 175 | +bool idt_is_f00f_address(unsigned long address) |
| 176 | +{ |
| 177 | + return ((address - idt_descr.address) >> 3) == 6; |
| 178 | +} |
190 | 179 | #endif
|
191 | 180 |
|
192 | 181 | static inline void idt_init_desc(gate_desc *gate, const struct idt_data *d)
|
@@ -255,6 +244,27 @@ void __init idt_setup_traps(void)
|
255 | 244 | }
|
256 | 245 |
|
257 | 246 | #ifdef CONFIG_X86_64
|
| 247 | +/* |
| 248 | + * Early traps running on the DEFAULT_STACK because the other interrupt |
| 249 | + * stacks work only after cpu_init(). |
| 250 | + */ |
| 251 | +static const __initconst struct idt_data early_pf_idts[] = { |
| 252 | + INTG(X86_TRAP_PF, asm_exc_page_fault), |
| 253 | +}; |
| 254 | + |
| 255 | +/* |
| 256 | + * The exceptions which use Interrupt stacks. They are setup after |
| 257 | + * cpu_init() when the TSS has been initialized. |
| 258 | + */ |
| 259 | +static const __initconst struct idt_data ist_idts[] = { |
| 260 | + ISTG(X86_TRAP_DB, asm_exc_debug, IST_INDEX_DB), |
| 261 | + ISTG(X86_TRAP_NMI, asm_exc_nmi, IST_INDEX_NMI), |
| 262 | + ISTG(X86_TRAP_DF, asm_exc_double_fault, IST_INDEX_DF), |
| 263 | +#ifdef CONFIG_X86_MCE |
| 264 | + ISTG(X86_TRAP_MC, asm_exc_machine_check, IST_INDEX_MCE), |
| 265 | +#endif |
| 266 | +}; |
| 267 | + |
258 | 268 | /**
|
259 | 269 | * idt_setup_early_pf - Initialize the idt table with early pagefault handler
|
260 | 270 | *
|
@@ -325,6 +335,9 @@ void __init idt_setup_apic_and_irq_gates(void)
|
325 | 335 | idt_map_in_cea();
|
326 | 336 | load_idt(&idt_descr);
|
327 | 337 |
|
| 338 | + /* Make the IDT table read only */ |
| 339 | + set_memory_ro((unsigned long)&idt_table, 1); |
| 340 | + |
328 | 341 | idt_setup_done = true;
|
329 | 342 | }
|
330 | 343 |
|
|
0 commit comments