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