xref: /openbmc/linux/arch/x86/include/asm/idtentry.h (revision 11c416e3)
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 /**
357  * DECLARE_IDTENTRY_DF - Declare functions for double fault 32bit variant
358  * @vector:	Vector number (ignored for C)
359  * @func:	Function name of the entry point
360  *
361  * Declares two functions:
362  * - The ASM entry point: asm_##func
363  * - The C handler called from the C shim
364  */
365 #define DECLARE_IDTENTRY_DF(vector, func)				\
366 	asmlinkage void asm_##func(void);				\
367 	__visible void func(struct pt_regs *regs,			\
368 			    unsigned long error_code,			\
369 			    unsigned long address)
370 
371 /**
372  * DEFINE_IDTENTRY_DF - Emit code for double fault on 32bit
373  * @func:	Function name of the entry point
374  *
375  * This is called through the doublefault shim which already provides
376  * cr2 in the address argument.
377  */
378 #define DEFINE_IDTENTRY_DF(func)					\
379 __visible noinstr void func(struct pt_regs *regs,			\
380 			    unsigned long error_code,			\
381 			    unsigned long address)
382 
383 #endif	/* !CONFIG_X86_64 */
384 
385 /* C-Code mapping */
386 #define DECLARE_IDTENTRY_NMI		DECLARE_IDTENTRY_RAW
387 #define DEFINE_IDTENTRY_NMI		DEFINE_IDTENTRY_RAW
388 
389 #ifdef CONFIG_X86_64
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_DEBUG		DECLARE_IDTENTRY_IST
395 #define DEFINE_IDTENTRY_DEBUG		DEFINE_IDTENTRY_IST
396 #define DEFINE_IDTENTRY_DEBUG_USER	DEFINE_IDTENTRY_NOIST
397 #endif
398 
399 #else /* !__ASSEMBLY__ */
400 
401 /*
402  * The ASM variants for DECLARE_IDTENTRY*() which emit the ASM entry stubs.
403  */
404 #define DECLARE_IDTENTRY(vector, func)					\
405 	idtentry vector asm_##func func has_error_code=0
406 
407 #define DECLARE_IDTENTRY_ERRORCODE(vector, func)			\
408 	idtentry vector asm_##func func has_error_code=1
409 
410 /* Special case for 32bit IRET 'trap'. Do not emit ASM code */
411 #define DECLARE_IDTENTRY_SW(vector, func)
412 
413 #define DECLARE_IDTENTRY_RAW(vector, func)				\
414 	DECLARE_IDTENTRY(vector, func)
415 
416 #define DECLARE_IDTENTRY_RAW_ERRORCODE(vector, func)			\
417 	DECLARE_IDTENTRY_ERRORCODE(vector, func)
418 
419 /* Entries for common/spurious (device) interrupts */
420 #define DECLARE_IDTENTRY_IRQ(vector, func)				\
421 	idtentry_irq vector func
422 
423 /* System vector entries */
424 #define DECLARE_IDTENTRY_SYSVEC(vector, func)				\
425 	idtentry_sysvec vector func
426 
427 #ifdef CONFIG_X86_64
428 # define DECLARE_IDTENTRY_MCE(vector, func)				\
429 	idtentry_mce_db vector asm_##func func
430 
431 # define DECLARE_IDTENTRY_DEBUG(vector, func)				\
432 	idtentry_mce_db vector asm_##func func
433 
434 # define DECLARE_IDTENTRY_DF(vector, func)				\
435 	idtentry_df vector asm_##func func
436 
437 # define DECLARE_IDTENTRY_XENCB(vector, func)				\
438 	DECLARE_IDTENTRY(vector, func)
439 
440 #else
441 # define DECLARE_IDTENTRY_MCE(vector, func)				\
442 	DECLARE_IDTENTRY(vector, func)
443 
444 /* No ASM emitted for DF as this goes through a C shim */
445 # define DECLARE_IDTENTRY_DF(vector, func)
446 
447 /* No ASM emitted for XEN hypervisor callback */
448 # define DECLARE_IDTENTRY_XENCB(vector, func)
449 
450 #endif
451 
452 /* No ASM code emitted for NMI */
453 #define DECLARE_IDTENTRY_NMI(vector, func)
454 
455 /*
456  * ASM code to emit the common vector entry stubs where each stub is
457  * packed into 8 bytes.
458  *
459  * Note, that the 'pushq imm8' is emitted via '.byte 0x6a, vector' because
460  * GCC treats the local vector variable as unsigned int and would expand
461  * all vectors above 0x7F to a 5 byte push. The original code did an
462  * adjustment of the vector number to be in the signed byte range to avoid
463  * this. While clever it's mindboggling counterintuitive and requires the
464  * odd conversion back to a real vector number in the C entry points. Using
465  * .byte achieves the same thing and the only fixup needed in the C entry
466  * point is to mask off the bits above bit 7 because the push is sign
467  * extending.
468  */
469 	.align 8
470 SYM_CODE_START(irq_entries_start)
471     vector=FIRST_EXTERNAL_VECTOR
472     .rept (FIRST_SYSTEM_VECTOR - FIRST_EXTERNAL_VECTOR)
473 	UNWIND_HINT_IRET_REGS
474 0 :
475 	.byte	0x6a, vector
476 	jmp	asm_common_interrupt
477 	nop
478 	/* Ensure that the above is 8 bytes max */
479 	. = 0b + 8
480 	vector = vector+1
481     .endr
482 SYM_CODE_END(irq_entries_start)
483 
484 #ifdef CONFIG_X86_LOCAL_APIC
485 	.align 8
486 SYM_CODE_START(spurious_entries_start)
487     vector=FIRST_SYSTEM_VECTOR
488     .rept (NR_VECTORS - FIRST_SYSTEM_VECTOR)
489 	UNWIND_HINT_IRET_REGS
490 0 :
491 	.byte	0x6a, vector
492 	jmp	asm_spurious_interrupt
493 	nop
494 	/* Ensure that the above is 8 bytes max */
495 	. = 0b + 8
496 	vector = vector+1
497     .endr
498 SYM_CODE_END(spurious_entries_start)
499 #endif
500 
501 #endif /* __ASSEMBLY__ */
502 
503 /*
504  * The actual entry points. Note that DECLARE_IDTENTRY*() serves two
505  * purposes:
506  *  - provide the function declarations when included from C-Code
507  *  - emit the ASM stubs when included from entry_32/64.S
508  *
509  * This avoids duplicate defines and ensures that everything is consistent.
510  */
511 
512 /*
513  * Dummy trap number so the low level ASM macro vector number checks do not
514  * match which results in emitting plain IDTENTRY stubs without bells and
515  * whistels.
516  */
517 #define X86_TRAP_OTHER		0xFFFF
518 
519 /* Simple exception entry points. No hardware error code */
520 DECLARE_IDTENTRY(X86_TRAP_DE,		exc_divide_error);
521 DECLARE_IDTENTRY(X86_TRAP_OF,		exc_overflow);
522 DECLARE_IDTENTRY(X86_TRAP_BR,		exc_bounds);
523 DECLARE_IDTENTRY(X86_TRAP_NM,		exc_device_not_available);
524 DECLARE_IDTENTRY(X86_TRAP_OLD_MF,	exc_coproc_segment_overrun);
525 DECLARE_IDTENTRY(X86_TRAP_SPURIOUS,	exc_spurious_interrupt_bug);
526 DECLARE_IDTENTRY(X86_TRAP_MF,		exc_coprocessor_error);
527 DECLARE_IDTENTRY(X86_TRAP_XF,		exc_simd_coprocessor_error);
528 
529 /* 32bit software IRET trap. Do not emit ASM code */
530 DECLARE_IDTENTRY_SW(X86_TRAP_IRET,	iret_error);
531 
532 /* Simple exception entries with error code pushed by hardware */
533 DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_TS,	exc_invalid_tss);
534 DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_NP,	exc_segment_not_present);
535 DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_SS,	exc_stack_segment);
536 DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_GP,	exc_general_protection);
537 DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_AC,	exc_alignment_check);
538 
539 /* Raw exception entries which need extra work */
540 DECLARE_IDTENTRY_RAW(X86_TRAP_UD,		exc_invalid_op);
541 DECLARE_IDTENTRY_RAW(X86_TRAP_BP,		exc_int3);
542 DECLARE_IDTENTRY_RAW_ERRORCODE(X86_TRAP_PF,	exc_page_fault);
543 
544 #ifdef CONFIG_X86_MCE
545 #ifdef CONFIG_X86_64
546 DECLARE_IDTENTRY_MCE(X86_TRAP_MC,	exc_machine_check);
547 #else
548 DECLARE_IDTENTRY_RAW(X86_TRAP_MC,	exc_machine_check);
549 #endif
550 #endif
551 
552 /* NMI */
553 DECLARE_IDTENTRY_NMI(X86_TRAP_NMI,	exc_nmi);
554 #if defined(CONFIG_XEN_PV) && defined(CONFIG_X86_64)
555 DECLARE_IDTENTRY_RAW(X86_TRAP_NMI,	xenpv_exc_nmi);
556 #endif
557 
558 /* #DB */
559 #ifdef CONFIG_X86_64
560 DECLARE_IDTENTRY_DEBUG(X86_TRAP_DB,	exc_debug);
561 #else
562 DECLARE_IDTENTRY_RAW(X86_TRAP_DB,	exc_debug);
563 #endif
564 #if defined(CONFIG_XEN_PV) && defined(CONFIG_X86_64)
565 DECLARE_IDTENTRY_RAW(X86_TRAP_DB,	xenpv_exc_debug);
566 #endif
567 
568 /* #DF */
569 DECLARE_IDTENTRY_DF(X86_TRAP_DF,	exc_double_fault);
570 
571 #ifdef CONFIG_XEN_PV
572 DECLARE_IDTENTRY_XENCB(X86_TRAP_OTHER,	exc_xen_hypervisor_callback);
573 #endif
574 
575 /* Device interrupts common/spurious */
576 DECLARE_IDTENTRY_IRQ(X86_TRAP_OTHER,	common_interrupt);
577 #ifdef CONFIG_X86_LOCAL_APIC
578 DECLARE_IDTENTRY_IRQ(X86_TRAP_OTHER,	spurious_interrupt);
579 #endif
580 
581 /* System vector entry points */
582 #ifdef CONFIG_X86_LOCAL_APIC
583 DECLARE_IDTENTRY_SYSVEC(ERROR_APIC_VECTOR,		sysvec_error_interrupt);
584 DECLARE_IDTENTRY_SYSVEC(SPURIOUS_APIC_VECTOR,		sysvec_spurious_apic_interrupt);
585 DECLARE_IDTENTRY_SYSVEC(LOCAL_TIMER_VECTOR,		sysvec_apic_timer_interrupt);
586 DECLARE_IDTENTRY_SYSVEC(X86_PLATFORM_IPI_VECTOR,	sysvec_x86_platform_ipi);
587 #endif
588 
589 #ifdef CONFIG_SMP
590 DECLARE_IDTENTRY(RESCHEDULE_VECTOR,			sysvec_reschedule_ipi);
591 DECLARE_IDTENTRY_SYSVEC(IRQ_MOVE_CLEANUP_VECTOR,	sysvec_irq_move_cleanup);
592 DECLARE_IDTENTRY_SYSVEC(REBOOT_VECTOR,			sysvec_reboot);
593 DECLARE_IDTENTRY_SYSVEC(CALL_FUNCTION_SINGLE_VECTOR,	sysvec_call_function_single);
594 DECLARE_IDTENTRY_SYSVEC(CALL_FUNCTION_VECTOR,		sysvec_call_function);
595 #endif
596 
597 #ifdef CONFIG_X86_LOCAL_APIC
598 # ifdef CONFIG_X86_UV
599 DECLARE_IDTENTRY_SYSVEC(UV_BAU_MESSAGE,			sysvec_uv_bau_message);
600 # endif
601 
602 # ifdef CONFIG_X86_MCE_THRESHOLD
603 DECLARE_IDTENTRY_SYSVEC(THRESHOLD_APIC_VECTOR,		sysvec_threshold);
604 # endif
605 
606 # ifdef CONFIG_X86_MCE_AMD
607 DECLARE_IDTENTRY_SYSVEC(DEFERRED_ERROR_VECTOR,		sysvec_deferred_error);
608 # endif
609 
610 # ifdef CONFIG_X86_THERMAL_VECTOR
611 DECLARE_IDTENTRY_SYSVEC(THERMAL_APIC_VECTOR,		sysvec_thermal);
612 # endif
613 
614 # ifdef CONFIG_IRQ_WORK
615 DECLARE_IDTENTRY_SYSVEC(IRQ_WORK_VECTOR,		sysvec_irq_work);
616 # endif
617 #endif
618 
619 #ifdef CONFIG_HAVE_KVM
620 DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_VECTOR,		sysvec_kvm_posted_intr_ipi);
621 DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_WAKEUP_VECTOR,	sysvec_kvm_posted_intr_wakeup_ipi);
622 DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_NESTED_VECTOR,	sysvec_kvm_posted_intr_nested_ipi);
623 #endif
624 
625 #if IS_ENABLED(CONFIG_HYPERV)
626 DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_CALLBACK_VECTOR,	sysvec_hyperv_callback);
627 DECLARE_IDTENTRY_SYSVEC(HYPERV_REENLIGHTENMENT_VECTOR,	sysvec_hyperv_reenlightenment);
628 DECLARE_IDTENTRY_SYSVEC(HYPERV_STIMER0_VECTOR,	sysvec_hyperv_stimer0);
629 #endif
630 
631 #if IS_ENABLED(CONFIG_ACRN_GUEST)
632 DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_CALLBACK_VECTOR,	sysvec_acrn_hv_callback);
633 #endif
634 
635 #ifdef CONFIG_XEN_PVHVM
636 DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_CALLBACK_VECTOR,	sysvec_xen_hvm_callback);
637 #endif
638 
639 #undef X86_TRAP_OTHER
640 
641 #endif
642