xref: /openbmc/linux/arch/x86/include/asm/idtentry.h (revision 82df5b73)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _ASM_X86_IDTENTRY_H
3 #define _ASM_X86_IDTENTRY_H
4 
5 /* Interrupts/Exceptions */
6 #include <asm/trapnr.h>
7 
8 #ifndef __ASSEMBLY__
9 #include <linux/hardirq.h>
10 
11 #include <asm/irq_stack.h>
12 
13 void idtentry_enter_user(struct pt_regs *regs);
14 void idtentry_exit_user(struct pt_regs *regs);
15 
16 bool idtentry_enter_cond_rcu(struct pt_regs *regs);
17 void idtentry_exit_cond_rcu(struct pt_regs *regs, bool rcu_exit);
18 
19 /**
20  * DECLARE_IDTENTRY - Declare functions for simple IDT entry points
21  *		      No error code pushed by hardware
22  * @vector:	Vector number (ignored for C)
23  * @func:	Function name of the entry point
24  *
25  * Declares three functions:
26  * - The ASM entry point: asm_##func
27  * - The XEN PV trap entry point: xen_##func (maybe unused)
28  * - The C handler called from the ASM entry point
29  *
30  * Note: This is the C variant of DECLARE_IDTENTRY(). As the name says it
31  * declares the entry points for usage in C code. There is an ASM variant
32  * as well which is used to emit the entry stubs in entry_32/64.S.
33  */
34 #define DECLARE_IDTENTRY(vector, func)					\
35 	asmlinkage void asm_##func(void);				\
36 	asmlinkage void xen_asm_##func(void);				\
37 	__visible void func(struct pt_regs *regs)
38 
39 /**
40  * DEFINE_IDTENTRY - Emit code for simple IDT entry points
41  * @func:	Function name of the entry point
42  *
43  * @func is called from ASM entry code with interrupts disabled.
44  *
45  * The macro is written so it acts as function definition. Append the
46  * body with a pair of curly brackets.
47  *
48  * idtentry_enter() contains common code which has to be invoked before
49  * arbitrary code in the body. idtentry_exit() contains common code
50  * which has to run before returning to the low level assembly code.
51  */
52 #define DEFINE_IDTENTRY(func)						\
53 static __always_inline void __##func(struct pt_regs *regs);		\
54 									\
55 __visible noinstr void func(struct pt_regs *regs)			\
56 {									\
57 	bool rcu_exit = idtentry_enter_cond_rcu(regs);			\
58 									\
59 	instrumentation_begin();					\
60 	__##func (regs);						\
61 	instrumentation_end();						\
62 	idtentry_exit_cond_rcu(regs, rcu_exit);				\
63 }									\
64 									\
65 static __always_inline void __##func(struct pt_regs *regs)
66 
67 /* Special case for 32bit IRET 'trap' */
68 #define DECLARE_IDTENTRY_SW	DECLARE_IDTENTRY
69 #define DEFINE_IDTENTRY_SW	DEFINE_IDTENTRY
70 
71 /**
72  * DECLARE_IDTENTRY_ERRORCODE - Declare functions for simple IDT entry points
73  *				Error code pushed by hardware
74  * @vector:	Vector number (ignored for C)
75  * @func:	Function name of the entry point
76  *
77  * Declares three functions:
78  * - The ASM entry point: asm_##func
79  * - The XEN PV trap entry point: xen_##func (maybe unused)
80  * - The C handler called from the ASM entry point
81  *
82  * Same as DECLARE_IDTENTRY, but has an extra error_code argument for the
83  * C-handler.
84  */
85 #define DECLARE_IDTENTRY_ERRORCODE(vector, func)			\
86 	asmlinkage void asm_##func(void);				\
87 	asmlinkage void xen_asm_##func(void);				\
88 	__visible void func(struct pt_regs *regs, unsigned long error_code)
89 
90 /**
91  * DEFINE_IDTENTRY_ERRORCODE - Emit code for simple IDT entry points
92  *			       Error code pushed by hardware
93  * @func:	Function name of the entry point
94  *
95  * Same as DEFINE_IDTENTRY, but has an extra error_code argument
96  */
97 #define DEFINE_IDTENTRY_ERRORCODE(func)					\
98 static __always_inline void __##func(struct pt_regs *regs,		\
99 				     unsigned long error_code);		\
100 									\
101 __visible noinstr void func(struct pt_regs *regs,			\
102 			    unsigned long error_code)			\
103 {									\
104 	bool rcu_exit = idtentry_enter_cond_rcu(regs);			\
105 									\
106 	instrumentation_begin();					\
107 	__##func (regs, error_code);					\
108 	instrumentation_end();						\
109 	idtentry_exit_cond_rcu(regs, rcu_exit);				\
110 }									\
111 									\
112 static __always_inline void __##func(struct pt_regs *regs,		\
113 				     unsigned long error_code)
114 
115 /**
116  * DECLARE_IDTENTRY_RAW - Declare functions for raw IDT entry points
117  *		      No error code pushed by hardware
118  * @vector:	Vector number (ignored for C)
119  * @func:	Function name of the entry point
120  *
121  * Maps to DECLARE_IDTENTRY().
122  */
123 #define DECLARE_IDTENTRY_RAW(vector, func)				\
124 	DECLARE_IDTENTRY(vector, func)
125 
126 /**
127  * DEFINE_IDTENTRY_RAW - Emit code for raw IDT entry points
128  * @func:	Function name of the entry point
129  *
130  * @func is called from ASM entry code with interrupts disabled.
131  *
132  * The macro is written so it acts as function definition. Append the
133  * body with a pair of curly brackets.
134  *
135  * Contrary to DEFINE_IDTENTRY() this does not invoke the
136  * idtentry_enter/exit() helpers before and after the body invocation. This
137  * needs to be done in the body itself if applicable. Use if extra work
138  * is required before the enter/exit() helpers are invoked.
139  */
140 #define DEFINE_IDTENTRY_RAW(func)					\
141 __visible noinstr void func(struct pt_regs *regs)
142 
143 /**
144  * DECLARE_IDTENTRY_RAW_ERRORCODE - Declare functions for raw IDT entry points
145  *				    Error code pushed by hardware
146  * @vector:	Vector number (ignored for C)
147  * @func:	Function name of the entry point
148  *
149  * Maps to DECLARE_IDTENTRY_ERRORCODE()
150  */
151 #define DECLARE_IDTENTRY_RAW_ERRORCODE(vector, func)			\
152 	DECLARE_IDTENTRY_ERRORCODE(vector, func)
153 
154 /**
155  * DEFINE_IDTENTRY_RAW_ERRORCODE - Emit code for raw IDT entry points
156  * @func:	Function name of the entry point
157  *
158  * @func is called from ASM entry code with interrupts disabled.
159  *
160  * The macro is written so it acts as function definition. Append the
161  * body with a pair of curly brackets.
162  *
163  * Contrary to DEFINE_IDTENTRY_ERRORCODE() this does not invoke the
164  * idtentry_enter/exit() helpers before and after the body invocation. This
165  * needs to be done in the body itself if applicable. Use if extra work
166  * is required before the enter/exit() helpers are invoked.
167  */
168 #define DEFINE_IDTENTRY_RAW_ERRORCODE(func)				\
169 __visible noinstr void func(struct pt_regs *regs, unsigned long error_code)
170 
171 /**
172  * DECLARE_IDTENTRY_IRQ - Declare functions for device interrupt IDT entry
173  *			  points (common/spurious)
174  * @vector:	Vector number (ignored for C)
175  * @func:	Function name of the entry point
176  *
177  * Maps to DECLARE_IDTENTRY_ERRORCODE()
178  */
179 #define DECLARE_IDTENTRY_IRQ(vector, func)				\
180 	DECLARE_IDTENTRY_ERRORCODE(vector, func)
181 
182 /**
183  * DEFINE_IDTENTRY_IRQ - Emit code for device interrupt IDT entry points
184  * @func:	Function name of the entry point
185  *
186  * The vector number is pushed by the low level entry stub and handed
187  * to the function as error_code argument which needs to be truncated
188  * to an u8 because the push is sign extending.
189  *
190  * On 64-bit idtentry_enter/exit() are invoked in the ASM entry code before
191  * and after switching to the interrupt stack. On 32-bit this happens in C.
192  *
193  * irq_enter/exit_rcu() are invoked before the function body and the
194  * KVM L1D flush request is set.
195  */
196 #define DEFINE_IDTENTRY_IRQ(func)					\
197 static __always_inline void __##func(struct pt_regs *regs, u8 vector);	\
198 									\
199 __visible noinstr void func(struct pt_regs *regs,			\
200 			    unsigned long error_code)			\
201 {									\
202 	bool rcu_exit = idtentry_enter_cond_rcu(regs);			\
203 									\
204 	instrumentation_begin();					\
205 	irq_enter_rcu();						\
206 	kvm_set_cpu_l1tf_flush_l1d();					\
207 	__##func (regs, (u8)error_code);				\
208 	irq_exit_rcu();							\
209 	instrumentation_end();						\
210 	idtentry_exit_cond_rcu(regs, rcu_exit);				\
211 }									\
212 									\
213 static __always_inline void __##func(struct pt_regs *regs, u8 vector)
214 
215 /**
216  * DECLARE_IDTENTRY_SYSVEC - Declare functions for system vector entry points
217  * @vector:	Vector number (ignored for C)
218  * @func:	Function name of the entry point
219  *
220  * Declares three functions:
221  * - The ASM entry point: asm_##func
222  * - The XEN PV trap entry point: xen_##func (maybe unused)
223  * - The C handler called from the ASM entry point
224  *
225  * Maps to DECLARE_IDTENTRY().
226  */
227 #define DECLARE_IDTENTRY_SYSVEC(vector, func)				\
228 	DECLARE_IDTENTRY(vector, func)
229 
230 /**
231  * DEFINE_IDTENTRY_SYSVEC - Emit code for system vector IDT entry points
232  * @func:	Function name of the entry point
233  *
234  * idtentry_enter/exit() and irq_enter/exit_rcu() are invoked before the
235  * function body. KVM L1D flush request is set.
236  *
237  * Runs the function on the interrupt stack if the entry hit kernel mode
238  */
239 #define DEFINE_IDTENTRY_SYSVEC(func)					\
240 static void __##func(struct pt_regs *regs);				\
241 									\
242 __visible noinstr void func(struct pt_regs *regs)			\
243 {									\
244 	bool rcu_exit = idtentry_enter_cond_rcu(regs);			\
245 									\
246 	instrumentation_begin();					\
247 	irq_enter_rcu();						\
248 	kvm_set_cpu_l1tf_flush_l1d();					\
249 	run_on_irqstack_cond(__##func, regs, regs);			\
250 	irq_exit_rcu();							\
251 	instrumentation_end();						\
252 	idtentry_exit_cond_rcu(regs, rcu_exit);				\
253 }									\
254 									\
255 static noinline void __##func(struct pt_regs *regs)
256 
257 /**
258  * DEFINE_IDTENTRY_SYSVEC_SIMPLE - Emit code for simple system vector IDT
259  *				   entry points
260  * @func:	Function name of the entry point
261  *
262  * Runs the function on the interrupted stack. No switch to IRQ stack and
263  * only the minimal __irq_enter/exit() handling.
264  *
265  * Only use for 'empty' vectors like reschedule IPI and KVM posted
266  * interrupt vectors.
267  */
268 #define DEFINE_IDTENTRY_SYSVEC_SIMPLE(func)				\
269 static __always_inline void __##func(struct pt_regs *regs);		\
270 									\
271 __visible noinstr void func(struct pt_regs *regs)			\
272 {									\
273 	bool rcu_exit = idtentry_enter_cond_rcu(regs);			\
274 									\
275 	instrumentation_begin();					\
276 	__irq_enter_raw();						\
277 	kvm_set_cpu_l1tf_flush_l1d();					\
278 	__##func (regs);						\
279 	__irq_exit_raw();						\
280 	instrumentation_end();						\
281 	idtentry_exit_cond_rcu(regs, rcu_exit);				\
282 }									\
283 									\
284 static __always_inline void __##func(struct pt_regs *regs)
285 
286 /**
287  * DECLARE_IDTENTRY_XENCB - Declare functions for XEN HV callback entry point
288  * @vector:	Vector number (ignored for C)
289  * @func:	Function name of the entry point
290  *
291  * Declares three functions:
292  * - The ASM entry point: asm_##func
293  * - The XEN PV trap entry point: xen_##func (maybe unused)
294  * - The C handler called from the ASM entry point
295  *
296  * Maps to DECLARE_IDTENTRY(). Distinct entry point to handle the 32/64-bit
297  * difference
298  */
299 #define DECLARE_IDTENTRY_XENCB(vector, func)				\
300 	DECLARE_IDTENTRY(vector, func)
301 
302 #ifdef CONFIG_X86_64
303 /**
304  * DECLARE_IDTENTRY_IST - Declare functions for IST handling IDT entry points
305  * @vector:	Vector number (ignored for C)
306  * @func:	Function name of the entry point
307  *
308  * Maps to DECLARE_IDTENTRY_RAW, but declares also the NOIST C handler
309  * which is called from the ASM entry point on user mode entry
310  */
311 #define DECLARE_IDTENTRY_IST(vector, func)				\
312 	DECLARE_IDTENTRY_RAW(vector, func);				\
313 	__visible void noist_##func(struct pt_regs *regs)
314 
315 /**
316  * DEFINE_IDTENTRY_IST - Emit code for IST entry points
317  * @func:	Function name of the entry point
318  *
319  * Maps to DEFINE_IDTENTRY_RAW
320  */
321 #define DEFINE_IDTENTRY_IST(func)					\
322 	DEFINE_IDTENTRY_RAW(func)
323 
324 /**
325  * DEFINE_IDTENTRY_NOIST - Emit code for NOIST entry points which
326  *			   belong to a IST entry point (MCE, DB)
327  * @func:	Function name of the entry point. Must be the same as
328  *		the function name of the corresponding IST variant
329  *
330  * Maps to DEFINE_IDTENTRY_RAW().
331  */
332 #define DEFINE_IDTENTRY_NOIST(func)					\
333 	DEFINE_IDTENTRY_RAW(noist_##func)
334 
335 /**
336  * DECLARE_IDTENTRY_DF - Declare functions for double fault
337  * @vector:	Vector number (ignored for C)
338  * @func:	Function name of the entry point
339  *
340  * Maps to DECLARE_IDTENTRY_RAW_ERRORCODE
341  */
342 #define DECLARE_IDTENTRY_DF(vector, func)				\
343 	DECLARE_IDTENTRY_RAW_ERRORCODE(vector, func)
344 
345 /**
346  * DEFINE_IDTENTRY_DF - Emit code for double fault
347  * @func:	Function name of the entry point
348  *
349  * Maps to DEFINE_IDTENTRY_RAW_ERRORCODE
350  */
351 #define DEFINE_IDTENTRY_DF(func)					\
352 	DEFINE_IDTENTRY_RAW_ERRORCODE(func)
353 
354 #else	/* CONFIG_X86_64 */
355 
356 /* Maps to a regular IDTENTRY on 32bit for now */
357 # define DECLARE_IDTENTRY_IST		DECLARE_IDTENTRY
358 # define DEFINE_IDTENTRY_IST		DEFINE_IDTENTRY
359 
360 /**
361  * DECLARE_IDTENTRY_DF - Declare functions for double fault 32bit variant
362  * @vector:	Vector number (ignored for C)
363  * @func:	Function name of the entry point
364  *
365  * Declares two functions:
366  * - The ASM entry point: asm_##func
367  * - The C handler called from the C shim
368  */
369 #define DECLARE_IDTENTRY_DF(vector, func)				\
370 	asmlinkage void asm_##func(void);				\
371 	__visible void func(struct pt_regs *regs,			\
372 			    unsigned long error_code,			\
373 			    unsigned long address)
374 
375 /**
376  * DEFINE_IDTENTRY_DF - Emit code for double fault on 32bit
377  * @func:	Function name of the entry point
378  *
379  * This is called through the doublefault shim which already provides
380  * cr2 in the address argument.
381  */
382 #define DEFINE_IDTENTRY_DF(func)					\
383 __visible noinstr void func(struct pt_regs *regs,			\
384 			    unsigned long error_code,			\
385 			    unsigned long address)
386 
387 #endif	/* !CONFIG_X86_64 */
388 
389 /* C-Code mapping */
390 #define DECLARE_IDTENTRY_MCE		DECLARE_IDTENTRY_IST
391 #define DEFINE_IDTENTRY_MCE		DEFINE_IDTENTRY_IST
392 #define DEFINE_IDTENTRY_MCE_USER	DEFINE_IDTENTRY_NOIST
393 
394 #define DECLARE_IDTENTRY_NMI		DECLARE_IDTENTRY_RAW
395 #define DEFINE_IDTENTRY_NMI		DEFINE_IDTENTRY_RAW
396 
397 #define DECLARE_IDTENTRY_DEBUG		DECLARE_IDTENTRY_IST
398 #define DEFINE_IDTENTRY_DEBUG		DEFINE_IDTENTRY_IST
399 #define DEFINE_IDTENTRY_DEBUG_USER	DEFINE_IDTENTRY_NOIST
400 
401 /**
402  * DECLARE_IDTENTRY_XEN - Declare functions for XEN redirect IDT entry points
403  * @vector:	Vector number (ignored for C)
404  * @func:	Function name of the entry point
405  *
406  * Used for xennmi and xendebug redirections. No DEFINE as this is all ASM
407  * indirection magic.
408  */
409 #define DECLARE_IDTENTRY_XEN(vector, func)				\
410 	asmlinkage void xen_asm_exc_xen##func(void);			\
411 	asmlinkage void asm_exc_xen##func(void)
412 
413 #else /* !__ASSEMBLY__ */
414 
415 /*
416  * The ASM variants for DECLARE_IDTENTRY*() which emit the ASM entry stubs.
417  */
418 #define DECLARE_IDTENTRY(vector, func)					\
419 	idtentry vector asm_##func func has_error_code=0
420 
421 #define DECLARE_IDTENTRY_ERRORCODE(vector, func)			\
422 	idtentry vector asm_##func func has_error_code=1
423 
424 /* Special case for 32bit IRET 'trap'. Do not emit ASM code */
425 #define DECLARE_IDTENTRY_SW(vector, func)
426 
427 #define DECLARE_IDTENTRY_RAW(vector, func)				\
428 	DECLARE_IDTENTRY(vector, func)
429 
430 #define DECLARE_IDTENTRY_RAW_ERRORCODE(vector, func)			\
431 	DECLARE_IDTENTRY_ERRORCODE(vector, func)
432 
433 /* Entries for common/spurious (device) interrupts */
434 #define DECLARE_IDTENTRY_IRQ(vector, func)				\
435 	idtentry_irq vector func
436 
437 /* System vector entries */
438 #define DECLARE_IDTENTRY_SYSVEC(vector, func)				\
439 	idtentry_sysvec vector func
440 
441 #ifdef CONFIG_X86_64
442 # define DECLARE_IDTENTRY_MCE(vector, func)				\
443 	idtentry_mce_db vector asm_##func func
444 
445 # define DECLARE_IDTENTRY_DEBUG(vector, func)				\
446 	idtentry_mce_db vector asm_##func func
447 
448 # define DECLARE_IDTENTRY_DF(vector, func)				\
449 	idtentry_df vector asm_##func func
450 
451 # define DECLARE_IDTENTRY_XENCB(vector, func)				\
452 	DECLARE_IDTENTRY(vector, func)
453 
454 #else
455 # define DECLARE_IDTENTRY_MCE(vector, func)				\
456 	DECLARE_IDTENTRY(vector, func)
457 
458 # define DECLARE_IDTENTRY_DEBUG(vector, func)				\
459 	DECLARE_IDTENTRY(vector, func)
460 
461 /* No ASM emitted for DF as this goes through a C shim */
462 # define DECLARE_IDTENTRY_DF(vector, func)
463 
464 /* No ASM emitted for XEN hypervisor callback */
465 # define DECLARE_IDTENTRY_XENCB(vector, func)
466 
467 #endif
468 
469 /* No ASM code emitted for NMI */
470 #define DECLARE_IDTENTRY_NMI(vector, func)
471 
472 /* XEN NMI and DB wrapper */
473 #define DECLARE_IDTENTRY_XEN(vector, func)				\
474 	idtentry vector asm_exc_xen##func exc_##func has_error_code=0
475 
476 /*
477  * ASM code to emit the common vector entry stubs where each stub is
478  * packed into 8 bytes.
479  *
480  * Note, that the 'pushq imm8' is emitted via '.byte 0x6a, vector' because
481  * GCC treats the local vector variable as unsigned int and would expand
482  * all vectors above 0x7F to a 5 byte push. The original code did an
483  * adjustment of the vector number to be in the signed byte range to avoid
484  * this. While clever it's mindboggling counterintuitive and requires the
485  * odd conversion back to a real vector number in the C entry points. Using
486  * .byte achieves the same thing and the only fixup needed in the C entry
487  * point is to mask off the bits above bit 7 because the push is sign
488  * extending.
489  */
490 	.align 8
491 SYM_CODE_START(irq_entries_start)
492     vector=FIRST_EXTERNAL_VECTOR
493     pos = .
494     .rept (FIRST_SYSTEM_VECTOR - FIRST_EXTERNAL_VECTOR)
495 	UNWIND_HINT_IRET_REGS
496 	.byte	0x6a, vector
497 	jmp	asm_common_interrupt
498 	nop
499 	/* Ensure that the above is 8 bytes max */
500 	. = pos + 8
501     pos=pos+8
502     vector=vector+1
503     .endr
504 SYM_CODE_END(irq_entries_start)
505 
506 #ifdef CONFIG_X86_LOCAL_APIC
507 	.align 8
508 SYM_CODE_START(spurious_entries_start)
509     vector=FIRST_SYSTEM_VECTOR
510     pos = .
511     .rept (NR_VECTORS - FIRST_SYSTEM_VECTOR)
512 	UNWIND_HINT_IRET_REGS
513 	.byte	0x6a, vector
514 	jmp	asm_spurious_interrupt
515 	nop
516 	/* Ensure that the above is 8 bytes max */
517 	. = pos + 8
518     pos=pos+8
519     vector=vector+1
520     .endr
521 SYM_CODE_END(spurious_entries_start)
522 #endif
523 
524 #endif /* __ASSEMBLY__ */
525 
526 /*
527  * The actual entry points. Note that DECLARE_IDTENTRY*() serves two
528  * purposes:
529  *  - provide the function declarations when included from C-Code
530  *  - emit the ASM stubs when included from entry_32/64.S
531  *
532  * This avoids duplicate defines and ensures that everything is consistent.
533  */
534 
535 /*
536  * Dummy trap number so the low level ASM macro vector number checks do not
537  * match which results in emitting plain IDTENTRY stubs without bells and
538  * whistels.
539  */
540 #define X86_TRAP_OTHER		0xFFFF
541 
542 /* Simple exception entry points. No hardware error code */
543 DECLARE_IDTENTRY(X86_TRAP_DE,		exc_divide_error);
544 DECLARE_IDTENTRY(X86_TRAP_OF,		exc_overflow);
545 DECLARE_IDTENTRY(X86_TRAP_BR,		exc_bounds);
546 DECLARE_IDTENTRY(X86_TRAP_NM,		exc_device_not_available);
547 DECLARE_IDTENTRY(X86_TRAP_OLD_MF,	exc_coproc_segment_overrun);
548 DECLARE_IDTENTRY(X86_TRAP_SPURIOUS,	exc_spurious_interrupt_bug);
549 DECLARE_IDTENTRY(X86_TRAP_MF,		exc_coprocessor_error);
550 DECLARE_IDTENTRY(X86_TRAP_XF,		exc_simd_coprocessor_error);
551 
552 /* 32bit software IRET trap. Do not emit ASM code */
553 DECLARE_IDTENTRY_SW(X86_TRAP_IRET,	iret_error);
554 
555 /* Simple exception entries with error code pushed by hardware */
556 DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_TS,	exc_invalid_tss);
557 DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_NP,	exc_segment_not_present);
558 DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_SS,	exc_stack_segment);
559 DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_GP,	exc_general_protection);
560 DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_AC,	exc_alignment_check);
561 
562 /* Raw exception entries which need extra work */
563 DECLARE_IDTENTRY_RAW(X86_TRAP_UD,		exc_invalid_op);
564 DECLARE_IDTENTRY_RAW(X86_TRAP_BP,		exc_int3);
565 DECLARE_IDTENTRY_RAW_ERRORCODE(X86_TRAP_PF,	exc_page_fault);
566 
567 #ifdef CONFIG_X86_MCE
568 DECLARE_IDTENTRY_MCE(X86_TRAP_MC,	exc_machine_check);
569 #endif
570 
571 /* NMI */
572 DECLARE_IDTENTRY_NMI(X86_TRAP_NMI,	exc_nmi);
573 DECLARE_IDTENTRY_XEN(X86_TRAP_NMI,	nmi);
574 
575 /* #DB */
576 DECLARE_IDTENTRY_DEBUG(X86_TRAP_DB,	exc_debug);
577 DECLARE_IDTENTRY_XEN(X86_TRAP_DB,	debug);
578 
579 /* #DF */
580 DECLARE_IDTENTRY_DF(X86_TRAP_DF,	exc_double_fault);
581 
582 #ifdef CONFIG_XEN_PV
583 DECLARE_IDTENTRY_XENCB(X86_TRAP_OTHER,	exc_xen_hypervisor_callback);
584 #endif
585 
586 /* Device interrupts common/spurious */
587 DECLARE_IDTENTRY_IRQ(X86_TRAP_OTHER,	common_interrupt);
588 #ifdef CONFIG_X86_LOCAL_APIC
589 DECLARE_IDTENTRY_IRQ(X86_TRAP_OTHER,	spurious_interrupt);
590 #endif
591 
592 /* System vector entry points */
593 #ifdef CONFIG_X86_LOCAL_APIC
594 DECLARE_IDTENTRY_SYSVEC(ERROR_APIC_VECTOR,		sysvec_error_interrupt);
595 DECLARE_IDTENTRY_SYSVEC(SPURIOUS_APIC_VECTOR,		sysvec_spurious_apic_interrupt);
596 DECLARE_IDTENTRY_SYSVEC(LOCAL_TIMER_VECTOR,		sysvec_apic_timer_interrupt);
597 DECLARE_IDTENTRY_SYSVEC(X86_PLATFORM_IPI_VECTOR,	sysvec_x86_platform_ipi);
598 #endif
599 
600 #ifdef CONFIG_SMP
601 DECLARE_IDTENTRY(RESCHEDULE_VECTOR,			sysvec_reschedule_ipi);
602 DECLARE_IDTENTRY_SYSVEC(IRQ_MOVE_CLEANUP_VECTOR,	sysvec_irq_move_cleanup);
603 DECLARE_IDTENTRY_SYSVEC(REBOOT_VECTOR,			sysvec_reboot);
604 DECLARE_IDTENTRY_SYSVEC(CALL_FUNCTION_SINGLE_VECTOR,	sysvec_call_function_single);
605 DECLARE_IDTENTRY_SYSVEC(CALL_FUNCTION_VECTOR,		sysvec_call_function);
606 #endif
607 
608 #ifdef CONFIG_X86_LOCAL_APIC
609 # ifdef CONFIG_X86_UV
610 DECLARE_IDTENTRY_SYSVEC(UV_BAU_MESSAGE,			sysvec_uv_bau_message);
611 # endif
612 
613 # ifdef CONFIG_X86_MCE_THRESHOLD
614 DECLARE_IDTENTRY_SYSVEC(THRESHOLD_APIC_VECTOR,		sysvec_threshold);
615 # endif
616 
617 # ifdef CONFIG_X86_MCE_AMD
618 DECLARE_IDTENTRY_SYSVEC(DEFERRED_ERROR_VECTOR,		sysvec_deferred_error);
619 # endif
620 
621 # ifdef CONFIG_X86_THERMAL_VECTOR
622 DECLARE_IDTENTRY_SYSVEC(THERMAL_APIC_VECTOR,		sysvec_thermal);
623 # endif
624 
625 # ifdef CONFIG_IRQ_WORK
626 DECLARE_IDTENTRY_SYSVEC(IRQ_WORK_VECTOR,		sysvec_irq_work);
627 # endif
628 #endif
629 
630 #ifdef CONFIG_HAVE_KVM
631 DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_VECTOR,		sysvec_kvm_posted_intr_ipi);
632 DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_WAKEUP_VECTOR,	sysvec_kvm_posted_intr_wakeup_ipi);
633 DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_NESTED_VECTOR,	sysvec_kvm_posted_intr_nested_ipi);
634 #endif
635 
636 #if IS_ENABLED(CONFIG_HYPERV)
637 DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_CALLBACK_VECTOR,	sysvec_hyperv_callback);
638 DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_REENLIGHTENMENT_VECTOR,	sysvec_hyperv_reenlightenment);
639 DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_STIMER0_VECTOR,	sysvec_hyperv_stimer0);
640 #endif
641 
642 #if IS_ENABLED(CONFIG_ACRN_GUEST)
643 DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_CALLBACK_VECTOR,	sysvec_acrn_hv_callback);
644 #endif
645 
646 #ifdef CONFIG_XEN_PVHVM
647 DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_CALLBACK_VECTOR,	sysvec_xen_hvm_callback);
648 #endif
649 
650 #undef X86_TRAP_OTHER
651 
652 #endif
653