Merge tag 'efi-core-2020-10-12' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / arch / x86 / kernel / idt.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Interrupt descriptor table related code
4  */
5 #include <linux/interrupt.h>
6
7 #include <asm/cpu_entry_area.h>
8 #include <asm/set_memory.h>
9 #include <asm/traps.h>
10 #include <asm/proto.h>
11 #include <asm/desc.h>
12 #include <asm/hw_irq.h>
13
14 struct idt_data {
15         unsigned int    vector;
16         unsigned int    segment;
17         struct idt_bits bits;
18         const void      *addr;
19 };
20
21 #define DPL0            0x0
22 #define DPL3            0x3
23
24 #define DEFAULT_STACK   0
25
26 #define G(_vector, _addr, _ist, _type, _dpl, _segment)  \
27         {                                               \
28                 .vector         = _vector,              \
29                 .bits.ist       = _ist,                 \
30                 .bits.type      = _type,                \
31                 .bits.dpl       = _dpl,                 \
32                 .bits.p         = 1,                    \
33                 .addr           = _addr,                \
34                 .segment        = _segment,             \
35         }
36
37 /* Interrupt gate */
38 #define INTG(_vector, _addr)                            \
39         G(_vector, _addr, DEFAULT_STACK, GATE_INTERRUPT, DPL0, __KERNEL_CS)
40
41 /* System interrupt gate */
42 #define SYSG(_vector, _addr)                            \
43         G(_vector, _addr, DEFAULT_STACK, GATE_INTERRUPT, DPL3, __KERNEL_CS)
44
45 /*
46  * Interrupt gate with interrupt stack. The _ist index is the index in
47  * the tss.ist[] array, but for the descriptor it needs to start at 1.
48  */
49 #define ISTG(_vector, _addr, _ist)                      \
50         G(_vector, _addr, _ist + 1, GATE_INTERRUPT, DPL0, __KERNEL_CS)
51
52 /* Task gate */
53 #define TSKG(_vector, _gdt)                             \
54         G(_vector, NULL, DEFAULT_STACK, GATE_TASK, DPL0, _gdt << 3)
55
56 #define IDT_TABLE_SIZE          (IDT_ENTRIES * sizeof(gate_desc))
57
58 static bool idt_setup_done __initdata;
59
60 /*
61  * Early traps running on the DEFAULT_STACK because the other interrupt
62  * stacks work only after cpu_init().
63  */
64 static const __initconst struct idt_data early_idts[] = {
65         INTG(X86_TRAP_DB,               asm_exc_debug),
66         SYSG(X86_TRAP_BP,               asm_exc_int3),
67
68 #ifdef CONFIG_X86_32
69         /*
70          * Not possible on 64-bit. See idt_setup_early_pf() for details.
71          */
72         INTG(X86_TRAP_PF,               asm_exc_page_fault),
73 #endif
74 };
75
76 /*
77  * The default IDT entries which are set up in trap_init() before
78  * cpu_init() is invoked. Interrupt stacks cannot be used at that point and
79  * the traps which use them are reinitialized with IST after cpu_init() has
80  * set up TSS.
81  */
82 static const __initconst struct idt_data def_idts[] = {
83         INTG(X86_TRAP_DE,               asm_exc_divide_error),
84         INTG(X86_TRAP_NMI,              asm_exc_nmi),
85         INTG(X86_TRAP_BR,               asm_exc_bounds),
86         INTG(X86_TRAP_UD,               asm_exc_invalid_op),
87         INTG(X86_TRAP_NM,               asm_exc_device_not_available),
88         INTG(X86_TRAP_OLD_MF,           asm_exc_coproc_segment_overrun),
89         INTG(X86_TRAP_TS,               asm_exc_invalid_tss),
90         INTG(X86_TRAP_NP,               asm_exc_segment_not_present),
91         INTG(X86_TRAP_SS,               asm_exc_stack_segment),
92         INTG(X86_TRAP_GP,               asm_exc_general_protection),
93         INTG(X86_TRAP_SPURIOUS,         asm_exc_spurious_interrupt_bug),
94         INTG(X86_TRAP_MF,               asm_exc_coprocessor_error),
95         INTG(X86_TRAP_AC,               asm_exc_alignment_check),
96         INTG(X86_TRAP_XF,               asm_exc_simd_coprocessor_error),
97
98 #ifdef CONFIG_X86_32
99         TSKG(X86_TRAP_DF,               GDT_ENTRY_DOUBLEFAULT_TSS),
100 #else
101         INTG(X86_TRAP_DF,               asm_exc_double_fault),
102 #endif
103         INTG(X86_TRAP_DB,               asm_exc_debug),
104
105 #ifdef CONFIG_X86_MCE
106         INTG(X86_TRAP_MC,               asm_exc_machine_check),
107 #endif
108
109         SYSG(X86_TRAP_OF,               asm_exc_overflow),
110 #if defined(CONFIG_IA32_EMULATION)
111         SYSG(IA32_SYSCALL_VECTOR,       entry_INT80_compat),
112 #elif defined(CONFIG_X86_32)
113         SYSG(IA32_SYSCALL_VECTOR,       entry_INT80_32),
114 #endif
115 };
116
117 /*
118  * The APIC and SMP idt entries
119  */
120 static const __initconst struct idt_data apic_idts[] = {
121 #ifdef CONFIG_SMP
122         INTG(RESCHEDULE_VECTOR,                 asm_sysvec_reschedule_ipi),
123         INTG(CALL_FUNCTION_VECTOR,              asm_sysvec_call_function),
124         INTG(CALL_FUNCTION_SINGLE_VECTOR,       asm_sysvec_call_function_single),
125         INTG(IRQ_MOVE_CLEANUP_VECTOR,           asm_sysvec_irq_move_cleanup),
126         INTG(REBOOT_VECTOR,                     asm_sysvec_reboot),
127 #endif
128
129 #ifdef CONFIG_X86_THERMAL_VECTOR
130         INTG(THERMAL_APIC_VECTOR,               asm_sysvec_thermal),
131 #endif
132
133 #ifdef CONFIG_X86_MCE_THRESHOLD
134         INTG(THRESHOLD_APIC_VECTOR,             asm_sysvec_threshold),
135 #endif
136
137 #ifdef CONFIG_X86_MCE_AMD
138         INTG(DEFERRED_ERROR_VECTOR,             asm_sysvec_deferred_error),
139 #endif
140
141 #ifdef CONFIG_X86_LOCAL_APIC
142         INTG(LOCAL_TIMER_VECTOR,                asm_sysvec_apic_timer_interrupt),
143         INTG(X86_PLATFORM_IPI_VECTOR,           asm_sysvec_x86_platform_ipi),
144 # ifdef CONFIG_HAVE_KVM
145         INTG(POSTED_INTR_VECTOR,                asm_sysvec_kvm_posted_intr_ipi),
146         INTG(POSTED_INTR_WAKEUP_VECTOR,         asm_sysvec_kvm_posted_intr_wakeup_ipi),
147         INTG(POSTED_INTR_NESTED_VECTOR,         asm_sysvec_kvm_posted_intr_nested_ipi),
148 # endif
149 # ifdef CONFIG_IRQ_WORK
150         INTG(IRQ_WORK_VECTOR,                   asm_sysvec_irq_work),
151 # endif
152         INTG(SPURIOUS_APIC_VECTOR,              asm_sysvec_spurious_apic_interrupt),
153         INTG(ERROR_APIC_VECTOR,                 asm_sysvec_error_interrupt),
154 #endif
155 };
156
157 /* Must be page-aligned because the real IDT is used in the cpu entry area */
158 static gate_desc idt_table[IDT_ENTRIES] __page_aligned_bss;
159
160 static struct desc_ptr idt_descr __ro_after_init = {
161         .size           = IDT_TABLE_SIZE - 1,
162         .address        = (unsigned long) idt_table,
163 };
164
165 void load_current_idt(void)
166 {
167         lockdep_assert_irqs_disabled();
168         load_idt(&idt_descr);
169 }
170
171 #ifdef CONFIG_X86_F00F_BUG
172 bool idt_is_f00f_address(unsigned long address)
173 {
174         return ((address - idt_descr.address) >> 3) == 6;
175 }
176 #endif
177
178 static inline void idt_init_desc(gate_desc *gate, const struct idt_data *d)
179 {
180         unsigned long addr = (unsigned long) d->addr;
181
182         gate->offset_low        = (u16) addr;
183         gate->segment           = (u16) d->segment;
184         gate->bits              = d->bits;
185         gate->offset_middle     = (u16) (addr >> 16);
186 #ifdef CONFIG_X86_64
187         gate->offset_high       = (u32) (addr >> 32);
188         gate->reserved          = 0;
189 #endif
190 }
191
192 static __init void
193 idt_setup_from_table(gate_desc *idt, const struct idt_data *t, int size, bool sys)
194 {
195         gate_desc desc;
196
197         for (; size > 0; t++, size--) {
198                 idt_init_desc(&desc, t);
199                 write_idt_entry(idt, t->vector, &desc);
200                 if (sys)
201                         set_bit(t->vector, system_vectors);
202         }
203 }
204
205 static __init void set_intr_gate(unsigned int n, const void *addr)
206 {
207         struct idt_data data;
208
209         BUG_ON(n > 0xFF);
210
211         memset(&data, 0, sizeof(data));
212         data.vector     = n;
213         data.addr       = addr;
214         data.segment    = __KERNEL_CS;
215         data.bits.type  = GATE_INTERRUPT;
216         data.bits.p     = 1;
217
218         idt_setup_from_table(idt_table, &data, 1, false);
219 }
220
221 /**
222  * idt_setup_early_traps - Initialize the idt table with early traps
223  *
224  * On X8664 these traps do not use interrupt stacks as they can't work
225  * before cpu_init() is invoked and sets up TSS. The IST variants are
226  * installed after that.
227  */
228 void __init idt_setup_early_traps(void)
229 {
230         idt_setup_from_table(idt_table, early_idts, ARRAY_SIZE(early_idts),
231                              true);
232         load_idt(&idt_descr);
233 }
234
235 /**
236  * idt_setup_traps - Initialize the idt table with default traps
237  */
238 void __init idt_setup_traps(void)
239 {
240         idt_setup_from_table(idt_table, def_idts, ARRAY_SIZE(def_idts), true);
241 }
242
243 #ifdef CONFIG_X86_64
244 /*
245  * Early traps running on the DEFAULT_STACK because the other interrupt
246  * stacks work only after cpu_init().
247  */
248 static const __initconst struct idt_data early_pf_idts[] = {
249         INTG(X86_TRAP_PF,               asm_exc_page_fault),
250 };
251
252 /*
253  * The exceptions which use Interrupt stacks. They are setup after
254  * cpu_init() when the TSS has been initialized.
255  */
256 static const __initconst struct idt_data ist_idts[] = {
257         ISTG(X86_TRAP_DB,       asm_exc_debug,          IST_INDEX_DB),
258         ISTG(X86_TRAP_NMI,      asm_exc_nmi,            IST_INDEX_NMI),
259         ISTG(X86_TRAP_DF,       asm_exc_double_fault,   IST_INDEX_DF),
260 #ifdef CONFIG_X86_MCE
261         ISTG(X86_TRAP_MC,       asm_exc_machine_check,  IST_INDEX_MCE),
262 #endif
263 };
264
265 /**
266  * idt_setup_early_pf - Initialize the idt table with early pagefault handler
267  *
268  * On X8664 this does not use interrupt stacks as they can't work before
269  * cpu_init() is invoked and sets up TSS. The IST variant is installed
270  * after that.
271  *
272  * Note, that X86_64 cannot install the real #PF handler in
273  * idt_setup_early_traps() because the memory intialization needs the #PF
274  * handler from the early_idt_handler_array to initialize the early page
275  * tables.
276  */
277 void __init idt_setup_early_pf(void)
278 {
279         idt_setup_from_table(idt_table, early_pf_idts,
280                              ARRAY_SIZE(early_pf_idts), true);
281 }
282
283 /**
284  * idt_setup_ist_traps - Initialize the idt table with traps using IST
285  */
286 void __init idt_setup_ist_traps(void)
287 {
288         idt_setup_from_table(idt_table, ist_idts, ARRAY_SIZE(ist_idts), true);
289 }
290 #endif
291
292 static void __init idt_map_in_cea(void)
293 {
294         /*
295          * Set the IDT descriptor to a fixed read-only location in the cpu
296          * entry area, so that the "sidt" instruction will not leak the
297          * location of the kernel, and to defend the IDT against arbitrary
298          * memory write vulnerabilities.
299          */
300         cea_set_pte(CPU_ENTRY_AREA_RO_IDT_VADDR, __pa_symbol(idt_table),
301                     PAGE_KERNEL_RO);
302         idt_descr.address = CPU_ENTRY_AREA_RO_IDT;
303 }
304
305 /**
306  * idt_setup_apic_and_irq_gates - Setup APIC/SMP and normal interrupt gates
307  */
308 void __init idt_setup_apic_and_irq_gates(void)
309 {
310         int i = FIRST_EXTERNAL_VECTOR;
311         void *entry;
312
313         idt_setup_from_table(idt_table, apic_idts, ARRAY_SIZE(apic_idts), true);
314
315         for_each_clear_bit_from(i, system_vectors, FIRST_SYSTEM_VECTOR) {
316                 entry = irq_entries_start + 8 * (i - FIRST_EXTERNAL_VECTOR);
317                 set_intr_gate(i, entry);
318         }
319
320 #ifdef CONFIG_X86_LOCAL_APIC
321         for_each_clear_bit_from(i, system_vectors, NR_VECTORS) {
322                 /*
323                  * Don't set the non assigned system vectors in the
324                  * system_vectors bitmap. Otherwise they show up in
325                  * /proc/interrupts.
326                  */
327                 entry = spurious_entries_start + 8 * (i - FIRST_SYSTEM_VECTOR);
328                 set_intr_gate(i, entry);
329         }
330 #endif
331         /* Map IDT into CPU entry area and reload it. */
332         idt_map_in_cea();
333         load_idt(&idt_descr);
334
335         /* Make the IDT table read only */
336         set_memory_ro((unsigned long)&idt_table, 1);
337
338         idt_setup_done = true;
339 }
340
341 /**
342  * idt_setup_early_handler - Initializes the idt table with early handlers
343  */
344 void __init idt_setup_early_handler(void)
345 {
346         int i;
347
348         for (i = 0; i < NUM_EXCEPTION_VECTORS; i++)
349                 set_intr_gate(i, early_idt_handler_array[i]);
350 #ifdef CONFIG_X86_32
351         for ( ; i < NR_VECTORS; i++)
352                 set_intr_gate(i, early_ignore_irq);
353 #endif
354         load_idt(&idt_descr);
355 }
356
357 /**
358  * idt_invalidate - Invalidate interrupt descriptor table
359  * @addr:       The virtual address of the 'invalid' IDT
360  */
361 void idt_invalidate(void *addr)
362 {
363         struct desc_ptr idt = { .address = (unsigned long) addr, .size = 0 };
364
365         load_idt(&idt);
366 }
367
368 void __init alloc_intr_gate(unsigned int n, const void *addr)
369 {
370         if (WARN_ON(n < FIRST_SYSTEM_VECTOR))
371                 return;
372
373         if (WARN_ON(idt_setup_done))
374                 return;
375
376         if (!WARN_ON(test_and_set_bit(n, system_vectors)))
377                 set_intr_gate(n, addr);
378 }