xref: /openbmc/linux/arch/x86/include/asm/idtentry.h (revision a16be368)
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 	lockdep_hardirq_exit();						\
210 	instrumentation_end();						\
211 	idtentry_exit_cond_rcu(regs, rcu_exit);				\
212 }									\
213 									\
214 static __always_inline void __##func(struct pt_regs *regs, u8 vector)
215 
216 /**
217  * DECLARE_IDTENTRY_SYSVEC - Declare functions for system vector entry points
218  * @vector:	Vector number (ignored for C)
219  * @func:	Function name of the entry point
220  *
221  * Declares three functions:
222  * - The ASM entry point: asm_##func
223  * - The XEN PV trap entry point: xen_##func (maybe unused)
224  * - The C handler called from the ASM entry point
225  *
226  * Maps to DECLARE_IDTENTRY().
227  */
228 #define DECLARE_IDTENTRY_SYSVEC(vector, func)				\
229 	DECLARE_IDTENTRY(vector, func)
230 
231 /**
232  * DEFINE_IDTENTRY_SYSVEC - Emit code for system vector IDT entry points
233  * @func:	Function name of the entry point
234  *
235  * idtentry_enter/exit() and irq_enter/exit_rcu() are invoked before the
236  * function body. KVM L1D flush request is set.
237  *
238  * Runs the function on the interrupt stack if the entry hit kernel mode
239  */
240 #define DEFINE_IDTENTRY_SYSVEC(func)					\
241 static void __##func(struct pt_regs *regs);				\
242 									\
243 __visible noinstr void func(struct pt_regs *regs)			\
244 {									\
245 	bool rcu_exit = idtentry_enter_cond_rcu(regs);			\
246 									\
247 	instrumentation_begin();					\
248 	irq_enter_rcu();						\
249 	kvm_set_cpu_l1tf_flush_l1d();					\
250 	run_on_irqstack_cond(__##func, regs, regs);			\
251 	irq_exit_rcu();							\
252 	lockdep_hardirq_exit();						\
253 	instrumentation_end();						\
254 	idtentry_exit_cond_rcu(regs, rcu_exit);				\
255 }									\
256 									\
257 static noinline void __##func(struct pt_regs *regs)
258 
259 /**
260  * DEFINE_IDTENTRY_SYSVEC_SIMPLE - Emit code for simple system vector IDT
261  *				   entry points
262  * @func:	Function name of the entry point
263  *
264  * Runs the function on the interrupted stack. No switch to IRQ stack and
265  * only the minimal __irq_enter/exit() handling.
266  *
267  * Only use for 'empty' vectors like reschedule IPI and KVM posted
268  * interrupt vectors.
269  */
270 #define DEFINE_IDTENTRY_SYSVEC_SIMPLE(func)				\
271 static __always_inline void __##func(struct pt_regs *regs);		\
272 									\
273 __visible noinstr void func(struct pt_regs *regs)			\
274 {									\
275 	bool rcu_exit = idtentry_enter_cond_rcu(regs);			\
276 									\
277 	instrumentation_begin();					\
278 	__irq_enter_raw();						\
279 	kvm_set_cpu_l1tf_flush_l1d();					\
280 	__##func (regs);						\
281 	__irq_exit_raw();						\
282 	instrumentation_end();						\
283 	idtentry_exit_cond_rcu(regs, rcu_exit);				\
284 }									\
285 									\
286 static __always_inline void __##func(struct pt_regs *regs)
287 
288 /**
289  * DECLARE_IDTENTRY_XENCB - Declare functions for XEN HV callback entry point
290  * @vector:	Vector number (ignored for C)
291  * @func:	Function name of the entry point
292  *
293  * Declares three functions:
294  * - The ASM entry point: asm_##func
295  * - The XEN PV trap entry point: xen_##func (maybe unused)
296  * - The C handler called from the ASM entry point
297  *
298  * Maps to DECLARE_IDTENTRY(). Distinct entry point to handle the 32/64-bit
299  * difference
300  */
301 #define DECLARE_IDTENTRY_XENCB(vector, func)				\
302 	DECLARE_IDTENTRY(vector, func)
303 
304 #ifdef CONFIG_X86_64
305 /**
306  * DECLARE_IDTENTRY_IST - Declare functions for IST handling IDT entry points
307  * @vector:	Vector number (ignored for C)
308  * @func:	Function name of the entry point
309  *
310  * Maps to DECLARE_IDTENTRY_RAW, but declares also the NOIST C handler
311  * which is called from the ASM entry point on user mode entry
312  */
313 #define DECLARE_IDTENTRY_IST(vector, func)				\
314 	DECLARE_IDTENTRY_RAW(vector, func);				\
315 	__visible void noist_##func(struct pt_regs *regs)
316 
317 /**
318  * DEFINE_IDTENTRY_IST - Emit code for IST entry points
319  * @func:	Function name of the entry point
320  *
321  * Maps to DEFINE_IDTENTRY_RAW
322  */
323 #define DEFINE_IDTENTRY_IST(func)					\
324 	DEFINE_IDTENTRY_RAW(func)
325 
326 /**
327  * DEFINE_IDTENTRY_NOIST - Emit code for NOIST entry points which
328  *			   belong to a IST entry point (MCE, DB)
329  * @func:	Function name of the entry point. Must be the same as
330  *		the function name of the corresponding IST variant
331  *
332  * Maps to DEFINE_IDTENTRY_RAW().
333  */
334 #define DEFINE_IDTENTRY_NOIST(func)					\
335 	DEFINE_IDTENTRY_RAW(noist_##func)
336 
337 /**
338  * DECLARE_IDTENTRY_DF - Declare functions for double fault
339  * @vector:	Vector number (ignored for C)
340  * @func:	Function name of the entry point
341  *
342  * Maps to DECLARE_IDTENTRY_RAW_ERRORCODE
343  */
344 #define DECLARE_IDTENTRY_DF(vector, func)				\
345 	DECLARE_IDTENTRY_RAW_ERRORCODE(vector, func)
346 
347 /**
348  * DEFINE_IDTENTRY_DF - Emit code for double fault
349  * @func:	Function name of the entry point
350  *
351  * Maps to DEFINE_IDTENTRY_RAW_ERRORCODE
352  */
353 #define DEFINE_IDTENTRY_DF(func)					\
354 	DEFINE_IDTENTRY_RAW_ERRORCODE(func)
355 
356 #else	/* CONFIG_X86_64 */
357 
358 /* Maps to a regular IDTENTRY on 32bit for now */
359 # define DECLARE_IDTENTRY_IST		DECLARE_IDTENTRY
360 # define DEFINE_IDTENTRY_IST		DEFINE_IDTENTRY
361 
362 /**
363  * DECLARE_IDTENTRY_DF - Declare functions for double fault 32bit variant
364  * @vector:	Vector number (ignored for C)
365  * @func:	Function name of the entry point
366  *
367  * Declares two functions:
368  * - The ASM entry point: asm_##func
369  * - The C handler called from the C shim
370  */
371 #define DECLARE_IDTENTRY_DF(vector, func)				\
372 	asmlinkage void asm_##func(void);				\
373 	__visible void func(struct pt_regs *regs,			\
374 			    unsigned long error_code,			\
375 			    unsigned long address)
376 
377 /**
378  * DEFINE_IDTENTRY_DF - Emit code for double fault on 32bit
379  * @func:	Function name of the entry point
380  *
381  * This is called through the doublefault shim which already provides
382  * cr2 in the address argument.
383  */
384 #define DEFINE_IDTENTRY_DF(func)					\
385 __visible noinstr void func(struct pt_regs *regs,			\
386 			    unsigned long error_code,			\
387 			    unsigned long address)
388 
389 #endif	/* !CONFIG_X86_64 */
390 
391 /* C-Code mapping */
392 #define DECLARE_IDTENTRY_MCE		DECLARE_IDTENTRY_IST
393 #define DEFINE_IDTENTRY_MCE		DEFINE_IDTENTRY_IST
394 #define DEFINE_IDTENTRY_MCE_USER	DEFINE_IDTENTRY_NOIST
395 
396 #define DECLARE_IDTENTRY_NMI		DECLARE_IDTENTRY_IST
397 #define DEFINE_IDTENTRY_NMI		DEFINE_IDTENTRY_IST
398 
399 #define DECLARE_IDTENTRY_DEBUG		DECLARE_IDTENTRY_IST
400 #define DEFINE_IDTENTRY_DEBUG		DEFINE_IDTENTRY_IST
401 #define DEFINE_IDTENTRY_DEBUG_USER	DEFINE_IDTENTRY_NOIST
402 
403 /**
404  * DECLARE_IDTENTRY_XEN - Declare functions for XEN redirect IDT entry points
405  * @vector:	Vector number (ignored for C)
406  * @func:	Function name of the entry point
407  *
408  * Used for xennmi and xendebug redirections. No DEFINE as this is all ASM
409  * indirection magic.
410  */
411 #define DECLARE_IDTENTRY_XEN(vector, func)				\
412 	asmlinkage void xen_asm_exc_xen##func(void);			\
413 	asmlinkage void asm_exc_xen##func(void)
414 
415 #else /* !__ASSEMBLY__ */
416 
417 /*
418  * The ASM variants for DECLARE_IDTENTRY*() which emit the ASM entry stubs.
419  */
420 #define DECLARE_IDTENTRY(vector, func)					\
421 	idtentry vector asm_##func func has_error_code=0
422 
423 #define DECLARE_IDTENTRY_ERRORCODE(vector, func)			\
424 	idtentry vector asm_##func func has_error_code=1
425 
426 /* Special case for 32bit IRET 'trap'. Do not emit ASM code */
427 #define DECLARE_IDTENTRY_SW(vector, func)
428 
429 #define DECLARE_IDTENTRY_RAW(vector, func)				\
430 	DECLARE_IDTENTRY(vector, func)
431 
432 #define DECLARE_IDTENTRY_RAW_ERRORCODE(vector, func)			\
433 	DECLARE_IDTENTRY_ERRORCODE(vector, func)
434 
435 /* Entries for common/spurious (device) interrupts */
436 #define DECLARE_IDTENTRY_IRQ(vector, func)				\
437 	idtentry_irq vector func
438 
439 /* System vector entries */
440 #define DECLARE_IDTENTRY_SYSVEC(vector, func)				\
441 	idtentry_sysvec vector func
442 
443 #ifdef CONFIG_X86_64
444 # define DECLARE_IDTENTRY_MCE(vector, func)				\
445 	idtentry_mce_db vector asm_##func func
446 
447 # define DECLARE_IDTENTRY_DEBUG(vector, func)				\
448 	idtentry_mce_db vector asm_##func func
449 
450 # define DECLARE_IDTENTRY_DF(vector, func)				\
451 	idtentry_df vector asm_##func func
452 
453 # define DECLARE_IDTENTRY_XENCB(vector, func)				\
454 	DECLARE_IDTENTRY(vector, func)
455 
456 #else
457 # define DECLARE_IDTENTRY_MCE(vector, func)				\
458 	DECLARE_IDTENTRY(vector, func)
459 
460 # define DECLARE_IDTENTRY_DEBUG(vector, func)				\
461 	DECLARE_IDTENTRY(vector, func)
462 
463 /* No ASM emitted for DF as this goes through a C shim */
464 # define DECLARE_IDTENTRY_DF(vector, func)
465 
466 /* No ASM emitted for XEN hypervisor callback */
467 # define DECLARE_IDTENTRY_XENCB(vector, func)
468 
469 #endif
470 
471 /* No ASM code emitted for NMI */
472 #define DECLARE_IDTENTRY_NMI(vector, func)
473 
474 /* XEN NMI and DB wrapper */
475 #define DECLARE_IDTENTRY_XEN(vector, func)				\
476 	idtentry vector asm_exc_xen##func exc_##func has_error_code=0
477 
478 /*
479  * ASM code to emit the common vector entry stubs where each stub is
480  * packed into 8 bytes.
481  *
482  * Note, that the 'pushq imm8' is emitted via '.byte 0x6a, vector' because
483  * GCC treats the local vector variable as unsigned int and would expand
484  * all vectors above 0x7F to a 5 byte push. The original code did an
485  * adjustment of the vector number to be in the signed byte range to avoid
486  * this. While clever it's mindboggling counterintuitive and requires the
487  * odd conversion back to a real vector number in the C entry points. Using
488  * .byte achieves the same thing and the only fixup needed in the C entry
489  * point is to mask off the bits above bit 7 because the push is sign
490  * extending.
491  */
492 	.align 8
493 SYM_CODE_START(irq_entries_start)
494     vector=FIRST_EXTERNAL_VECTOR
495     pos = .
496     .rept (FIRST_SYSTEM_VECTOR - FIRST_EXTERNAL_VECTOR)
497 	UNWIND_HINT_IRET_REGS
498 	.byte	0x6a, vector
499 	jmp	asm_common_interrupt
500 	nop
501 	/* Ensure that the above is 8 bytes max */
502 	. = pos + 8
503     pos=pos+8
504     vector=vector+1
505     .endr
506 SYM_CODE_END(irq_entries_start)
507 
508 #ifdef CONFIG_X86_LOCAL_APIC
509 	.align 8
510 SYM_CODE_START(spurious_entries_start)
511     vector=FIRST_SYSTEM_VECTOR
512     pos = .
513     .rept (NR_VECTORS - FIRST_SYSTEM_VECTOR)
514 	UNWIND_HINT_IRET_REGS
515 	.byte	0x6a, vector
516 	jmp	asm_spurious_interrupt
517 	nop
518 	/* Ensure that the above is 8 bytes max */
519 	. = pos + 8
520     pos=pos+8
521     vector=vector+1
522     .endr
523 SYM_CODE_END(spurious_entries_start)
524 #endif
525 
526 #endif /* __ASSEMBLY__ */
527 
528 /*
529  * The actual entry points. Note that DECLARE_IDTENTRY*() serves two
530  * purposes:
531  *  - provide the function declarations when included from C-Code
532  *  - emit the ASM stubs when included from entry_32/64.S
533  *
534  * This avoids duplicate defines and ensures that everything is consistent.
535  */
536 
537 /*
538  * Dummy trap number so the low level ASM macro vector number checks do not
539  * match which results in emitting plain IDTENTRY stubs without bells and
540  * whistels.
541  */
542 #define X86_TRAP_OTHER		0xFFFF
543 
544 /* Simple exception entry points. No hardware error code */
545 DECLARE_IDTENTRY(X86_TRAP_DE,		exc_divide_error);
546 DECLARE_IDTENTRY(X86_TRAP_OF,		exc_overflow);
547 DECLARE_IDTENTRY(X86_TRAP_BR,		exc_bounds);
548 DECLARE_IDTENTRY(X86_TRAP_UD,		exc_invalid_op);
549 DECLARE_IDTENTRY(X86_TRAP_NM,		exc_device_not_available);
550 DECLARE_IDTENTRY(X86_TRAP_OLD_MF,	exc_coproc_segment_overrun);
551 DECLARE_IDTENTRY(X86_TRAP_SPURIOUS,	exc_spurious_interrupt_bug);
552 DECLARE_IDTENTRY(X86_TRAP_MF,		exc_coprocessor_error);
553 DECLARE_IDTENTRY(X86_TRAP_XF,		exc_simd_coprocessor_error);
554 
555 /* 32bit software IRET trap. Do not emit ASM code */
556 DECLARE_IDTENTRY_SW(X86_TRAP_IRET,	iret_error);
557 
558 /* Simple exception entries with error code pushed by hardware */
559 DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_TS,	exc_invalid_tss);
560 DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_NP,	exc_segment_not_present);
561 DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_SS,	exc_stack_segment);
562 DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_GP,	exc_general_protection);
563 DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_AC,	exc_alignment_check);
564 
565 /* Raw exception entries which need extra work */
566 DECLARE_IDTENTRY_RAW(X86_TRAP_BP,		exc_int3);
567 DECLARE_IDTENTRY_RAW_ERRORCODE(X86_TRAP_PF,	exc_page_fault);
568 
569 #ifdef CONFIG_X86_MCE
570 DECLARE_IDTENTRY_MCE(X86_TRAP_MC,	exc_machine_check);
571 #endif
572 
573 /* NMI */
574 DECLARE_IDTENTRY_NMI(X86_TRAP_NMI,	exc_nmi);
575 DECLARE_IDTENTRY_XEN(X86_TRAP_NMI,	nmi);
576 
577 /* #DB */
578 DECLARE_IDTENTRY_DEBUG(X86_TRAP_DB,	exc_debug);
579 DECLARE_IDTENTRY_XEN(X86_TRAP_DB,	debug);
580 
581 /* #DF */
582 DECLARE_IDTENTRY_DF(X86_TRAP_DF,	exc_double_fault);
583 
584 #ifdef CONFIG_XEN_PV
585 DECLARE_IDTENTRY_XENCB(X86_TRAP_OTHER,	exc_xen_hypervisor_callback);
586 #endif
587 
588 /* Device interrupts common/spurious */
589 DECLARE_IDTENTRY_IRQ(X86_TRAP_OTHER,	common_interrupt);
590 #ifdef CONFIG_X86_LOCAL_APIC
591 DECLARE_IDTENTRY_IRQ(X86_TRAP_OTHER,	spurious_interrupt);
592 #endif
593 
594 /* System vector entry points */
595 #ifdef CONFIG_X86_LOCAL_APIC
596 DECLARE_IDTENTRY_SYSVEC(ERROR_APIC_VECTOR,		sysvec_error_interrupt);
597 DECLARE_IDTENTRY_SYSVEC(SPURIOUS_APIC_VECTOR,		sysvec_spurious_apic_interrupt);
598 DECLARE_IDTENTRY_SYSVEC(LOCAL_TIMER_VECTOR,		sysvec_apic_timer_interrupt);
599 DECLARE_IDTENTRY_SYSVEC(X86_PLATFORM_IPI_VECTOR,	sysvec_x86_platform_ipi);
600 #endif
601 
602 #ifdef CONFIG_SMP
603 DECLARE_IDTENTRY_SYSVEC(IRQ_MOVE_CLEANUP_VECTOR,	sysvec_irq_move_cleanup);
604 DECLARE_IDTENTRY_SYSVEC(REBOOT_VECTOR,			sysvec_reboot);
605 DECLARE_IDTENTRY_SYSVEC(CALL_FUNCTION_SINGLE_VECTOR,	sysvec_call_function_single);
606 DECLARE_IDTENTRY_SYSVEC(CALL_FUNCTION_VECTOR,		sysvec_call_function);
607 #endif
608 
609 #ifdef CONFIG_X86_LOCAL_APIC
610 # ifdef CONFIG_X86_UV
611 DECLARE_IDTENTRY_SYSVEC(UV_BAU_MESSAGE,			sysvec_uv_bau_message);
612 # endif
613 
614 # ifdef CONFIG_X86_MCE_THRESHOLD
615 DECLARE_IDTENTRY_SYSVEC(THRESHOLD_APIC_VECTOR,		sysvec_threshold);
616 # endif
617 
618 # ifdef CONFIG_X86_MCE_AMD
619 DECLARE_IDTENTRY_SYSVEC(DEFERRED_ERROR_VECTOR,		sysvec_deferred_error);
620 # endif
621 
622 # ifdef CONFIG_X86_THERMAL_VECTOR
623 DECLARE_IDTENTRY_SYSVEC(THERMAL_APIC_VECTOR,		sysvec_thermal);
624 # endif
625 
626 # ifdef CONFIG_IRQ_WORK
627 DECLARE_IDTENTRY_SYSVEC(IRQ_WORK_VECTOR,		sysvec_irq_work);
628 # endif
629 #endif
630 
631 #ifdef CONFIG_HAVE_KVM
632 DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_VECTOR,		sysvec_kvm_posted_intr_ipi);
633 DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_WAKEUP_VECTOR,	sysvec_kvm_posted_intr_wakeup_ipi);
634 DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_NESTED_VECTOR,	sysvec_kvm_posted_intr_nested_ipi);
635 #endif
636 
637 #if IS_ENABLED(CONFIG_HYPERV)
638 DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_CALLBACK_VECTOR,	sysvec_hyperv_callback);
639 DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_REENLIGHTENMENT_VECTOR,	sysvec_hyperv_reenlightenment);
640 DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_STIMER0_VECTOR,	sysvec_hyperv_stimer0);
641 #endif
642 
643 #if IS_ENABLED(CONFIG_ACRN_GUEST)
644 DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_CALLBACK_VECTOR,	sysvec_acrn_hv_callback);
645 #endif
646 
647 #undef X86_TRAP_OTHER
648 
649 #endif
650