Merge branch 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 apic updates from Thomas Gleixner:
"This update provides:

- Cleanup of the IDT management including the removal of the extra
tracing IDT. A first step to cleanup the vector management code.

- The removal of the paravirt op adjust_exception_frame. This is a
XEN specific issue, but merged through this branch to avoid nasty
merge collisions

- Prevent dmesg spam about the TSC DEADLINE bug, when the CPU has
disabled the TSC DEADLINE timer in CPUID.

- Adjust a debug message in the ioapic code to print out the
information correctly"

* 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (51 commits)
x86/idt: Fix the X86_TRAP_BP gate
x86/xen: Get rid of paravirt op adjust_exception_frame
x86/eisa: Add missing include
x86/idt: Remove superfluous ALIGNment
x86/apic: Silence "FW_BUG TSC_DEADLINE disabled due to Errata" on CPUs without the feature
x86/idt: Remove the tracing IDT leftovers
x86/idt: Hide set_intr_gate()
x86/idt: Simplify alloc_intr_gate()
x86/idt: Deinline setup functions
x86/idt: Remove unused functions/inlines
x86/idt: Move interrupt gate initialization to IDT code
x86/idt: Move APIC gate initialization to tables
x86/idt: Move regular trap init to tables
x86/idt: Move IST stack based traps to table init
x86/idt: Move debug stack init to table based
x86/idt: Switch early trap init to IDT tables
x86/idt: Prepare for table based init
x86/idt: Move early IDT setup out of 32-bit asm
x86/idt: Move early IDT handler setup to IDT code
x86/idt: Consolidate IDT invalidation
...

+908 -1084
+4 -4
arch/x86/boot/compressed/eboot.c
··· 1058 1058 desc->s = DESC_TYPE_CODE_DATA; 1059 1059 desc->dpl = 0; 1060 1060 desc->p = 1; 1061 - desc->limit = 0xf; 1061 + desc->limit1 = 0xf; 1062 1062 desc->avl = 0; 1063 1063 desc->l = 0; 1064 1064 desc->d = SEG_OP_SIZE_32BIT; ··· 1078 1078 desc->s = DESC_TYPE_CODE_DATA; 1079 1079 desc->dpl = 0; 1080 1080 desc->p = 1; 1081 - desc->limit = 0xf; 1081 + desc->limit1 = 0xf; 1082 1082 desc->avl = 0; 1083 1083 if (IS_ENABLED(CONFIG_X86_64)) { 1084 1084 desc->l = 1; ··· 1099 1099 desc->s = DESC_TYPE_CODE_DATA; 1100 1100 desc->dpl = 0; 1101 1101 desc->p = 1; 1102 - desc->limit = 0xf; 1102 + desc->limit1 = 0xf; 1103 1103 desc->avl = 0; 1104 1104 desc->l = 0; 1105 1105 desc->d = SEG_OP_SIZE_32BIT; ··· 1116 1116 desc->s = 0; 1117 1117 desc->dpl = 0; 1118 1118 desc->p = 1; 1119 - desc->limit = 0x0; 1119 + desc->limit1 = 0x0; 1120 1120 desc->avl = 0; 1121 1121 desc->l = 0; 1122 1122 desc->d = 0;
+2 -18
arch/x86/entry/entry_32.S
··· 673 673 jmp ret_from_intr; \ 674 674 ENDPROC(name) 675 675 676 - 677 - #ifdef CONFIG_TRACING 678 - # define TRACE_BUILD_INTERRUPT(name, nr) BUILD_INTERRUPT3(trace_##name, nr, smp_trace_##name) 679 - #else 680 - # define TRACE_BUILD_INTERRUPT(name, nr) 681 - #endif 682 - 683 676 #define BUILD_INTERRUPT(name, nr) \ 684 677 BUILD_INTERRUPT3(name, nr, smp_##name); \ 685 - TRACE_BUILD_INTERRUPT(name, nr) 686 678 687 679 /* The include is where all of the SMP etc. interrupts come from */ 688 680 #include <asm/entry_arch.h> ··· 872 880 ENDPROC(xen_failsafe_callback) 873 881 874 882 BUILD_INTERRUPT3(xen_hvm_callback_vector, HYPERVISOR_CALLBACK_VECTOR, 875 - xen_evtchn_do_upcall) 883 + xen_evtchn_do_upcall) 876 884 877 885 #endif /* CONFIG_XEN */ 878 886 879 887 #if IS_ENABLED(CONFIG_HYPERV) 880 888 881 889 BUILD_INTERRUPT3(hyperv_callback_vector, HYPERVISOR_CALLBACK_VECTOR, 882 - hyperv_vector_handler) 890 + hyperv_vector_handler) 883 891 884 892 #endif /* CONFIG_HYPERV */ 885 - 886 - #ifdef CONFIG_TRACING 887 - ENTRY(trace_page_fault) 888 - ASM_CLAC 889 - pushl $trace_do_page_fault 890 - jmp common_exception 891 - END(trace_page_fault) 892 - #endif 893 893 894 894 ENTRY(page_fault) 895 895 ASM_CLAC
+5 -44
arch/x86/entry/entry_64.S
··· 748 748 END(\sym) 749 749 .endm 750 750 751 - #ifdef CONFIG_TRACING 752 - #define trace(sym) trace_##sym 753 - #define smp_trace(sym) smp_trace_##sym 754 - 755 - .macro trace_apicinterrupt num sym 756 - apicinterrupt3 \num trace(\sym) smp_trace(\sym) 757 - .endm 758 - #else 759 - .macro trace_apicinterrupt num sym do_sym 760 - .endm 761 - #endif 762 - 763 751 /* Make sure APIC interrupt handlers end up in the irqentry section: */ 764 752 #define PUSH_SECTION_IRQENTRY .pushsection .irqentry.text, "ax" 765 753 #define POP_SECTION_IRQENTRY .popsection ··· 755 767 .macro apicinterrupt num sym do_sym 756 768 PUSH_SECTION_IRQENTRY 757 769 apicinterrupt3 \num \sym \do_sym 758 - trace_apicinterrupt \num \sym 759 770 POP_SECTION_IRQENTRY 760 771 .endm 761 772 ··· 816 829 .endif 817 830 818 831 ASM_CLAC 819 - PARAVIRT_ADJUST_EXCEPTION_FRAME 820 832 821 833 .ifeq \has_error_code 822 834 pushq $-1 /* ORIG_RAX: no syscall to restart */ ··· 899 913 END(\sym) 900 914 .endm 901 915 902 - #ifdef CONFIG_TRACING 903 - .macro trace_idtentry sym do_sym has_error_code:req 904 - idtentry trace(\sym) trace(\do_sym) has_error_code=\has_error_code 905 - idtentry \sym \do_sym has_error_code=\has_error_code 906 - .endm 907 - #else 908 - .macro trace_idtentry sym do_sym has_error_code:req 909 - idtentry \sym \do_sym has_error_code=\has_error_code 910 - .endm 911 - #endif 912 - 913 916 idtentry divide_error do_divide_error has_error_code=0 914 917 idtentry overflow do_overflow has_error_code=0 915 918 idtentry bounds do_bounds has_error_code=0 ··· 961 986 ENDPROC(do_softirq_own_stack) 962 987 963 988 #ifdef CONFIG_XEN 964 - idtentry xen_hypervisor_callback xen_do_hypervisor_callback has_error_code=0 989 + idtentry hypervisor_callback xen_do_hypervisor_callback has_error_code=0 965 990 966 991 /* 967 992 * A note on the "critical region" in our callback handler. ··· 1028 1053 movq 8(%rsp), %r11 1029 1054 addq $0x30, %rsp 1030 1055 pushq $0 /* RIP */ 1031 - pushq %r11 1032 - pushq %rcx 1033 1056 UNWIND_HINT_IRET_REGS offset=8 1034 1057 jmp general_protection 1035 1058 1: /* Segment mismatch => Category 1 (Bad segment). Retry the IRET. */ ··· 1058 1085 idtentry stack_segment do_stack_segment has_error_code=1 1059 1086 1060 1087 #ifdef CONFIG_XEN 1061 - idtentry xen_debug do_debug has_error_code=0 1062 - idtentry xen_int3 do_int3 has_error_code=0 1063 - idtentry xen_stack_segment do_stack_segment has_error_code=1 1088 + idtentry xendebug do_debug has_error_code=0 1089 + idtentry xenint3 do_int3 has_error_code=0 1064 1090 #endif 1065 1091 1066 1092 idtentry general_protection do_general_protection has_error_code=1 1067 - trace_idtentry page_fault do_page_fault has_error_code=1 1093 + idtentry page_fault do_page_fault has_error_code=1 1068 1094 1069 1095 #ifdef CONFIG_KVM_GUEST 1070 1096 idtentry async_page_fault do_async_page_fault has_error_code=1 ··· 1223 1251 END(error_exit) 1224 1252 1225 1253 /* Runs on exception stack */ 1254 + /* XXX: broken on Xen PV */ 1226 1255 ENTRY(nmi) 1227 1256 UNWIND_HINT_IRET_REGS 1228 - /* 1229 - * Fix up the exception frame if we're on Xen. 1230 - * PARAVIRT_ADJUST_EXCEPTION_FRAME is guaranteed to push at most 1231 - * one value to the stack on native, so it may clobber the rdx 1232 - * scratch slot, but it won't clobber any of the important 1233 - * slots past it. 1234 - * 1235 - * Xen is a different story, because the Xen frame itself overlaps 1236 - * the "NMI executing" variable. 1237 - */ 1238 - PARAVIRT_ADJUST_EXCEPTION_FRAME 1239 - 1240 1257 /* 1241 1258 * We allow breakpoints in NMIs. If a breakpoint occurs, then 1242 1259 * the iretq it performs will take us out of NMI context.
-1
arch/x86/entry/entry_64_compat.S
··· 293 293 /* 294 294 * Interrupts are off on entry. 295 295 */ 296 - PARAVIRT_ADJUST_EXCEPTION_FRAME 297 296 ASM_CLAC /* Do this early to minimize exposure */ 298 297 SWAPGS 299 298
+1 -1
arch/x86/entry/vdso/vma.c
··· 351 351 * and 8 bits for the node) 352 352 */ 353 353 d.limit0 = cpu | ((node & 0xf) << 12); 354 - d.limit = node >> 4; 354 + d.limit1 = node >> 4; 355 355 d.type = 5; /* RO data, expand down, accessed */ 356 356 d.dpl = 3; /* Visible to user code */ 357 357 d.s = 1; /* Not a system segment */
+46 -202
arch/x86/include/asm/desc.h
··· 5 5 #include <asm/ldt.h> 6 6 #include <asm/mmu.h> 7 7 #include <asm/fixmap.h> 8 + #include <asm/irq_vectors.h> 8 9 9 10 #include <linux/smp.h> 10 11 #include <linux/percpu.h> ··· 23 22 desc->s = 1; 24 23 desc->dpl = 0x3; 25 24 desc->p = info->seg_not_present ^ 1; 26 - desc->limit = (info->limit & 0xf0000) >> 16; 25 + desc->limit1 = (info->limit & 0xf0000) >> 16; 27 26 desc->avl = info->useable; 28 27 desc->d = info->seg_32bit; 29 28 desc->g = info->limit_in_pages; ··· 84 83 return per_cpu_ptr_to_phys(get_cpu_gdt_rw(cpu)); 85 84 } 86 85 87 - #ifdef CONFIG_X86_64 88 - 89 86 static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func, 90 87 unsigned dpl, unsigned ist, unsigned seg) 91 88 { 92 - gate->offset_low = PTR_LOW(func); 89 + gate->offset_low = (u16) func; 90 + gate->bits.p = 1; 91 + gate->bits.dpl = dpl; 92 + gate->bits.zero = 0; 93 + gate->bits.type = type; 94 + gate->offset_middle = (u16) (func >> 16); 95 + #ifdef CONFIG_X86_64 93 96 gate->segment = __KERNEL_CS; 94 - gate->ist = ist; 95 - gate->p = 1; 96 - gate->dpl = dpl; 97 - gate->zero0 = 0; 98 - gate->zero1 = 0; 99 - gate->type = type; 100 - gate->offset_middle = PTR_MIDDLE(func); 101 - gate->offset_high = PTR_HIGH(func); 102 - } 103 - 97 + gate->bits.ist = ist; 98 + gate->reserved = 0; 99 + gate->offset_high = (u32) (func >> 32); 104 100 #else 105 - static inline void pack_gate(gate_desc *gate, unsigned char type, 106 - unsigned long base, unsigned dpl, unsigned flags, 107 - unsigned short seg) 108 - { 109 - gate->a = (seg << 16) | (base & 0xffff); 110 - gate->b = (base & 0xffff0000) | (((0x80 | type | (dpl << 5)) & 0xff) << 8); 111 - } 112 - 101 + gate->segment = seg; 102 + gate->bits.ist = 0; 113 103 #endif 104 + } 114 105 115 106 static inline int desc_empty(const void *ptr) 116 107 { ··· 166 173 memcpy(&gdt[entry], desc, size); 167 174 } 168 175 169 - static inline void pack_descriptor(struct desc_struct *desc, unsigned long base, 170 - unsigned long limit, unsigned char type, 171 - unsigned char flags) 176 + static inline void set_tssldt_descriptor(void *d, unsigned long addr, 177 + unsigned type, unsigned size) 172 178 { 173 - desc->a = ((base & 0xffff) << 16) | (limit & 0xffff); 174 - desc->b = (base & 0xff000000) | ((base & 0xff0000) >> 16) | 175 - (limit & 0x000f0000) | ((type & 0xff) << 8) | 176 - ((flags & 0xf) << 20); 177 - desc->p = 1; 178 - } 179 - 180 - 181 - static inline void set_tssldt_descriptor(void *d, unsigned long addr, unsigned type, unsigned size) 182 - { 183 - #ifdef CONFIG_X86_64 184 - struct ldttss_desc64 *desc = d; 179 + struct ldttss_desc *desc = d; 185 180 186 181 memset(desc, 0, sizeof(*desc)); 187 182 188 - desc->limit0 = size & 0xFFFF; 189 - desc->base0 = PTR_LOW(addr); 190 - desc->base1 = PTR_MIDDLE(addr) & 0xFF; 183 + desc->limit0 = (u16) size; 184 + desc->base0 = (u16) addr; 185 + desc->base1 = (addr >> 16) & 0xFF; 191 186 desc->type = type; 192 187 desc->p = 1; 193 188 desc->limit1 = (size >> 16) & 0xF; 194 - desc->base2 = (PTR_MIDDLE(addr) >> 8) & 0xFF; 195 - desc->base3 = PTR_HIGH(addr); 196 - #else 197 - pack_descriptor((struct desc_struct *)d, addr, size, 0x80 | type, 0); 189 + desc->base2 = (addr >> 24) & 0xFF; 190 + #ifdef CONFIG_X86_64 191 + desc->base3 = (u32) (addr >> 32); 198 192 #endif 199 193 } 200 194 ··· 381 401 382 402 static inline unsigned long get_desc_limit(const struct desc_struct *desc) 383 403 { 384 - return desc->limit0 | (desc->limit << 16); 404 + return desc->limit0 | (desc->limit1 << 16); 385 405 } 386 406 387 407 static inline void set_desc_limit(struct desc_struct *desc, unsigned long limit) 388 408 { 389 409 desc->limit0 = limit & 0xffff; 390 - desc->limit = (limit >> 16) & 0xf; 410 + desc->limit1 = (limit >> 16) & 0xf; 391 411 } 392 412 393 - #ifdef CONFIG_X86_64 394 - static inline void set_nmi_gate(int gate, void *addr) 395 - { 396 - gate_desc s; 413 + void update_intr_gate(unsigned int n, const void *addr); 414 + void alloc_intr_gate(unsigned int n, const void *addr); 397 415 398 - pack_gate(&s, GATE_INTERRUPT, (unsigned long)addr, 0, 0, __KERNEL_CS); 399 - write_idt_entry(debug_idt_table, gate, &s); 400 - } 401 - #endif 402 - 403 - #ifdef CONFIG_TRACING 404 - extern struct desc_ptr trace_idt_descr; 405 - extern gate_desc trace_idt_table[]; 406 - static inline void write_trace_idt_entry(int entry, const gate_desc *gate) 407 - { 408 - write_idt_entry(trace_idt_table, entry, gate); 409 - } 410 - 411 - static inline void _trace_set_gate(int gate, unsigned type, void *addr, 412 - unsigned dpl, unsigned ist, unsigned seg) 413 - { 414 - gate_desc s; 415 - 416 - pack_gate(&s, type, (unsigned long)addr, dpl, ist, seg); 417 - /* 418 - * does not need to be atomic because it is only done once at 419 - * setup time 420 - */ 421 - write_trace_idt_entry(gate, &s); 422 - } 423 - #else 424 - static inline void write_trace_idt_entry(int entry, const gate_desc *gate) 425 - { 426 - } 427 - 428 - #define _trace_set_gate(gate, type, addr, dpl, ist, seg) 429 - #endif 430 - 431 - static inline void _set_gate(int gate, unsigned type, void *addr, 432 - unsigned dpl, unsigned ist, unsigned seg) 433 - { 434 - gate_desc s; 435 - 436 - pack_gate(&s, type, (unsigned long)addr, dpl, ist, seg); 437 - /* 438 - * does not need to be atomic because it is only done once at 439 - * setup time 440 - */ 441 - write_idt_entry(idt_table, gate, &s); 442 - write_trace_idt_entry(gate, &s); 443 - } 444 - 445 - /* 446 - * This needs to use 'idt_table' rather than 'idt', and 447 - * thus use the _nonmapped_ version of the IDT, as the 448 - * Pentium F0 0F bugfix can have resulted in the mapped 449 - * IDT being write-protected. 450 - */ 451 - #define set_intr_gate_notrace(n, addr) \ 452 - do { \ 453 - BUG_ON((unsigned)n > 0xFF); \ 454 - _set_gate(n, GATE_INTERRUPT, (void *)addr, 0, 0, \ 455 - __KERNEL_CS); \ 456 - } while (0) 457 - 458 - #define set_intr_gate(n, addr) \ 459 - do { \ 460 - set_intr_gate_notrace(n, addr); \ 461 - _trace_set_gate(n, GATE_INTERRUPT, (void *)trace_##addr,\ 462 - 0, 0, __KERNEL_CS); \ 463 - } while (0) 464 - 465 - extern int first_system_vector; 466 - /* used_vectors is BITMAP for irq is not managed by percpu vector_irq */ 467 416 extern unsigned long used_vectors[]; 468 - 469 - static inline void alloc_system_vector(int vector) 470 - { 471 - if (!test_bit(vector, used_vectors)) { 472 - set_bit(vector, used_vectors); 473 - if (first_system_vector > vector) 474 - first_system_vector = vector; 475 - } else { 476 - BUG(); 477 - } 478 - } 479 - 480 - #define alloc_intr_gate(n, addr) \ 481 - do { \ 482 - alloc_system_vector(n); \ 483 - set_intr_gate(n, addr); \ 484 - } while (0) 485 - 486 - /* 487 - * This routine sets up an interrupt gate at directory privilege level 3. 488 - */ 489 - static inline void set_system_intr_gate(unsigned int n, void *addr) 490 - { 491 - BUG_ON((unsigned)n > 0xFF); 492 - _set_gate(n, GATE_INTERRUPT, addr, 0x3, 0, __KERNEL_CS); 493 - } 494 - 495 - static inline void set_system_trap_gate(unsigned int n, void *addr) 496 - { 497 - BUG_ON((unsigned)n > 0xFF); 498 - _set_gate(n, GATE_TRAP, addr, 0x3, 0, __KERNEL_CS); 499 - } 500 - 501 - static inline void set_trap_gate(unsigned int n, void *addr) 502 - { 503 - BUG_ON((unsigned)n > 0xFF); 504 - _set_gate(n, GATE_TRAP, addr, 0, 0, __KERNEL_CS); 505 - } 506 - 507 - static inline void set_task_gate(unsigned int n, unsigned int gdt_entry) 508 - { 509 - BUG_ON((unsigned)n > 0xFF); 510 - _set_gate(n, GATE_TASK, (void *)0, 0, 0, (gdt_entry<<3)); 511 - } 512 - 513 - static inline void set_intr_gate_ist(int n, void *addr, unsigned ist) 514 - { 515 - BUG_ON((unsigned)n > 0xFF); 516 - _set_gate(n, GATE_INTERRUPT, addr, 0, ist, __KERNEL_CS); 517 - } 518 - 519 - static inline void set_system_intr_gate_ist(int n, void *addr, unsigned ist) 520 - { 521 - BUG_ON((unsigned)n > 0xFF); 522 - _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS); 523 - } 524 417 525 418 #ifdef CONFIG_X86_64 526 419 DECLARE_PER_CPU(u32, debug_idt_ctr); ··· 420 567 } 421 568 #endif 422 569 423 - #ifdef CONFIG_TRACING 424 - extern atomic_t trace_idt_ctr; 425 - static inline bool is_trace_idt_enabled(void) 426 - { 427 - if (atomic_read(&trace_idt_ctr)) 428 - return true; 429 - 430 - return false; 431 - } 432 - 433 - static inline void load_trace_idt(void) 434 - { 435 - load_idt((const struct desc_ptr *)&trace_idt_descr); 436 - } 437 - #else 438 - static inline bool is_trace_idt_enabled(void) 439 - { 440 - return false; 441 - } 442 - 443 - static inline void load_trace_idt(void) 444 - { 445 - } 446 - #endif 447 - 448 570 /* 449 571 * The load_current_idt() must be called with interrupts disabled 450 572 * to avoid races. That way the IDT will always be set back to the expected ··· 431 603 { 432 604 if (is_debug_idt_enabled()) 433 605 load_debug_idt(); 434 - else if (is_trace_idt_enabled()) 435 - load_trace_idt(); 436 606 else 437 607 load_idt((const struct desc_ptr *)&idt_descr); 438 608 } 609 + 610 + extern void idt_setup_early_handler(void); 611 + extern void idt_setup_early_traps(void); 612 + extern void idt_setup_traps(void); 613 + extern void idt_setup_apic_and_irq_gates(void); 614 + 615 + #ifdef CONFIG_X86_64 616 + extern void idt_setup_early_pf(void); 617 + extern void idt_setup_ist_traps(void); 618 + extern void idt_setup_debugidt_traps(void); 619 + #else 620 + static inline void idt_setup_early_pf(void) { } 621 + static inline void idt_setup_ist_traps(void) { } 622 + static inline void idt_setup_debugidt_traps(void) { } 623 + #endif 624 + 625 + extern void idt_invalidate(void *addr); 626 + 439 627 #endif /* _ASM_X86_DESC_H */
+67 -57
arch/x86/include/asm/desc_defs.h
··· 11 11 12 12 #include <linux/types.h> 13 13 14 - /* 15 - * FIXME: Accessing the desc_struct through its fields is more elegant, 16 - * and should be the one valid thing to do. However, a lot of open code 17 - * still touches the a and b accessors, and doing this allow us to do it 18 - * incrementally. We keep the signature as a struct, rather than a union, 19 - * so we can get rid of it transparently in the future -- glommer 20 - */ 21 14 /* 8 byte segment descriptor */ 22 15 struct desc_struct { 23 - union { 24 - struct { 25 - unsigned int a; 26 - unsigned int b; 27 - }; 28 - struct { 29 - u16 limit0; 30 - u16 base0; 31 - unsigned base1: 8, type: 4, s: 1, dpl: 2, p: 1; 32 - unsigned limit: 4, avl: 1, l: 1, d: 1, g: 1, base2: 8; 33 - }; 34 - }; 16 + u16 limit0; 17 + u16 base0; 18 + u16 base1: 8, type: 4, s: 1, dpl: 2, p: 1; 19 + u16 limit1: 4, avl: 1, l: 1, d: 1, g: 1, base2: 8; 35 20 } __attribute__((packed)); 36 21 37 - #define GDT_ENTRY_INIT(flags, base, limit) { { { \ 38 - .a = ((limit) & 0xffff) | (((base) & 0xffff) << 16), \ 39 - .b = (((base) & 0xff0000) >> 16) | (((flags) & 0xf0ff) << 8) | \ 40 - ((limit) & 0xf0000) | ((base) & 0xff000000), \ 41 - } } } 22 + #define GDT_ENTRY_INIT(flags, base, limit) \ 23 + { \ 24 + .limit0 = (u16) (limit), \ 25 + .limit1 = ((limit) >> 16) & 0x0F, \ 26 + .base0 = (u16) (base), \ 27 + .base1 = ((base) >> 16) & 0xFF, \ 28 + .base2 = ((base) >> 24) & 0xFF, \ 29 + .type = (flags & 0x0f), \ 30 + .s = (flags >> 4) & 0x01, \ 31 + .dpl = (flags >> 5) & 0x03, \ 32 + .p = (flags >> 7) & 0x01, \ 33 + .avl = (flags >> 12) & 0x01, \ 34 + .l = (flags >> 13) & 0x01, \ 35 + .d = (flags >> 14) & 0x01, \ 36 + .g = (flags >> 15) & 0x01, \ 37 + } 42 38 43 39 enum { 44 40 GATE_INTERRUPT = 0xE, ··· 43 47 GATE_TASK = 0x5, 44 48 }; 45 49 46 - /* 16byte gate */ 47 - struct gate_struct64 { 48 - u16 offset_low; 49 - u16 segment; 50 - unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1; 51 - u16 offset_middle; 52 - u32 offset_high; 53 - u32 zero1; 54 - } __attribute__((packed)); 55 - 56 - #define PTR_LOW(x) ((unsigned long long)(x) & 0xFFFF) 57 - #define PTR_MIDDLE(x) (((unsigned long long)(x) >> 16) & 0xFFFF) 58 - #define PTR_HIGH(x) ((unsigned long long)(x) >> 32) 59 - 60 50 enum { 61 51 DESC_TSS = 0x9, 62 52 DESC_LDT = 0x2, 63 53 DESCTYPE_S = 0x10, /* !system */ 64 54 }; 65 55 66 - /* LDT or TSS descriptor in the GDT. 16 bytes. */ 67 - struct ldttss_desc64 { 68 - u16 limit0; 69 - u16 base0; 70 - unsigned base1 : 8, type : 5, dpl : 2, p : 1; 71 - unsigned limit1 : 4, zero0 : 3, g : 1, base2 : 8; 72 - u32 base3; 73 - u32 zero1; 56 + /* LDT or TSS descriptor in the GDT. */ 57 + struct ldttss_desc { 58 + u16 limit0; 59 + u16 base0; 60 + 61 + u16 base1 : 8, type : 5, dpl : 2, p : 1; 62 + u16 limit1 : 4, zero0 : 3, g : 1, base2 : 8; 63 + #ifdef CONFIG_X86_64 64 + u32 base3; 65 + u32 zero1; 66 + #endif 74 67 } __attribute__((packed)); 75 68 69 + typedef struct ldttss_desc ldt_desc; 70 + typedef struct ldttss_desc tss_desc; 71 + 72 + struct idt_bits { 73 + u16 ist : 3, 74 + zero : 5, 75 + type : 5, 76 + dpl : 2, 77 + p : 1; 78 + } __attribute__((packed)); 79 + 80 + struct gate_struct { 81 + u16 offset_low; 82 + u16 segment; 83 + struct idt_bits bits; 84 + u16 offset_middle; 76 85 #ifdef CONFIG_X86_64 77 - typedef struct gate_struct64 gate_desc; 78 - typedef struct ldttss_desc64 ldt_desc; 79 - typedef struct ldttss_desc64 tss_desc; 80 - #define gate_offset(g) ((g).offset_low | ((unsigned long)(g).offset_middle << 16) | ((unsigned long)(g).offset_high << 32)) 81 - #define gate_segment(g) ((g).segment) 82 - #else 83 - typedef struct desc_struct gate_desc; 84 - typedef struct desc_struct ldt_desc; 85 - typedef struct desc_struct tss_desc; 86 - #define gate_offset(g) (((g).b & 0xffff0000) | ((g).a & 0x0000ffff)) 87 - #define gate_segment(g) ((g).a >> 16) 86 + u32 offset_high; 87 + u32 reserved; 88 88 #endif 89 + } __attribute__((packed)); 90 + 91 + typedef struct gate_struct gate_desc; 92 + 93 + static inline unsigned long gate_offset(const gate_desc *g) 94 + { 95 + #ifdef CONFIG_X86_64 96 + return g->offset_low | ((unsigned long)g->offset_middle << 16) | 97 + ((unsigned long) g->offset_high << 32); 98 + #else 99 + return g->offset_low | ((unsigned long)g->offset_middle << 16); 100 + #endif 101 + } 102 + 103 + static inline unsigned long gate_segment(const gate_desc *g) 104 + { 105 + return g->segment; 106 + } 89 107 90 108 struct desc_ptr { 91 109 unsigned short size;
+6 -11
arch/x86/include/asm/entry_arch.h
··· 13 13 BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR) 14 14 BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) 15 15 BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR) 16 - BUILD_INTERRUPT3(irq_move_cleanup_interrupt, IRQ_MOVE_CLEANUP_VECTOR, 17 - smp_irq_move_cleanup_interrupt) 18 - BUILD_INTERRUPT3(reboot_interrupt, REBOOT_VECTOR, smp_reboot_interrupt) 16 + BUILD_INTERRUPT(irq_move_cleanup_interrupt, IRQ_MOVE_CLEANUP_VECTOR) 17 + BUILD_INTERRUPT(reboot_interrupt, REBOOT_VECTOR) 19 18 #endif 20 19 21 - BUILD_INTERRUPT(x86_platform_ipi, X86_PLATFORM_IPI_VECTOR) 22 - 23 20 #ifdef CONFIG_HAVE_KVM 24 - BUILD_INTERRUPT3(kvm_posted_intr_ipi, POSTED_INTR_VECTOR, 25 - smp_kvm_posted_intr_ipi) 26 - BUILD_INTERRUPT3(kvm_posted_intr_wakeup_ipi, POSTED_INTR_WAKEUP_VECTOR, 27 - smp_kvm_posted_intr_wakeup_ipi) 28 - BUILD_INTERRUPT3(kvm_posted_intr_nested_ipi, POSTED_INTR_NESTED_VECTOR, 29 - smp_kvm_posted_intr_nested_ipi) 21 + BUILD_INTERRUPT(kvm_posted_intr_ipi, POSTED_INTR_VECTOR) 22 + BUILD_INTERRUPT(kvm_posted_intr_wakeup_ipi, POSTED_INTR_WAKEUP_VECTOR) 23 + BUILD_INTERRUPT(kvm_posted_intr_nested_ipi, POSTED_INTR_NESTED_VECTOR) 30 24 #endif 31 25 32 26 /* ··· 35 41 BUILD_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR) 36 42 BUILD_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR) 37 43 BUILD_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR) 44 + BUILD_INTERRUPT(x86_platform_ipi, X86_PLATFORM_IPI_VECTOR) 38 45 39 46 #ifdef CONFIG_IRQ_WORK 40 47 BUILD_INTERRUPT(irq_work_interrupt, IRQ_WORK_VECTOR)
-20
arch/x86/include/asm/hw_irq.h
··· 46 46 extern asmlinkage void call_function_interrupt(void); 47 47 extern asmlinkage void call_function_single_interrupt(void); 48 48 49 - #ifdef CONFIG_TRACING 50 - /* Interrupt handlers registered during init_IRQ */ 51 - extern void trace_apic_timer_interrupt(void); 52 - extern void trace_x86_platform_ipi(void); 53 - extern void trace_error_interrupt(void); 54 - extern void trace_irq_work_interrupt(void); 55 - extern void trace_spurious_interrupt(void); 56 - extern void trace_thermal_interrupt(void); 57 - extern void trace_reschedule_interrupt(void); 58 - extern void trace_threshold_interrupt(void); 59 - extern void trace_deferred_error_interrupt(void); 60 - extern void trace_call_function_interrupt(void); 61 - extern void trace_call_function_single_interrupt(void); 62 - #define trace_irq_move_cleanup_interrupt irq_move_cleanup_interrupt 63 - #define trace_reboot_interrupt reboot_interrupt 64 - #define trace_kvm_posted_intr_ipi kvm_posted_intr_ipi 65 - #define trace_kvm_posted_intr_wakeup_ipi kvm_posted_intr_wakeup_ipi 66 - #define trace_kvm_posted_intr_nested_ipi kvm_posted_intr_nested_ipi 67 - #endif /* CONFIG_TRACING */ 68 - 69 49 #ifdef CONFIG_X86_LOCAL_APIC 70 50 struct irq_data; 71 51 struct pci_dev;
-4
arch/x86/include/asm/irq.h
··· 42 42 43 43 extern __visible unsigned int do_IRQ(struct pt_regs *regs); 44 44 45 - /* Interrupt vector management */ 46 - extern DECLARE_BITMAP(used_vectors, NR_VECTORS); 47 - extern int vector_used_by_percpu_irq(unsigned int vector); 48 - 49 45 extern void init_ISA_irqs(void); 50 46 51 47 #ifdef CONFIG_X86_LOCAL_APIC
+8
arch/x86/include/asm/irq_work.h
··· 3 3 4 4 #include <asm/cpufeature.h> 5 5 6 + #ifdef CONFIG_X86_LOCAL_APIC 6 7 static inline bool arch_irq_work_has_interrupt(void) 7 8 { 8 9 return boot_cpu_has(X86_FEATURE_APIC); 9 10 } 11 + extern void arch_irq_work_raise(void); 12 + #else 13 + static inline bool arch_irq_work_has_interrupt(void) 14 + { 15 + return false; 16 + } 17 + #endif 10 18 11 19 #endif /* _ASM_IRQ_WORK_H */
-5
arch/x86/include/asm/paravirt.h
··· 960 960 #define GET_CR2_INTO_RAX \ 961 961 call PARA_INDIRECT(pv_mmu_ops+PV_MMU_read_cr2) 962 962 963 - #define PARAVIRT_ADJUST_EXCEPTION_FRAME \ 964 - PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_adjust_exception_frame), \ 965 - CLBR_NONE, \ 966 - call PARA_INDIRECT(pv_irq_ops+PV_IRQ_adjust_exception_frame)) 967 - 968 963 #define USERGS_SYSRET64 \ 969 964 PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_usergs_sysret64), \ 970 965 CLBR_NONE, \
-3
arch/x86/include/asm/paravirt_types.h
··· 196 196 void (*safe_halt)(void); 197 197 void (*halt)(void); 198 198 199 - #ifdef CONFIG_X86_64 200 - void (*adjust_exception_frame)(void); 201 - #endif 202 199 } __no_randomize_layout; 203 200 204 201 struct pv_mmu_ops {
+3
arch/x86/include/asm/proto.h
··· 24 24 void __end_entry_SYSENTER_compat(void); 25 25 void entry_SYSCALL_compat(void); 26 26 void entry_INT80_compat(void); 27 + #if defined(CONFIG_X86_64) && defined(CONFIG_XEN_PV) 28 + void xen_entry_INT80_compat(void); 29 + #endif 27 30 #endif 28 31 29 32 void x86_configure_nx(void);
+1 -3
arch/x86/include/asm/segment.h
··· 238 238 #ifndef __ASSEMBLY__ 239 239 240 240 extern const char early_idt_handler_array[NUM_EXCEPTION_VECTORS][EARLY_IDT_HANDLER_SIZE]; 241 - #ifdef CONFIG_TRACING 242 - # define trace_early_idt_handler_array early_idt_handler_array 243 - #endif 241 + extern void early_ignore_irq(void); 244 242 245 243 /* 246 244 * Load a segment. Fall back on loading the zero segment if something goes
+16
arch/x86/include/asm/trace/common.h
··· 1 + #ifndef _ASM_TRACE_COMMON_H 2 + #define _ASM_TRACE_COMMON_H 3 + 4 + #ifdef CONFIG_TRACING 5 + DECLARE_STATIC_KEY_FALSE(trace_pagefault_key); 6 + #define trace_pagefault_enabled() \ 7 + static_branch_unlikely(&trace_pagefault_key) 8 + DECLARE_STATIC_KEY_FALSE(trace_resched_ipi_key); 9 + #define trace_resched_ipi_enabled() \ 10 + static_branch_unlikely(&trace_resched_ipi_key) 11 + #else 12 + static inline bool trace_pagefault_enabled(void) { return false; } 13 + static inline bool trace_resched_ipi_enabled(void) { return false; } 14 + #endif 15 + 16 + #endif
+4 -4
arch/x86/include/asm/trace/exceptions.h
··· 5 5 #define _TRACE_PAGE_FAULT_H 6 6 7 7 #include <linux/tracepoint.h> 8 + #include <asm/trace/common.h> 8 9 9 - extern int trace_irq_vector_regfunc(void); 10 - extern void trace_irq_vector_unregfunc(void); 10 + extern int trace_pagefault_reg(void); 11 + extern void trace_pagefault_unreg(void); 11 12 12 13 DECLARE_EVENT_CLASS(x86_exceptions, 13 14 ··· 38 37 TP_PROTO(unsigned long address, struct pt_regs *regs, \ 39 38 unsigned long error_code), \ 40 39 TP_ARGS(address, regs, error_code), \ 41 - trace_irq_vector_regfunc, \ 42 - trace_irq_vector_unregfunc); 40 + trace_pagefault_reg, trace_pagefault_unreg); 43 41 44 42 DEFINE_PAGE_FAULT_EVENT(page_fault_user); 45 43 DEFINE_PAGE_FAULT_EVENT(page_fault_kernel);
+39 -12
arch/x86/include/asm/trace/irq_vectors.h
··· 5 5 #define _TRACE_IRQ_VECTORS_H 6 6 7 7 #include <linux/tracepoint.h> 8 + #include <asm/trace/common.h> 8 9 9 - extern int trace_irq_vector_regfunc(void); 10 - extern void trace_irq_vector_unregfunc(void); 10 + #ifdef CONFIG_X86_LOCAL_APIC 11 + 12 + extern int trace_resched_ipi_reg(void); 13 + extern void trace_resched_ipi_unreg(void); 11 14 12 15 DECLARE_EVENT_CLASS(x86_irq_vector, 13 16 ··· 31 28 #define DEFINE_IRQ_VECTOR_EVENT(name) \ 32 29 DEFINE_EVENT_FN(x86_irq_vector, name##_entry, \ 33 30 TP_PROTO(int vector), \ 31 + TP_ARGS(vector), NULL, NULL); \ 32 + DEFINE_EVENT_FN(x86_irq_vector, name##_exit, \ 33 + TP_PROTO(int vector), \ 34 + TP_ARGS(vector), NULL, NULL); 35 + 36 + #define DEFINE_RESCHED_IPI_EVENT(name) \ 37 + DEFINE_EVENT_FN(x86_irq_vector, name##_entry, \ 38 + TP_PROTO(int vector), \ 34 39 TP_ARGS(vector), \ 35 - trace_irq_vector_regfunc, \ 36 - trace_irq_vector_unregfunc); \ 40 + trace_resched_ipi_reg, \ 41 + trace_resched_ipi_unreg); \ 37 42 DEFINE_EVENT_FN(x86_irq_vector, name##_exit, \ 38 43 TP_PROTO(int vector), \ 39 44 TP_ARGS(vector), \ 40 - trace_irq_vector_regfunc, \ 41 - trace_irq_vector_unregfunc); 42 - 45 + trace_resched_ipi_reg, \ 46 + trace_resched_ipi_unreg); 43 47 44 48 /* 45 49 * local_timer - called when entering/exiting a local timer interrupt 46 50 * vector handler 47 51 */ 48 52 DEFINE_IRQ_VECTOR_EVENT(local_timer); 49 - 50 - /* 51 - * reschedule - called when entering/exiting a reschedule vector handler 52 - */ 53 - DEFINE_IRQ_VECTOR_EVENT(reschedule); 54 53 55 54 /* 56 55 * spurious_apic - called when entering/exiting a spurious apic vector handler ··· 70 65 */ 71 66 DEFINE_IRQ_VECTOR_EVENT(x86_platform_ipi); 72 67 68 + #ifdef CONFIG_IRQ_WORK 73 69 /* 74 70 * irq_work - called when entering/exiting a irq work interrupt 75 71 * vector handler ··· 87 81 * 4) goto 1 88 82 */ 89 83 TRACE_EVENT_PERF_PERM(irq_work_exit, is_sampling_event(p_event) ? -EPERM : 0); 84 + #endif 85 + 86 + /* 87 + * The ifdef is required because that tracepoint macro hell emits tracepoint 88 + * code in files which include this header even if the tracepoint is not 89 + * enabled. Brilliant stuff that. 90 + */ 91 + #ifdef CONFIG_SMP 92 + /* 93 + * reschedule - called when entering/exiting a reschedule vector handler 94 + */ 95 + DEFINE_RESCHED_IPI_EVENT(reschedule); 90 96 91 97 /* 92 98 * call_function - called when entering/exiting a call function interrupt ··· 111 93 * single interrupt vector handler 112 94 */ 113 95 DEFINE_IRQ_VECTOR_EVENT(call_function_single); 96 + #endif 114 97 98 + #ifdef CONFIG_X86_MCE_THRESHOLD 115 99 /* 116 100 * threshold_apic - called when entering/exiting a threshold apic interrupt 117 101 * vector handler 118 102 */ 119 103 DEFINE_IRQ_VECTOR_EVENT(threshold_apic); 104 + #endif 120 105 106 + #ifdef CONFIG_X86_MCE_AMD 121 107 /* 122 108 * deferred_error_apic - called when entering/exiting a deferred apic interrupt 123 109 * vector handler 124 110 */ 125 111 DEFINE_IRQ_VECTOR_EVENT(deferred_error_apic); 112 + #endif 126 113 114 + #ifdef CONFIG_X86_THERMAL_VECTOR 127 115 /* 128 116 * thermal_apic - called when entering/exiting a thermal apic interrupt 129 117 * vector handler 130 118 */ 131 119 DEFINE_IRQ_VECTOR_EVENT(thermal_apic); 120 + #endif 121 + 122 + #endif /* CONFIG_X86_LOCAL_APIC */ 132 123 133 124 #undef TRACE_INCLUDE_PATH 134 125 #define TRACE_INCLUDE_PATH .
+23 -27
arch/x86/include/asm/traps.h
··· 13 13 asmlinkage void debug(void); 14 14 asmlinkage void nmi(void); 15 15 asmlinkage void int3(void); 16 - asmlinkage void xen_debug(void); 17 - asmlinkage void xen_int3(void); 18 - asmlinkage void xen_stack_segment(void); 19 16 asmlinkage void overflow(void); 20 17 asmlinkage void bounds(void); 21 18 asmlinkage void invalid_op(void); ··· 35 38 #endif /* CONFIG_X86_MCE */ 36 39 asmlinkage void simd_coprocessor_error(void); 37 40 38 - #ifdef CONFIG_TRACING 39 - asmlinkage void trace_page_fault(void); 40 - #define trace_stack_segment stack_segment 41 - #define trace_divide_error divide_error 42 - #define trace_bounds bounds 43 - #define trace_invalid_op invalid_op 44 - #define trace_device_not_available device_not_available 45 - #define trace_coprocessor_segment_overrun coprocessor_segment_overrun 46 - #define trace_invalid_TSS invalid_TSS 47 - #define trace_segment_not_present segment_not_present 48 - #define trace_general_protection general_protection 49 - #define trace_spurious_interrupt_bug spurious_interrupt_bug 50 - #define trace_coprocessor_error coprocessor_error 51 - #define trace_alignment_check alignment_check 52 - #define trace_simd_coprocessor_error simd_coprocessor_error 53 - #define trace_async_page_fault async_page_fault 41 + #if defined(CONFIG_X86_64) && defined(CONFIG_XEN_PV) 42 + asmlinkage void xen_divide_error(void); 43 + asmlinkage void xen_xendebug(void); 44 + asmlinkage void xen_xenint3(void); 45 + asmlinkage void xen_nmi(void); 46 + asmlinkage void xen_overflow(void); 47 + asmlinkage void xen_bounds(void); 48 + asmlinkage void xen_invalid_op(void); 49 + asmlinkage void xen_device_not_available(void); 50 + asmlinkage void xen_double_fault(void); 51 + asmlinkage void xen_coprocessor_segment_overrun(void); 52 + asmlinkage void xen_invalid_TSS(void); 53 + asmlinkage void xen_segment_not_present(void); 54 + asmlinkage void xen_stack_segment(void); 55 + asmlinkage void xen_general_protection(void); 56 + asmlinkage void xen_page_fault(void); 57 + asmlinkage void xen_spurious_interrupt_bug(void); 58 + asmlinkage void xen_coprocessor_error(void); 59 + asmlinkage void xen_alignment_check(void); 60 + #ifdef CONFIG_X86_MCE 61 + asmlinkage void xen_machine_check(void); 62 + #endif /* CONFIG_X86_MCE */ 63 + asmlinkage void xen_simd_coprocessor_error(void); 54 64 #endif 55 65 56 66 dotraplinkage void do_divide_error(struct pt_regs *, long); ··· 78 74 #endif 79 75 dotraplinkage void do_general_protection(struct pt_regs *, long); 80 76 dotraplinkage void do_page_fault(struct pt_regs *, unsigned long); 81 - #ifdef CONFIG_TRACING 82 - dotraplinkage void trace_do_page_fault(struct pt_regs *, unsigned long); 83 - #else 84 - static inline void trace_do_page_fault(struct pt_regs *regs, unsigned long error) 85 - { 86 - do_page_fault(regs, error); 87 - } 88 - #endif 89 77 dotraplinkage void do_spurious_interrupt_bug(struct pt_regs *, long); 90 78 dotraplinkage void do_coprocessor_error(struct pt_regs *, long); 91 79 dotraplinkage void do_alignment_check(struct pt_regs *, long);
+4 -2
arch/x86/include/asm/xen/hypercall.h
··· 552 552 MULTI_update_descriptor(struct multicall_entry *mcl, u64 maddr, 553 553 struct desc_struct desc) 554 554 { 555 + u32 *p = (u32 *) &desc; 556 + 555 557 mcl->op = __HYPERVISOR_update_descriptor; 556 558 if (sizeof(maddr) == sizeof(long)) { 557 559 mcl->args[0] = maddr; ··· 561 559 } else { 562 560 mcl->args[0] = maddr; 563 561 mcl->args[1] = maddr >> 32; 564 - mcl->args[2] = desc.a; 565 - mcl->args[3] = desc.b; 562 + mcl->args[2] = *p++; 563 + mcl->args[3] = *p; 566 564 } 567 565 568 566 trace_xen_mc_entry(mcl, sizeof(maddr) == sizeof(long) ? 2 : 4);
+2 -1
arch/x86/kernel/Makefile
··· 42 42 43 43 obj-y := process_$(BITS).o signal.o 44 44 obj-$(CONFIG_COMPAT) += signal_compat.o 45 - obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o 45 + obj-y += traps.o idt.o irq.o irq_$(BITS).o dumpstack_$(BITS).o 46 46 obj-y += time.o ioport.o dumpstack.o nmi.o 47 47 obj-$(CONFIG_MODIFY_LDT_SYSCALL) += ldt.o 48 48 obj-y += setup.o x86_init.o i8259.o irqinit.o jump_label.o ··· 111 111 obj-$(CONFIG_PARAVIRT_CLOCK) += pvclock.o 112 112 obj-$(CONFIG_X86_PMEM_LEGACY_DEVICE) += pmem.o 113 113 114 + obj-$(CONFIG_EISA) += eisa.o 114 115 obj-$(CONFIG_PCSPKR_PLATFORM) += pcspeaker.o 115 116 116 117 obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o
+18 -58
arch/x86/kernel/apic/apic.c
··· 177 177 int local_apic_timer_c2_ok; 178 178 EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok); 179 179 180 - int first_system_vector = FIRST_SYSTEM_VECTOR; 181 - 182 180 /* 183 181 * Debug level, exported for io_apic.c 184 182 */ ··· 597 599 598 600 static void apic_check_deadline_errata(void) 599 601 { 600 - const struct x86_cpu_id *m = x86_match_cpu(deadline_match); 602 + const struct x86_cpu_id *m; 601 603 u32 rev; 602 604 605 + if (!boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER)) 606 + return; 607 + 608 + m = x86_match_cpu(deadline_match); 603 609 if (!m) 604 610 return; 605 611 ··· 992 990 */ 993 991 static void local_apic_timer_interrupt(void) 994 992 { 995 - int cpu = smp_processor_id(); 996 - struct clock_event_device *evt = &per_cpu(lapic_events, cpu); 993 + struct clock_event_device *evt = this_cpu_ptr(&lapic_events); 997 994 998 995 /* 999 996 * Normally we should not be here till LAPIC has been initialized but ··· 1006 1005 * spurious. 1007 1006 */ 1008 1007 if (!evt->event_handler) { 1009 - pr_warning("Spurious LAPIC timer interrupt on cpu %d\n", cpu); 1008 + pr_warning("Spurious LAPIC timer interrupt on cpu %d\n", 1009 + smp_processor_id()); 1010 1010 /* Switch it off */ 1011 1011 lapic_timer_shutdown(evt); 1012 1012 return; ··· 1030 1028 * interrupt as well. Thus we cannot inline the local irq ... ] 1031 1029 */ 1032 1030 __visible void __irq_entry smp_apic_timer_interrupt(struct pt_regs *regs) 1033 - { 1034 - struct pt_regs *old_regs = set_irq_regs(regs); 1035 - 1036 - /* 1037 - * NOTE! We'd better ACK the irq immediately, 1038 - * because timer handling can be slow. 1039 - * 1040 - * update_process_times() expects us to have done irq_enter(). 1041 - * Besides, if we don't timer interrupts ignore the global 1042 - * interrupt lock, which is the WrongThing (tm) to do. 1043 - */ 1044 - entering_ack_irq(); 1045 - local_apic_timer_interrupt(); 1046 - exiting_irq(); 1047 - 1048 - set_irq_regs(old_regs); 1049 - } 1050 - 1051 - __visible void __irq_entry smp_trace_apic_timer_interrupt(struct pt_regs *regs) 1052 1031 { 1053 1032 struct pt_regs *old_regs = set_irq_regs(regs); 1054 1033 ··· 1903 1920 /* 1904 1921 * This interrupt should _never_ happen with our APIC/SMP architecture 1905 1922 */ 1906 - static void __smp_spurious_interrupt(u8 vector) 1923 + __visible void __irq_entry smp_spurious_interrupt(struct pt_regs *regs) 1907 1924 { 1925 + u8 vector = ~regs->orig_ax; 1908 1926 u32 v; 1927 + 1928 + entering_irq(); 1929 + trace_spurious_apic_entry(vector); 1909 1930 1910 1931 /* 1911 1932 * Check if this really is a spurious interrupt and ACK it ··· 1925 1938 /* see sw-dev-man vol 3, chapter 7.4.13.5 */ 1926 1939 pr_info("spurious APIC interrupt through vector %02x on CPU#%d, " 1927 1940 "should never happen.\n", vector, smp_processor_id()); 1928 - } 1929 1941 1930 - __visible void __irq_entry smp_spurious_interrupt(struct pt_regs *regs) 1931 - { 1932 - entering_irq(); 1933 - __smp_spurious_interrupt(~regs->orig_ax); 1934 - exiting_irq(); 1935 - } 1936 - 1937 - __visible void __irq_entry smp_trace_spurious_interrupt(struct pt_regs *regs) 1938 - { 1939 - u8 vector = ~regs->orig_ax; 1940 - 1941 - entering_irq(); 1942 - trace_spurious_apic_entry(vector); 1943 - __smp_spurious_interrupt(vector); 1944 1942 trace_spurious_apic_exit(vector); 1945 1943 exiting_irq(); 1946 1944 } ··· 1933 1961 /* 1934 1962 * This interrupt should never happen with our APIC/SMP architecture 1935 1963 */ 1936 - static void __smp_error_interrupt(struct pt_regs *regs) 1964 + __visible void __irq_entry smp_error_interrupt(struct pt_regs *regs) 1937 1965 { 1938 - u32 v; 1939 - u32 i = 0; 1940 1966 static const char * const error_interrupt_reason[] = { 1941 1967 "Send CS error", /* APIC Error Bit 0 */ 1942 1968 "Receive CS error", /* APIC Error Bit 1 */ ··· 1945 1975 "Received illegal vector", /* APIC Error Bit 6 */ 1946 1976 "Illegal register address", /* APIC Error Bit 7 */ 1947 1977 }; 1978 + u32 v, i = 0; 1979 + 1980 + entering_irq(); 1981 + trace_error_apic_entry(ERROR_APIC_VECTOR); 1948 1982 1949 1983 /* First tickle the hardware, only then report what went on. -- REW */ 1950 1984 if (lapic_get_maxlvt() > 3) /* Due to the Pentium erratum 3AP. */ ··· 1970 1996 1971 1997 apic_printk(APIC_DEBUG, KERN_CONT "\n"); 1972 1998 1973 - } 1974 - 1975 - __visible void __irq_entry smp_error_interrupt(struct pt_regs *regs) 1976 - { 1977 - entering_irq(); 1978 - __smp_error_interrupt(regs); 1979 - exiting_irq(); 1980 - } 1981 - 1982 - __visible void __irq_entry smp_trace_error_interrupt(struct pt_regs *regs) 1983 - { 1984 - entering_irq(); 1985 - trace_error_apic_entry(ERROR_APIC_VECTOR); 1986 - __smp_error_interrupt(regs); 1987 1999 trace_error_apic_exit(ERROR_APIC_VECTOR); 1988 2000 exiting_irq(); 1989 2001 }
+1 -1
arch/x86/kernel/apic/io_apic.c
··· 1243 1243 entry.vector, entry.irr, entry.delivery_status); 1244 1244 if (ir_entry->format) 1245 1245 printk(KERN_DEBUG "%s, remapped, I(%04X), Z(%X)\n", 1246 - buf, (ir_entry->index << 15) | ir_entry->index, 1246 + buf, (ir_entry->index2 << 15) | ir_entry->index, 1247 1247 ir_entry->zero); 1248 1248 else 1249 1249 printk(KERN_DEBUG "%s, %s, D(%02X), M(%1d)\n",
+1 -1
arch/x86/kernel/apic/vector.c
··· 166 166 offset = current_offset; 167 167 next: 168 168 vector += 16; 169 - if (vector >= first_system_vector) { 169 + if (vector >= FIRST_SYSTEM_VECTOR) { 170 170 offset = (offset + 1) % 16; 171 171 vector = FIRST_EXTERNAL_VECTOR + offset; 172 172 }
-1
arch/x86/kernel/asm-offsets_64.c
··· 20 20 int main(void) 21 21 { 22 22 #ifdef CONFIG_PARAVIRT 23 - OFFSET(PV_IRQ_adjust_exception_frame, pv_irq_ops, adjust_exception_frame); 24 23 OFFSET(PV_CPU_usergs_sysret64, pv_cpu_ops, usergs_sysret64); 25 24 OFFSET(PV_CPU_swapgs, pv_cpu_ops, swapgs); 26 25 BLANK();
-9
arch/x86/kernel/cpu/common.c
··· 1329 1329 __setup("clearcpuid=", setup_disablecpuid); 1330 1330 1331 1331 #ifdef CONFIG_X86_64 1332 - struct desc_ptr idt_descr __ro_after_init = { 1333 - .size = NR_VECTORS * 16 - 1, 1334 - .address = (unsigned long) idt_table, 1335 - }; 1336 - const struct desc_ptr debug_idt_descr = { 1337 - .size = NR_VECTORS * 16 - 1, 1338 - .address = (unsigned long) debug_idt_table, 1339 - }; 1340 - 1341 1332 DEFINE_PER_CPU_FIRST(union irq_stack_union, 1342 1333 irq_stack_union) __aligned(PAGE_SIZE) __visible; 1343 1334
+2 -14
arch/x86/kernel/cpu/mcheck/mce_amd.c
··· 771 771 mce_log(&m); 772 772 } 773 773 774 - static inline void __smp_deferred_error_interrupt(void) 775 - { 776 - inc_irq_stat(irq_deferred_error_count); 777 - deferred_error_int_vector(); 778 - } 779 - 780 774 asmlinkage __visible void __irq_entry smp_deferred_error_interrupt(void) 781 775 { 782 776 entering_irq(); 783 - __smp_deferred_error_interrupt(); 784 - exiting_ack_irq(); 785 - } 786 - 787 - asmlinkage __visible void __irq_entry smp_trace_deferred_error_interrupt(void) 788 - { 789 - entering_irq(); 790 777 trace_deferred_error_apic_entry(DEFERRED_ERROR_VECTOR); 791 - __smp_deferred_error_interrupt(); 778 + inc_irq_stat(irq_deferred_error_count); 779 + deferred_error_int_vector(); 792 780 trace_deferred_error_apic_exit(DEFERRED_ERROR_VECTOR); 793 781 exiting_ack_irq(); 794 782 }
+3 -17
arch/x86/kernel/cpu/mcheck/therm_throt.c
··· 390 390 391 391 static void (*smp_thermal_vector)(void) = unexpected_thermal_interrupt; 392 392 393 - static inline void __smp_thermal_interrupt(void) 394 - { 395 - inc_irq_stat(irq_thermal_count); 396 - smp_thermal_vector(); 397 - } 398 - 399 - asmlinkage __visible void __irq_entry 400 - smp_thermal_interrupt(struct pt_regs *regs) 401 - { 402 - entering_irq(); 403 - __smp_thermal_interrupt(); 404 - exiting_ack_irq(); 405 - } 406 - 407 - asmlinkage __visible void __irq_entry 408 - smp_trace_thermal_interrupt(struct pt_regs *regs) 393 + asmlinkage __visible void __irq_entry smp_thermal_interrupt(struct pt_regs *r) 409 394 { 410 395 entering_irq(); 411 396 trace_thermal_apic_entry(THERMAL_APIC_VECTOR); 412 - __smp_thermal_interrupt(); 397 + inc_irq_stat(irq_thermal_count); 398 + smp_thermal_vector(); 413 399 trace_thermal_apic_exit(THERMAL_APIC_VECTOR); 414 400 exiting_ack_irq(); 415 401 }
+2 -14
arch/x86/kernel/cpu/mcheck/threshold.c
··· 17 17 18 18 void (*mce_threshold_vector)(void) = default_threshold_interrupt; 19 19 20 - static inline void __smp_threshold_interrupt(void) 21 - { 22 - inc_irq_stat(irq_threshold_count); 23 - mce_threshold_vector(); 24 - } 25 - 26 20 asmlinkage __visible void __irq_entry smp_threshold_interrupt(void) 27 21 { 28 22 entering_irq(); 29 - __smp_threshold_interrupt(); 30 - exiting_ack_irq(); 31 - } 32 - 33 - asmlinkage __visible void __irq_entry smp_trace_threshold_interrupt(void) 34 - { 35 - entering_irq(); 36 23 trace_threshold_apic_entry(THRESHOLD_APIC_VECTOR); 37 - __smp_threshold_interrupt(); 24 + inc_irq_stat(irq_threshold_count); 25 + mce_threshold_vector(); 38 26 trace_threshold_apic_exit(THRESHOLD_APIC_VECTOR); 39 27 exiting_ack_irq(); 40 28 }
+2 -7
arch/x86/kernel/cpu/mshyperv.c
··· 59 59 void hv_setup_vmbus_irq(void (*handler)(void)) 60 60 { 61 61 vmbus_handler = handler; 62 - /* 63 - * Setup the IDT for hypervisor callback. Prevent reallocation 64 - * at module reload. 65 - */ 66 - if (!test_bit(HYPERVISOR_CALLBACK_VECTOR, used_vectors)) 67 - alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, 68 - hyperv_callback_vector); 62 + /* Setup the IDT for hypervisor callback */ 63 + alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector); 69 64 } 70 65 71 66 void hv_remove_vmbus_irq(void)
+19
arch/x86/kernel/eisa.c
··· 1 + /* 2 + * EISA specific code 3 + * 4 + * This file is licensed under the GPL V2 5 + */ 6 + #include <linux/ioport.h> 7 + #include <linux/eisa.h> 8 + #include <linux/io.h> 9 + 10 + static __init int eisa_bus_probe(void) 11 + { 12 + void __iomem *p = ioremap(0x0FFFD9, 4); 13 + 14 + if (readl(p) == 'E' + ('I'<<8) + ('S'<<16) + ('A'<<24)) 15 + EISA_bus = 1; 16 + iounmap(p); 17 + return 0; 18 + } 19 + subsys_initcall(eisa_bus_probe);
+4
arch/x86/kernel/head32.c
··· 10 10 #include <linux/mm.h> 11 11 #include <linux/memblock.h> 12 12 13 + #include <asm/desc.h> 13 14 #include <asm/setup.h> 14 15 #include <asm/sections.h> 15 16 #include <asm/e820/api.h> ··· 31 30 asmlinkage __visible void __init i386_start_kernel(void) 32 31 { 33 32 cr4_init_shadow(); 33 + 34 + idt_setup_early_handler(); 35 + 34 36 sanitize_boot_params(&boot_params); 35 37 36 38 x86_early_init_platform_quirks();
+1 -5
arch/x86/kernel/head64.c
··· 311 311 312 312 asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data) 313 313 { 314 - int i; 315 - 316 314 /* 317 315 * Build-time sanity checks on the kernel image and module 318 316 * area mappings. (these are purely build-time and produce no code) ··· 343 345 344 346 kasan_early_init(); 345 347 346 - for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) 347 - set_intr_gate(i, early_idt_handler_array[i]); 348 - load_idt((const struct desc_ptr *)&idt_descr); 348 + idt_setup_early_handler(); 349 349 350 350 copy_bootdata(__va(real_mode_data)); 351 351
+3 -41
arch/x86/kernel/head_32.S
··· 345 345 movl %eax,%cr0 346 346 347 347 lgdt early_gdt_descr 348 - lidt idt_descr 349 348 ljmp $(__KERNEL_CS),$1f 350 349 1: movl $(__KERNEL_DS),%eax # reload all the segment registers 351 350 movl %eax,%ss # after changing gdt. ··· 377 378 */ 378 379 __INIT 379 380 setup_once: 380 - /* 381 - * Set up a idt with 256 interrupt gates that push zero if there 382 - * is no error code and then jump to early_idt_handler_common. 383 - * It doesn't actually load the idt - that needs to be done on 384 - * each CPU. Interrupts are enabled elsewhere, when we can be 385 - * relatively sure everything is ok. 386 - */ 387 - 388 - movl $idt_table,%edi 389 - movl $early_idt_handler_array,%eax 390 - movl $NUM_EXCEPTION_VECTORS,%ecx 391 - 1: 392 - movl %eax,(%edi) 393 - movl %eax,4(%edi) 394 - /* interrupt gate, dpl=0, present */ 395 - movl $(0x8E000000 + __KERNEL_CS),2(%edi) 396 - addl $EARLY_IDT_HANDLER_SIZE,%eax 397 - addl $8,%edi 398 - loop 1b 399 - 400 - movl $256 - NUM_EXCEPTION_VECTORS,%ecx 401 - movl $ignore_int,%edx 402 - movl $(__KERNEL_CS << 16),%eax 403 - movw %dx,%ax /* selector = 0x0010 = cs */ 404 - movw $0x8E00,%dx /* interrupt gate - dpl=0, present */ 405 - 2: 406 - movl %eax,(%edi) 407 - movl %edx,4(%edi) 408 - addl $8,%edi 409 - loop 2b 410 - 411 381 #ifdef CONFIG_CC_STACKPROTECTOR 412 382 /* 413 383 * Configure the stack canary. The linker can't handle this by ··· 465 497 ENDPROC(early_idt_handler_common) 466 498 467 499 /* This is the default interrupt "handler" :-) */ 468 - ALIGN 469 - ignore_int: 500 + ENTRY(early_ignore_irq) 470 501 cld 471 502 #ifdef CONFIG_PRINTK 472 503 pushl %eax ··· 500 533 hlt_loop: 501 534 hlt 502 535 jmp hlt_loop 503 - ENDPROC(ignore_int) 536 + ENDPROC(early_ignore_irq) 537 + 504 538 __INITDATA 505 539 .align 4 506 540 GLOBAL(early_recursion_flag) ··· 590 622 591 623 .data 592 624 .globl boot_gdt_descr 593 - .globl idt_descr 594 625 595 626 ALIGN 596 627 # early boot GDT descriptor (must use 1:1 address mapping) ··· 597 630 boot_gdt_descr: 598 631 .word __BOOT_DS+7 599 632 .long boot_gdt - __PAGE_OFFSET 600 - 601 - .word 0 # 32-bit align idt_desc.address 602 - idt_descr: 603 - .word IDT_ENTRIES*8-1 # idt contains 256 entries 604 - .long idt_table 605 633 606 634 # boot GDT descriptor (later on used by CPU#0): 607 635 .word 0 # 32 bit align gdt_desc.address
+371
arch/x86/kernel/idt.c
··· 1 + /* 2 + * Interrupt descriptor table related code 3 + * 4 + * This file is licensed under the GPL V2 5 + */ 6 + #include <linux/interrupt.h> 7 + 8 + #include <asm/traps.h> 9 + #include <asm/proto.h> 10 + #include <asm/desc.h> 11 + 12 + struct idt_data { 13 + unsigned int vector; 14 + unsigned int segment; 15 + struct idt_bits bits; 16 + const void *addr; 17 + }; 18 + 19 + #define DPL0 0x0 20 + #define DPL3 0x3 21 + 22 + #define DEFAULT_STACK 0 23 + 24 + #define G(_vector, _addr, _ist, _type, _dpl, _segment) \ 25 + { \ 26 + .vector = _vector, \ 27 + .bits.ist = _ist, \ 28 + .bits.type = _type, \ 29 + .bits.dpl = _dpl, \ 30 + .bits.p = 1, \ 31 + .addr = _addr, \ 32 + .segment = _segment, \ 33 + } 34 + 35 + /* Interrupt gate */ 36 + #define INTG(_vector, _addr) \ 37 + G(_vector, _addr, DEFAULT_STACK, GATE_INTERRUPT, DPL0, __KERNEL_CS) 38 + 39 + /* System interrupt gate */ 40 + #define SYSG(_vector, _addr) \ 41 + G(_vector, _addr, DEFAULT_STACK, GATE_INTERRUPT, DPL3, __KERNEL_CS) 42 + 43 + /* Interrupt gate with interrupt stack */ 44 + #define ISTG(_vector, _addr, _ist) \ 45 + G(_vector, _addr, _ist, GATE_INTERRUPT, DPL0, __KERNEL_CS) 46 + 47 + /* System interrupt gate with interrupt stack */ 48 + #define SISTG(_vector, _addr, _ist) \ 49 + G(_vector, _addr, _ist, GATE_INTERRUPT, DPL3, __KERNEL_CS) 50 + 51 + /* Task gate */ 52 + #define TSKG(_vector, _gdt) \ 53 + G(_vector, NULL, DEFAULT_STACK, GATE_TASK, DPL0, _gdt << 3) 54 + 55 + /* 56 + * Early traps running on the DEFAULT_STACK because the other interrupt 57 + * stacks work only after cpu_init(). 58 + */ 59 + static const __initdata struct idt_data early_idts[] = { 60 + INTG(X86_TRAP_DB, debug), 61 + SYSG(X86_TRAP_BP, int3), 62 + #ifdef CONFIG_X86_32 63 + INTG(X86_TRAP_PF, page_fault), 64 + #endif 65 + }; 66 + 67 + /* 68 + * The default IDT entries which are set up in trap_init() before 69 + * cpu_init() is invoked. Interrupt stacks cannot be used at that point and 70 + * the traps which use them are reinitialized with IST after cpu_init() has 71 + * set up TSS. 72 + */ 73 + static const __initdata struct idt_data def_idts[] = { 74 + INTG(X86_TRAP_DE, divide_error), 75 + INTG(X86_TRAP_NMI, nmi), 76 + INTG(X86_TRAP_BR, bounds), 77 + INTG(X86_TRAP_UD, invalid_op), 78 + INTG(X86_TRAP_NM, device_not_available), 79 + INTG(X86_TRAP_OLD_MF, coprocessor_segment_overrun), 80 + INTG(X86_TRAP_TS, invalid_TSS), 81 + INTG(X86_TRAP_NP, segment_not_present), 82 + INTG(X86_TRAP_SS, stack_segment), 83 + INTG(X86_TRAP_GP, general_protection), 84 + INTG(X86_TRAP_SPURIOUS, spurious_interrupt_bug), 85 + INTG(X86_TRAP_MF, coprocessor_error), 86 + INTG(X86_TRAP_AC, alignment_check), 87 + INTG(X86_TRAP_XF, simd_coprocessor_error), 88 + 89 + #ifdef CONFIG_X86_32 90 + TSKG(X86_TRAP_DF, GDT_ENTRY_DOUBLEFAULT_TSS), 91 + #else 92 + INTG(X86_TRAP_DF, double_fault), 93 + #endif 94 + INTG(X86_TRAP_DB, debug), 95 + INTG(X86_TRAP_NMI, nmi), 96 + INTG(X86_TRAP_BP, int3), 97 + 98 + #ifdef CONFIG_X86_MCE 99 + INTG(X86_TRAP_MC, &machine_check), 100 + #endif 101 + 102 + SYSG(X86_TRAP_OF, overflow), 103 + #if defined(CONFIG_IA32_EMULATION) 104 + SYSG(IA32_SYSCALL_VECTOR, entry_INT80_compat), 105 + #elif defined(CONFIG_X86_32) 106 + SYSG(IA32_SYSCALL_VECTOR, entry_INT80_32), 107 + #endif 108 + }; 109 + 110 + /* 111 + * The APIC and SMP idt entries 112 + */ 113 + static const __initdata struct idt_data apic_idts[] = { 114 + #ifdef CONFIG_SMP 115 + INTG(RESCHEDULE_VECTOR, reschedule_interrupt), 116 + INTG(CALL_FUNCTION_VECTOR, call_function_interrupt), 117 + INTG(CALL_FUNCTION_SINGLE_VECTOR, call_function_single_interrupt), 118 + INTG(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt), 119 + INTG(REBOOT_VECTOR, reboot_interrupt), 120 + #endif 121 + 122 + #ifdef CONFIG_X86_THERMAL_VECTOR 123 + INTG(THERMAL_APIC_VECTOR, thermal_interrupt), 124 + #endif 125 + 126 + #ifdef CONFIG_X86_MCE_THRESHOLD 127 + INTG(THRESHOLD_APIC_VECTOR, threshold_interrupt), 128 + #endif 129 + 130 + #ifdef CONFIG_X86_MCE_AMD 131 + INTG(DEFERRED_ERROR_VECTOR, deferred_error_interrupt), 132 + #endif 133 + 134 + #ifdef CONFIG_X86_LOCAL_APIC 135 + INTG(LOCAL_TIMER_VECTOR, apic_timer_interrupt), 136 + INTG(X86_PLATFORM_IPI_VECTOR, x86_platform_ipi), 137 + # ifdef CONFIG_HAVE_KVM 138 + INTG(POSTED_INTR_VECTOR, kvm_posted_intr_ipi), 139 + INTG(POSTED_INTR_WAKEUP_VECTOR, kvm_posted_intr_wakeup_ipi), 140 + INTG(POSTED_INTR_NESTED_VECTOR, kvm_posted_intr_nested_ipi), 141 + # endif 142 + # ifdef CONFIG_IRQ_WORK 143 + INTG(IRQ_WORK_VECTOR, irq_work_interrupt), 144 + # endif 145 + INTG(SPURIOUS_APIC_VECTOR, spurious_interrupt), 146 + INTG(ERROR_APIC_VECTOR, error_interrupt), 147 + #endif 148 + }; 149 + 150 + #ifdef CONFIG_X86_64 151 + /* 152 + * Early traps running on the DEFAULT_STACK because the other interrupt 153 + * stacks work only after cpu_init(). 154 + */ 155 + static const __initdata struct idt_data early_pf_idts[] = { 156 + INTG(X86_TRAP_PF, page_fault), 157 + }; 158 + 159 + /* 160 + * Override for the debug_idt. Same as the default, but with interrupt 161 + * stack set to DEFAULT_STACK (0). Required for NMI trap handling. 162 + */ 163 + static const __initdata struct idt_data dbg_idts[] = { 164 + INTG(X86_TRAP_DB, debug), 165 + INTG(X86_TRAP_BP, int3), 166 + }; 167 + #endif 168 + 169 + /* Must be page-aligned because the real IDT is used in a fixmap. */ 170 + gate_desc idt_table[IDT_ENTRIES] __page_aligned_bss; 171 + 172 + struct desc_ptr idt_descr __ro_after_init = { 173 + .size = (IDT_ENTRIES * 2 * sizeof(unsigned long)) - 1, 174 + .address = (unsigned long) idt_table, 175 + }; 176 + 177 + #ifdef CONFIG_X86_64 178 + /* No need to be aligned, but done to keep all IDTs defined the same way. */ 179 + gate_desc debug_idt_table[IDT_ENTRIES] __page_aligned_bss; 180 + 181 + /* 182 + * The exceptions which use Interrupt stacks. They are setup after 183 + * cpu_init() when the TSS has been initialized. 184 + */ 185 + static const __initdata struct idt_data ist_idts[] = { 186 + ISTG(X86_TRAP_DB, debug, DEBUG_STACK), 187 + ISTG(X86_TRAP_NMI, nmi, NMI_STACK), 188 + SISTG(X86_TRAP_BP, int3, DEBUG_STACK), 189 + ISTG(X86_TRAP_DF, double_fault, DOUBLEFAULT_STACK), 190 + #ifdef CONFIG_X86_MCE 191 + ISTG(X86_TRAP_MC, &machine_check, MCE_STACK), 192 + #endif 193 + }; 194 + 195 + /* 196 + * Override for the debug_idt. Same as the default, but with interrupt 197 + * stack set to DEFAULT_STACK (0). Required for NMI trap handling. 198 + */ 199 + const struct desc_ptr debug_idt_descr = { 200 + .size = IDT_ENTRIES * 16 - 1, 201 + .address = (unsigned long) debug_idt_table, 202 + }; 203 + #endif 204 + 205 + static inline void idt_init_desc(gate_desc *gate, const struct idt_data *d) 206 + { 207 + unsigned long addr = (unsigned long) d->addr; 208 + 209 + gate->offset_low = (u16) addr; 210 + gate->segment = (u16) d->segment; 211 + gate->bits = d->bits; 212 + gate->offset_middle = (u16) (addr >> 16); 213 + #ifdef CONFIG_X86_64 214 + gate->offset_high = (u32) (addr >> 32); 215 + gate->reserved = 0; 216 + #endif 217 + } 218 + 219 + static void 220 + idt_setup_from_table(gate_desc *idt, const struct idt_data *t, int size, bool sys) 221 + { 222 + gate_desc desc; 223 + 224 + for (; size > 0; t++, size--) { 225 + idt_init_desc(&desc, t); 226 + write_idt_entry(idt, t->vector, &desc); 227 + if (sys) 228 + set_bit(t->vector, used_vectors); 229 + } 230 + } 231 + 232 + static void set_intr_gate(unsigned int n, const void *addr) 233 + { 234 + struct idt_data data; 235 + 236 + BUG_ON(n > 0xFF); 237 + 238 + memset(&data, 0, sizeof(data)); 239 + data.vector = n; 240 + data.addr = addr; 241 + data.segment = __KERNEL_CS; 242 + data.bits.type = GATE_INTERRUPT; 243 + data.bits.p = 1; 244 + 245 + idt_setup_from_table(idt_table, &data, 1, false); 246 + } 247 + 248 + /** 249 + * idt_setup_early_traps - Initialize the idt table with early traps 250 + * 251 + * On X8664 these traps do not use interrupt stacks as they can't work 252 + * before cpu_init() is invoked and sets up TSS. The IST variants are 253 + * installed after that. 254 + */ 255 + void __init idt_setup_early_traps(void) 256 + { 257 + idt_setup_from_table(idt_table, early_idts, ARRAY_SIZE(early_idts), 258 + true); 259 + load_idt(&idt_descr); 260 + } 261 + 262 + /** 263 + * idt_setup_traps - Initialize the idt table with default traps 264 + */ 265 + void __init idt_setup_traps(void) 266 + { 267 + idt_setup_from_table(idt_table, def_idts, ARRAY_SIZE(def_idts), true); 268 + } 269 + 270 + #ifdef CONFIG_X86_64 271 + /** 272 + * idt_setup_early_pf - Initialize the idt table with early pagefault handler 273 + * 274 + * On X8664 this does not use interrupt stacks as they can't work before 275 + * cpu_init() is invoked and sets up TSS. The IST variant is installed 276 + * after that. 277 + * 278 + * FIXME: Why is 32bit and 64bit installing the PF handler at different 279 + * places in the early setup code? 280 + */ 281 + void __init idt_setup_early_pf(void) 282 + { 283 + idt_setup_from_table(idt_table, early_pf_idts, 284 + ARRAY_SIZE(early_pf_idts), true); 285 + } 286 + 287 + /** 288 + * idt_setup_ist_traps - Initialize the idt table with traps using IST 289 + */ 290 + void __init idt_setup_ist_traps(void) 291 + { 292 + idt_setup_from_table(idt_table, ist_idts, ARRAY_SIZE(ist_idts), true); 293 + } 294 + 295 + /** 296 + * idt_setup_debugidt_traps - Initialize the debug idt table with debug traps 297 + */ 298 + void __init idt_setup_debugidt_traps(void) 299 + { 300 + memcpy(&debug_idt_table, &idt_table, IDT_ENTRIES * 16); 301 + 302 + idt_setup_from_table(debug_idt_table, dbg_idts, ARRAY_SIZE(dbg_idts), false); 303 + } 304 + #endif 305 + 306 + /** 307 + * idt_setup_apic_and_irq_gates - Setup APIC/SMP and normal interrupt gates 308 + */ 309 + void __init idt_setup_apic_and_irq_gates(void) 310 + { 311 + int i = FIRST_EXTERNAL_VECTOR; 312 + void *entry; 313 + 314 + idt_setup_from_table(idt_table, apic_idts, ARRAY_SIZE(apic_idts), true); 315 + 316 + for_each_clear_bit_from(i, used_vectors, FIRST_SYSTEM_VECTOR) { 317 + entry = irq_entries_start + 8 * (i - FIRST_EXTERNAL_VECTOR); 318 + set_intr_gate(i, entry); 319 + } 320 + 321 + for_each_clear_bit_from(i, used_vectors, NR_VECTORS) { 322 + #ifdef CONFIG_X86_LOCAL_APIC 323 + set_bit(i, used_vectors); 324 + set_intr_gate(i, spurious_interrupt); 325 + #else 326 + entry = irq_entries_start + 8 * (i - FIRST_EXTERNAL_VECTOR); 327 + set_intr_gate(i, entry); 328 + #endif 329 + } 330 + } 331 + 332 + /** 333 + * idt_setup_early_handler - Initializes the idt table with early handlers 334 + */ 335 + void __init idt_setup_early_handler(void) 336 + { 337 + int i; 338 + 339 + for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) 340 + set_intr_gate(i, early_idt_handler_array[i]); 341 + #ifdef CONFIG_X86_32 342 + for ( ; i < NR_VECTORS; i++) 343 + set_intr_gate(i, early_ignore_irq); 344 + #endif 345 + load_idt(&idt_descr); 346 + } 347 + 348 + /** 349 + * idt_invalidate - Invalidate interrupt descriptor table 350 + * @addr: The virtual address of the 'invalid' IDT 351 + */ 352 + void idt_invalidate(void *addr) 353 + { 354 + struct desc_ptr idt = { .address = (unsigned long) addr, .size = 0 }; 355 + 356 + load_idt(&idt); 357 + } 358 + 359 + void __init update_intr_gate(unsigned int n, const void *addr) 360 + { 361 + if (WARN_ON_ONCE(!test_bit(n, used_vectors))) 362 + return; 363 + set_intr_gate(n, addr); 364 + } 365 + 366 + void alloc_intr_gate(unsigned int n, const void *addr) 367 + { 368 + BUG_ON(n < FIRST_SYSTEM_VECTOR); 369 + if (!test_and_set_bit(n, used_vectors)) 370 + set_intr_gate(n, addr); 371 + }
+12 -28
arch/x86/kernel/irq.c
··· 29 29 30 30 atomic_t irq_err_count; 31 31 32 - /* Function pointer for generic interrupt vector handling */ 33 - void (*x86_platform_ipi_callback)(void) = NULL; 34 - 35 32 /* 36 33 * 'what should we do if we get a hw irq event on an illegal vector'. 37 34 * each architecture has to answer this themselves. ··· 84 87 for_each_online_cpu(j) 85 88 seq_printf(p, "%10u ", irq_stats(j)->icr_read_retry_count); 86 89 seq_puts(p, " APIC ICR read retries\n"); 87 - #endif 88 90 if (x86_platform_ipi_callback) { 89 91 seq_printf(p, "%*s: ", prec, "PLT"); 90 92 for_each_online_cpu(j) 91 93 seq_printf(p, "%10u ", irq_stats(j)->x86_platform_ipis); 92 94 seq_puts(p, " Platform interrupts\n"); 93 95 } 96 + #endif 94 97 #ifdef CONFIG_SMP 95 98 seq_printf(p, "%*s: ", prec, "RES"); 96 99 for_each_online_cpu(j) ··· 180 183 sum += irq_stats(cpu)->apic_perf_irqs; 181 184 sum += irq_stats(cpu)->apic_irq_work_irqs; 182 185 sum += irq_stats(cpu)->icr_read_retry_count; 183 - #endif 184 186 if (x86_platform_ipi_callback) 185 187 sum += irq_stats(cpu)->x86_platform_ipis; 188 + #endif 186 189 #ifdef CONFIG_SMP 187 190 sum += irq_stats(cpu)->irq_resched_count; 188 191 sum += irq_stats(cpu)->irq_call_count; ··· 256 259 return 1; 257 260 } 258 261 262 + #ifdef CONFIG_X86_LOCAL_APIC 263 + /* Function pointer for generic interrupt vector handling */ 264 + void (*x86_platform_ipi_callback)(void) = NULL; 259 265 /* 260 266 * Handler for X86_PLATFORM_IPI_VECTOR. 261 267 */ 262 - void __smp_x86_platform_ipi(void) 263 - { 264 - inc_irq_stat(x86_platform_ipis); 265 - 266 - if (x86_platform_ipi_callback) 267 - x86_platform_ipi_callback(); 268 - } 269 - 270 268 __visible void __irq_entry smp_x86_platform_ipi(struct pt_regs *regs) 271 269 { 272 270 struct pt_regs *old_regs = set_irq_regs(regs); 273 271 274 272 entering_ack_irq(); 275 - __smp_x86_platform_ipi(); 273 + trace_x86_platform_ipi_entry(X86_PLATFORM_IPI_VECTOR); 274 + inc_irq_stat(x86_platform_ipis); 275 + if (x86_platform_ipi_callback) 276 + x86_platform_ipi_callback(); 277 + trace_x86_platform_ipi_exit(X86_PLATFORM_IPI_VECTOR); 276 278 exiting_irq(); 277 279 set_irq_regs(old_regs); 278 280 } 281 + #endif 279 282 280 283 #ifdef CONFIG_HAVE_KVM 281 284 static void dummy_handler(void) {} ··· 331 334 } 332 335 #endif 333 336 334 - __visible void __irq_entry smp_trace_x86_platform_ipi(struct pt_regs *regs) 335 - { 336 - struct pt_regs *old_regs = set_irq_regs(regs); 337 - 338 - entering_ack_irq(); 339 - trace_x86_platform_ipi_entry(X86_PLATFORM_IPI_VECTOR); 340 - __smp_x86_platform_ipi(); 341 - trace_x86_platform_ipi_exit(X86_PLATFORM_IPI_VECTOR); 342 - exiting_irq(); 343 - set_irq_regs(old_regs); 344 - } 345 - 346 - EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq); 347 337 348 338 #ifdef CONFIG_HOTPLUG_CPU 349 339 ··· 415 431 * this w/o holding vector_lock. 416 432 */ 417 433 for (vector = FIRST_EXTERNAL_VECTOR; 418 - vector < first_system_vector; vector++) { 434 + vector < FIRST_SYSTEM_VECTOR; vector++) { 419 435 if (!test_bit(vector, used_vectors) && 420 436 IS_ERR_OR_NULL(per_cpu(vector_irq, cpu)[vector])) { 421 437 if (++count == this_count)
+4 -16
arch/x86/kernel/irq_work.c
··· 11 11 #include <asm/trace/irq_vectors.h> 12 12 #include <linux/interrupt.h> 13 13 14 - static inline void __smp_irq_work_interrupt(void) 15 - { 16 - inc_irq_stat(apic_irq_work_irqs); 17 - irq_work_run(); 18 - } 19 - 14 + #ifdef CONFIG_X86_LOCAL_APIC 20 15 __visible void __irq_entry smp_irq_work_interrupt(struct pt_regs *regs) 21 16 { 22 17 ipi_entering_ack_irq(); 23 - __smp_irq_work_interrupt(); 24 - exiting_irq(); 25 - } 26 - 27 - __visible void __irq_entry smp_trace_irq_work_interrupt(struct pt_regs *regs) 28 - { 29 - ipi_entering_ack_irq(); 30 18 trace_irq_work_entry(IRQ_WORK_VECTOR); 31 - __smp_irq_work_interrupt(); 19 + inc_irq_stat(apic_irq_work_irqs); 20 + irq_work_run(); 32 21 trace_irq_work_exit(IRQ_WORK_VECTOR); 33 22 exiting_irq(); 34 23 } 35 24 36 25 void arch_irq_work_raise(void) 37 26 { 38 - #ifdef CONFIG_X86_LOCAL_APIC 39 27 if (!arch_irq_work_has_interrupt()) 40 28 return; 41 29 42 30 apic->send_IPI_self(IRQ_WORK_VECTOR); 43 31 apic_wait_icr_idle(); 44 - #endif 45 32 } 33 + #endif
+1 -101
arch/x86/kernel/irqinit.c
··· 55 55 [0 ... NR_VECTORS - 1] = VECTOR_UNUSED, 56 56 }; 57 57 58 - int vector_used_by_percpu_irq(unsigned int vector) 59 - { 60 - int cpu; 61 - 62 - for_each_online_cpu(cpu) { 63 - if (!IS_ERR_OR_NULL(per_cpu(vector_irq, cpu)[vector])) 64 - return 1; 65 - } 66 - 67 - return 0; 68 - } 69 - 70 58 void __init init_ISA_irqs(void) 71 59 { 72 60 struct irq_chip *chip = legacy_pic->chip; ··· 87 99 x86_init.irqs.intr_init(); 88 100 } 89 101 90 - static void __init smp_intr_init(void) 91 - { 92 - #ifdef CONFIG_SMP 93 - /* 94 - * The reschedule interrupt is a CPU-to-CPU reschedule-helper 95 - * IPI, driven by wakeup. 96 - */ 97 - alloc_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt); 98 - 99 - /* IPI for generic function call */ 100 - alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); 101 - 102 - /* IPI for generic single function call */ 103 - alloc_intr_gate(CALL_FUNCTION_SINGLE_VECTOR, 104 - call_function_single_interrupt); 105 - 106 - /* Low priority IPI to cleanup after moving an irq */ 107 - set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt); 108 - set_bit(IRQ_MOVE_CLEANUP_VECTOR, used_vectors); 109 - 110 - /* IPI used for rebooting/stopping */ 111 - alloc_intr_gate(REBOOT_VECTOR, reboot_interrupt); 112 - #endif /* CONFIG_SMP */ 113 - } 114 - 115 - static void __init apic_intr_init(void) 116 - { 117 - smp_intr_init(); 118 - 119 - #ifdef CONFIG_X86_THERMAL_VECTOR 120 - alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt); 121 - #endif 122 - #ifdef CONFIG_X86_MCE_THRESHOLD 123 - alloc_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt); 124 - #endif 125 - 126 - #ifdef CONFIG_X86_MCE_AMD 127 - alloc_intr_gate(DEFERRED_ERROR_VECTOR, deferred_error_interrupt); 128 - #endif 129 - 130 - #ifdef CONFIG_X86_LOCAL_APIC 131 - /* self generated IPI for local APIC timer */ 132 - alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); 133 - 134 - /* IPI for X86 platform specific use */ 135 - alloc_intr_gate(X86_PLATFORM_IPI_VECTOR, x86_platform_ipi); 136 - #ifdef CONFIG_HAVE_KVM 137 - /* IPI for KVM to deliver posted interrupt */ 138 - alloc_intr_gate(POSTED_INTR_VECTOR, kvm_posted_intr_ipi); 139 - /* IPI for KVM to deliver interrupt to wake up tasks */ 140 - alloc_intr_gate(POSTED_INTR_WAKEUP_VECTOR, kvm_posted_intr_wakeup_ipi); 141 - /* IPI for KVM to deliver nested posted interrupt */ 142 - alloc_intr_gate(POSTED_INTR_NESTED_VECTOR, kvm_posted_intr_nested_ipi); 143 - #endif 144 - 145 - /* IPI vectors for APIC spurious and error interrupts */ 146 - alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); 147 - alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt); 148 - 149 - /* IRQ work interrupts: */ 150 - # ifdef CONFIG_IRQ_WORK 151 - alloc_intr_gate(IRQ_WORK_VECTOR, irq_work_interrupt); 152 - # endif 153 - 154 - #endif 155 - } 156 - 157 102 void __init native_init_IRQ(void) 158 103 { 159 - int i; 160 - 161 104 /* Execute any quirks before the call gates are initialised: */ 162 105 x86_init.irqs.pre_vector_init(); 163 106 164 - apic_intr_init(); 165 - 166 - /* 167 - * Cover the whole vector space, no vector can escape 168 - * us. (some of these will be overridden and become 169 - * 'special' SMP interrupts) 170 - */ 171 - i = FIRST_EXTERNAL_VECTOR; 172 - #ifndef CONFIG_X86_LOCAL_APIC 173 - #define first_system_vector NR_VECTORS 174 - #endif 175 - for_each_clear_bit_from(i, used_vectors, first_system_vector) { 176 - /* IA32_SYSCALL_VECTOR could be used in trap_init already. */ 177 - set_intr_gate(i, irq_entries_start + 178 - 8 * (i - FIRST_EXTERNAL_VECTOR)); 179 - } 180 - #ifdef CONFIG_X86_LOCAL_APIC 181 - for_each_clear_bit_from(i, used_vectors, NR_VECTORS) 182 - set_intr_gate(i, spurious_interrupt); 183 - #endif 107 + idt_setup_apic_and_irq_gates(); 184 108 185 109 if (!acpi_ioapic && !of_ioapic && nr_legacy_irqs()) 186 110 setup_irq(2, &irq2);
+2 -2
arch/x86/kernel/kvm.c
··· 263 263 264 264 switch (kvm_read_and_reset_pf_reason()) { 265 265 default: 266 - trace_do_page_fault(regs, error_code); 266 + do_page_fault(regs, error_code); 267 267 break; 268 268 case KVM_PV_REASON_PAGE_NOT_PRESENT: 269 269 /* page is swapped out by the host. */ ··· 455 455 456 456 static void __init kvm_apf_trap_init(void) 457 457 { 458 - set_intr_gate(14, async_page_fault); 458 + update_intr_gate(X86_TRAP_PF, async_page_fault); 459 459 } 460 460 461 461 void __init kvm_guest_init(void)
+1 -13
arch/x86/kernel/machine_kexec_32.c
··· 26 26 #include <asm/set_memory.h> 27 27 #include <asm/debugreg.h> 28 28 29 - static void set_idt(void *newidt, __u16 limit) 30 - { 31 - struct desc_ptr curidt; 32 - 33 - /* ia32 supports unaliged loads & stores */ 34 - curidt.size = limit; 35 - curidt.address = (unsigned long)newidt; 36 - 37 - load_idt(&curidt); 38 - } 39 - 40 - 41 29 static void set_gdt(void *newgdt, __u16 limit) 42 30 { 43 31 struct desc_ptr curgdt; ··· 233 245 * If you want to load them you must set up your own idt & gdt. 234 246 */ 235 247 set_gdt(phys_to_virt(0), 0); 236 - set_idt(phys_to_virt(0), 0); 248 + idt_invalidate(phys_to_virt(0)); 237 249 238 250 /* now call it */ 239 251 image->start = relocate_kernel_ptr((unsigned long)image->head,
-3
arch/x86/kernel/paravirt.c
··· 319 319 .irq_enable = __PV_IS_CALLEE_SAVE(native_irq_enable), 320 320 .safe_halt = native_safe_halt, 321 321 .halt = native_halt, 322 - #ifdef CONFIG_X86_64 323 - .adjust_exception_frame = paravirt_nop, 324 - #endif 325 322 }; 326 323 327 324 __visible struct pv_cpu_ops pv_cpu_ops = {
+1 -3
arch/x86/kernel/reboot.c
··· 38 38 void (*pm_power_off)(void); 39 39 EXPORT_SYMBOL(pm_power_off); 40 40 41 - static const struct desc_ptr no_idt = {}; 42 - 43 41 /* 44 42 * This is set if we need to go through the 'emergency' path. 45 43 * When machine_emergency_restart() is called, we may be on ··· 636 638 break; 637 639 638 640 case BOOT_TRIPLE: 639 - load_idt(&no_idt); 641 + idt_invalidate(NULL); 640 642 __asm__ __volatile__("int3"); 641 643 642 644 /* We're probably dead after this, but... */
+2 -2
arch/x86/kernel/setup.c
··· 900 900 */ 901 901 olpc_ofw_detect(); 902 902 903 - early_trap_init(); 903 + idt_setup_early_traps(); 904 904 early_cpu_init(); 905 905 early_ioremap_init(); 906 906 ··· 1171 1171 1172 1172 init_mem_mapping(); 1173 1173 1174 - early_trap_pf_init(); 1174 + idt_setup_early_pf(); 1175 1175 1176 1176 /* 1177 1177 * Update mmu_cr4_features (and, indirectly, trampoline_cr4_features)
+3 -6
arch/x86/kernel/setup_percpu.c
··· 155 155 static inline void setup_percpu_segment(int cpu) 156 156 { 157 157 #ifdef CONFIG_X86_32 158 - struct desc_struct gdt; 158 + struct desc_struct d = GDT_ENTRY_INIT(0x8092, per_cpu_offset(cpu), 159 + 0xFFFFF); 159 160 160 - pack_descriptor(&gdt, per_cpu_offset(cpu), 0xFFFFF, 161 - 0x2 | DESCTYPE_S, 0x8); 162 - gdt.s = 1; 163 - write_gdt_entry(get_cpu_gdt_rw(cpu), 164 - GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S); 161 + write_gdt_entry(get_cpu_gdt_rw(cpu), GDT_ENTRY_PERCPU, &d, DESCTYPE_S); 165 162 #endif 166 163 } 167 164
+21 -60
arch/x86/kernel/smp.c
··· 254 254 } 255 255 256 256 /* 257 - * Reschedule call back. 257 + * Reschedule call back. KVM uses this interrupt to force a cpu out of 258 + * guest mode 258 259 */ 259 - static inline void __smp_reschedule_interrupt(void) 260 - { 261 - inc_irq_stat(irq_resched_count); 262 - scheduler_ipi(); 263 - } 264 - 265 260 __visible void __irq_entry smp_reschedule_interrupt(struct pt_regs *regs) 266 261 { 267 262 ack_APIC_irq(); 268 - __smp_reschedule_interrupt(); 269 - /* 270 - * KVM uses this interrupt to force a cpu out of guest mode 271 - */ 272 - } 263 + inc_irq_stat(irq_resched_count); 273 264 274 - __visible void __irq_entry smp_trace_reschedule_interrupt(struct pt_regs *regs) 275 - { 276 - /* 277 - * Need to call irq_enter() before calling the trace point. 278 - * __smp_reschedule_interrupt() calls irq_enter/exit() too (in 279 - * scheduler_ipi(). This is OK, since those functions are allowed 280 - * to nest. 281 - */ 282 - ipi_entering_ack_irq(); 283 - trace_reschedule_entry(RESCHEDULE_VECTOR); 284 - __smp_reschedule_interrupt(); 285 - trace_reschedule_exit(RESCHEDULE_VECTOR); 286 - exiting_irq(); 287 - /* 288 - * KVM uses this interrupt to force a cpu out of guest mode 289 - */ 290 - } 291 - 292 - static inline void __smp_call_function_interrupt(void) 293 - { 294 - generic_smp_call_function_interrupt(); 295 - inc_irq_stat(irq_call_count); 265 + if (trace_resched_ipi_enabled()) { 266 + /* 267 + * scheduler_ipi() might call irq_enter() as well, but 268 + * nested calls are fine. 269 + */ 270 + irq_enter(); 271 + trace_reschedule_entry(RESCHEDULE_VECTOR); 272 + scheduler_ipi(); 273 + trace_reschedule_exit(RESCHEDULE_VECTOR); 274 + irq_exit(); 275 + return; 276 + } 277 + scheduler_ipi(); 296 278 } 297 279 298 280 __visible void __irq_entry smp_call_function_interrupt(struct pt_regs *regs) 299 281 { 300 282 ipi_entering_ack_irq(); 301 - __smp_call_function_interrupt(); 302 - exiting_irq(); 303 - } 304 - 305 - __visible void __irq_entry 306 - smp_trace_call_function_interrupt(struct pt_regs *regs) 307 - { 308 - ipi_entering_ack_irq(); 309 283 trace_call_function_entry(CALL_FUNCTION_VECTOR); 310 - __smp_call_function_interrupt(); 284 + inc_irq_stat(irq_call_count); 285 + generic_smp_call_function_interrupt(); 311 286 trace_call_function_exit(CALL_FUNCTION_VECTOR); 312 287 exiting_irq(); 313 288 } 314 289 315 - static inline void __smp_call_function_single_interrupt(void) 316 - { 317 - generic_smp_call_function_single_interrupt(); 318 - inc_irq_stat(irq_call_count); 319 - } 320 - 321 - __visible void __irq_entry 322 - smp_call_function_single_interrupt(struct pt_regs *regs) 323 - { 324 - ipi_entering_ack_irq(); 325 - __smp_call_function_single_interrupt(); 326 - exiting_irq(); 327 - } 328 - 329 - __visible void __irq_entry 330 - smp_trace_call_function_single_interrupt(struct pt_regs *regs) 290 + __visible void __irq_entry smp_call_function_single_interrupt(struct pt_regs *r) 331 291 { 332 292 ipi_entering_ack_irq(); 333 293 trace_call_function_single_entry(CALL_FUNCTION_SINGLE_VECTOR); 334 - __smp_call_function_single_interrupt(); 294 + inc_irq_stat(irq_call_count); 295 + generic_smp_call_function_single_interrupt(); 335 296 trace_call_function_single_exit(CALL_FUNCTION_SINGLE_VECTOR); 336 297 exiting_irq(); 337 298 }
+1 -1
arch/x86/kernel/tls.c
··· 93 93 94 94 while (n-- > 0) { 95 95 if (LDT_empty(info) || LDT_zero(info)) { 96 - desc->a = desc->b = 0; 96 + memset(desc, 0, sizeof(*desc)); 97 97 } else { 98 98 fill_ldt(desc, info); 99 99
+25 -44
arch/x86/kernel/tracepoint.c
··· 4 4 * Copyright (C) 2013 Seiji Aguchi <seiji.aguchi@hds.com> 5 5 * 6 6 */ 7 - #include <asm/hw_irq.h> 8 - #include <asm/desc.h> 7 + #include <linux/jump_label.h> 9 8 #include <linux/atomic.h> 10 9 11 - atomic_t trace_idt_ctr = ATOMIC_INIT(0); 12 - struct desc_ptr trace_idt_descr = { NR_VECTORS * 16 - 1, 13 - (unsigned long) trace_idt_table }; 10 + #include <asm/hw_irq.h> 11 + #include <asm/desc.h> 14 12 15 - /* No need to be aligned, but done to keep all IDTs defined the same way. */ 16 - gate_desc trace_idt_table[NR_VECTORS] __page_aligned_bss; 13 + DEFINE_STATIC_KEY_FALSE(trace_pagefault_key); 17 14 18 - static int trace_irq_vector_refcount; 19 - static DEFINE_MUTEX(irq_vector_mutex); 20 - 21 - static void set_trace_idt_ctr(int val) 15 + int trace_pagefault_reg(void) 22 16 { 23 - atomic_set(&trace_idt_ctr, val); 24 - /* Ensure the trace_idt_ctr is set before sending IPI */ 25 - wmb(); 26 - } 27 - 28 - static void switch_idt(void *arg) 29 - { 30 - unsigned long flags; 31 - 32 - local_irq_save(flags); 33 - load_current_idt(); 34 - local_irq_restore(flags); 35 - } 36 - 37 - int trace_irq_vector_regfunc(void) 38 - { 39 - mutex_lock(&irq_vector_mutex); 40 - if (!trace_irq_vector_refcount) { 41 - set_trace_idt_ctr(1); 42 - smp_call_function(switch_idt, NULL, 0); 43 - switch_idt(NULL); 44 - } 45 - trace_irq_vector_refcount++; 46 - mutex_unlock(&irq_vector_mutex); 17 + static_branch_inc(&trace_pagefault_key); 47 18 return 0; 48 19 } 49 20 50 - void trace_irq_vector_unregfunc(void) 21 + void trace_pagefault_unreg(void) 51 22 { 52 - mutex_lock(&irq_vector_mutex); 53 - trace_irq_vector_refcount--; 54 - if (!trace_irq_vector_refcount) { 55 - set_trace_idt_ctr(0); 56 - smp_call_function(switch_idt, NULL, 0); 57 - switch_idt(NULL); 58 - } 59 - mutex_unlock(&irq_vector_mutex); 23 + static_branch_dec(&trace_pagefault_key); 60 24 } 25 + 26 + #ifdef CONFIG_SMP 27 + 28 + DEFINE_STATIC_KEY_FALSE(trace_resched_ipi_key); 29 + 30 + int trace_resched_ipi_reg(void) 31 + { 32 + static_branch_inc(&trace_resched_ipi_key); 33 + return 0; 34 + } 35 + 36 + void trace_resched_ipi_unreg(void) 37 + { 38 + static_branch_dec(&trace_resched_ipi_key); 39 + } 40 + 41 + #endif
+3 -104
arch/x86/kernel/traps.c
··· 38 38 #include <linux/smp.h> 39 39 #include <linux/io.h> 40 40 41 - #ifdef CONFIG_EISA 42 - #include <linux/ioport.h> 43 - #include <linux/eisa.h> 44 - #endif 45 - 46 41 #if defined(CONFIG_EDAC) 47 42 #include <linux/edac.h> 48 43 #endif ··· 65 70 #include <asm/x86_init.h> 66 71 #include <asm/pgalloc.h> 67 72 #include <asm/proto.h> 68 - 69 - /* No need to be aligned, but done to keep all IDTs defined the same way. */ 70 - gate_desc debug_idt_table[NR_VECTORS] __page_aligned_bss; 71 73 #else 72 74 #include <asm/processor-flags.h> 73 75 #include <asm/setup.h> 74 76 #include <asm/proto.h> 75 77 #endif 76 78 77 - /* Must be page-aligned because the real IDT is used in a fixmap. */ 78 - gate_desc idt_table[NR_VECTORS] __page_aligned_bss; 79 - 80 79 DECLARE_BITMAP(used_vectors, NR_VECTORS); 81 - EXPORT_SYMBOL_GPL(used_vectors); 82 80 83 81 static inline void cond_local_irq_enable(struct pt_regs *regs) 84 82 { ··· 923 935 } 924 936 #endif 925 937 926 - /* Set of traps needed for early debugging. */ 927 - void __init early_trap_init(void) 928 - { 929 - /* 930 - * Don't use IST to set DEBUG_STACK as it doesn't work until TSS 931 - * is ready in cpu_init() <-- trap_init(). Before trap_init(), 932 - * CPU runs at ring 0 so it is impossible to hit an invalid 933 - * stack. Using the original stack works well enough at this 934 - * early stage. DEBUG_STACK will be equipped after cpu_init() in 935 - * trap_init(). 936 - * 937 - * We don't need to set trace_idt_table like set_intr_gate(), 938 - * since we don't have trace_debug and it will be reset to 939 - * 'debug' in trap_init() by set_intr_gate_ist(). 940 - */ 941 - set_intr_gate_notrace(X86_TRAP_DB, debug); 942 - /* int3 can be called from all */ 943 - set_system_intr_gate(X86_TRAP_BP, &int3); 944 - #ifdef CONFIG_X86_32 945 - set_intr_gate(X86_TRAP_PF, page_fault); 946 - #endif 947 - load_idt(&idt_descr); 948 - } 949 - 950 - void __init early_trap_pf_init(void) 951 - { 952 - #ifdef CONFIG_X86_64 953 - set_intr_gate(X86_TRAP_PF, page_fault); 954 - #endif 955 - } 956 - 957 938 void __init trap_init(void) 958 939 { 959 - int i; 960 - 961 - #ifdef CONFIG_EISA 962 - void __iomem *p = early_ioremap(0x0FFFD9, 4); 963 - 964 - if (readl(p) == 'E' + ('I'<<8) + ('S'<<16) + ('A'<<24)) 965 - EISA_bus = 1; 966 - early_iounmap(p, 4); 967 - #endif 968 - 969 - set_intr_gate(X86_TRAP_DE, divide_error); 970 - set_intr_gate_ist(X86_TRAP_NMI, &nmi, NMI_STACK); 971 - /* int4 can be called from all */ 972 - set_system_intr_gate(X86_TRAP_OF, &overflow); 973 - set_intr_gate(X86_TRAP_BR, bounds); 974 - set_intr_gate(X86_TRAP_UD, invalid_op); 975 - set_intr_gate(X86_TRAP_NM, device_not_available); 976 - #ifdef CONFIG_X86_32 977 - set_task_gate(X86_TRAP_DF, GDT_ENTRY_DOUBLEFAULT_TSS); 978 - #else 979 - set_intr_gate_ist(X86_TRAP_DF, &double_fault, DOUBLEFAULT_STACK); 980 - #endif 981 - set_intr_gate(X86_TRAP_OLD_MF, coprocessor_segment_overrun); 982 - set_intr_gate(X86_TRAP_TS, invalid_TSS); 983 - set_intr_gate(X86_TRAP_NP, segment_not_present); 984 - set_intr_gate(X86_TRAP_SS, stack_segment); 985 - set_intr_gate(X86_TRAP_GP, general_protection); 986 - set_intr_gate(X86_TRAP_SPURIOUS, spurious_interrupt_bug); 987 - set_intr_gate(X86_TRAP_MF, coprocessor_error); 988 - set_intr_gate(X86_TRAP_AC, alignment_check); 989 - #ifdef CONFIG_X86_MCE 990 - set_intr_gate_ist(X86_TRAP_MC, &machine_check, MCE_STACK); 991 - #endif 992 - set_intr_gate(X86_TRAP_XF, simd_coprocessor_error); 993 - 994 - /* Reserve all the builtin and the syscall vector: */ 995 - for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++) 996 - set_bit(i, used_vectors); 997 - 998 - #ifdef CONFIG_IA32_EMULATION 999 - set_system_intr_gate(IA32_SYSCALL_VECTOR, entry_INT80_compat); 1000 - set_bit(IA32_SYSCALL_VECTOR, used_vectors); 1001 - #endif 1002 - 1003 - #ifdef CONFIG_X86_32 1004 - set_system_intr_gate(IA32_SYSCALL_VECTOR, entry_INT80_32); 1005 - set_bit(IA32_SYSCALL_VECTOR, used_vectors); 1006 - #endif 940 + idt_setup_traps(); 1007 941 1008 942 /* 1009 943 * Set the IDT descriptor to a fixed read-only location, so that the ··· 940 1030 */ 941 1031 cpu_init(); 942 1032 943 - /* 944 - * X86_TRAP_DB and X86_TRAP_BP have been set 945 - * in early_trap_init(). However, ITS works only after 946 - * cpu_init() loads TSS. See comments in early_trap_init(). 947 - */ 948 - set_intr_gate_ist(X86_TRAP_DB, &debug, DEBUG_STACK); 949 - /* int3 can be called from all */ 950 - set_system_intr_gate_ist(X86_TRAP_BP, &int3, DEBUG_STACK); 1033 + idt_setup_ist_traps(); 951 1034 952 1035 x86_init.irqs.trap_init(); 953 1036 954 - #ifdef CONFIG_X86_64 955 - memcpy(&debug_idt_table, &idt_table, IDT_ENTRIES * 16); 956 - set_nmi_gate(X86_TRAP_DB, &debug); 957 - set_nmi_gate(X86_TRAP_BP, &int3); 958 - #endif 1037 + idt_setup_debugidt_traps(); 959 1038 }
+1 -1
arch/x86/kvm/vmx.c
··· 8779 8779 8780 8780 vector = exit_intr_info & INTR_INFO_VECTOR_MASK; 8781 8781 desc = (gate_desc *)vmx->host_idt_base + vector; 8782 - entry = gate_offset(*desc); 8782 + entry = gate_offset(desc); 8783 8783 asm volatile( 8784 8784 #ifdef CONFIG_X86_64 8785 8785 "mov %%" _ASM_SP ", %[sp]\n\t"
+5 -6
arch/x86/math-emu/fpu_entry.c
··· 147 147 } 148 148 149 149 code_descriptor = FPU_get_ldt_descriptor(FPU_CS); 150 - if (SEG_D_SIZE(code_descriptor)) { 150 + if (code_descriptor.d) { 151 151 /* The above test may be wrong, the book is not clear */ 152 152 /* Segmented 32 bit protected mode */ 153 153 addr_modes.default_mode = SEG32; ··· 155 155 /* 16 bit protected mode */ 156 156 addr_modes.default_mode = PM16; 157 157 } 158 - FPU_EIP += code_base = SEG_BASE_ADDR(code_descriptor); 159 - code_limit = code_base 160 - + (SEG_LIMIT(code_descriptor) + 161 - 1) * SEG_GRANULARITY(code_descriptor) 162 - - 1; 158 + FPU_EIP += code_base = seg_get_base(&code_descriptor); 159 + code_limit = seg_get_limit(&code_descriptor) + 1; 160 + code_limit *= seg_get_granularity(&code_descriptor); 161 + code_limit += code_base - 1; 163 162 if (code_limit < code_base) 164 163 code_limit = 0xffffffff; 165 164 }
+37 -11
arch/x86/math-emu/fpu_system.h
··· 34 34 return ret; 35 35 } 36 36 37 - #define SEG_D_SIZE(x) ((x).b & (3 << 21)) 38 - #define SEG_G_BIT(x) ((x).b & (1 << 23)) 39 - #define SEG_GRANULARITY(x) (((x).b & (1 << 23)) ? 4096 : 1) 40 - #define SEG_286_MODE(x) ((x).b & ( 0xff000000 | 0xf0000 | (1 << 23))) 41 - #define SEG_BASE_ADDR(s) (((s).b & 0xff000000) \ 42 - | (((s).b & 0xff) << 16) | ((s).a >> 16)) 43 - #define SEG_LIMIT(s) (((s).b & 0xff0000) | ((s).a & 0xffff)) 44 - #define SEG_EXECUTE_ONLY(s) (((s).b & ((1 << 11) | (1 << 9))) == (1 << 11)) 45 - #define SEG_WRITE_PERM(s) (((s).b & ((1 << 11) | (1 << 9))) == (1 << 9)) 46 - #define SEG_EXPAND_DOWN(s) (((s).b & ((1 << 11) | (1 << 10))) \ 47 - == (1 << 10)) 37 + #define SEG_TYPE_WRITABLE (1U << 1) 38 + #define SEG_TYPE_EXPANDS_DOWN (1U << 2) 39 + #define SEG_TYPE_EXECUTE (1U << 3) 40 + #define SEG_TYPE_EXPAND_MASK (SEG_TYPE_EXPANDS_DOWN | SEG_TYPE_EXECUTE) 41 + #define SEG_TYPE_EXECUTE_MASK (SEG_TYPE_WRITABLE | SEG_TYPE_EXECUTE) 42 + 43 + static inline unsigned long seg_get_base(struct desc_struct *d) 44 + { 45 + unsigned long base = (unsigned long)d->base2 << 24; 46 + 47 + return base | ((unsigned long)d->base1 << 16) | d->base0; 48 + } 49 + 50 + static inline unsigned long seg_get_limit(struct desc_struct *d) 51 + { 52 + return ((unsigned long)d->limit1 << 16) | d->limit0; 53 + } 54 + 55 + static inline unsigned long seg_get_granularity(struct desc_struct *d) 56 + { 57 + return d->g ? 4096 : 1; 58 + } 59 + 60 + static inline bool seg_expands_down(struct desc_struct *d) 61 + { 62 + return (d->type & SEG_TYPE_EXPAND_MASK) == SEG_TYPE_EXPANDS_DOWN; 63 + } 64 + 65 + static inline bool seg_execute_only(struct desc_struct *d) 66 + { 67 + return (d->type & SEG_TYPE_EXECUTE_MASK) == SEG_TYPE_EXECUTE; 68 + } 69 + 70 + static inline bool seg_writable(struct desc_struct *d) 71 + { 72 + return (d->type & SEG_TYPE_EXECUTE_MASK) == SEG_TYPE_WRITABLE; 73 + } 48 74 49 75 #define I387 (&current->thread.fpu.state) 50 76 #define FPU_info (I387->soft.info)
+9 -8
arch/x86/math-emu/get_address.c
··· 159 159 } 160 160 161 161 descriptor = FPU_get_ldt_descriptor(addr->selector); 162 - base_address = SEG_BASE_ADDR(descriptor); 162 + base_address = seg_get_base(&descriptor); 163 163 address = base_address + offset; 164 - limit = base_address 165 - + (SEG_LIMIT(descriptor) + 1) * SEG_GRANULARITY(descriptor) - 1; 164 + limit = seg_get_limit(&descriptor) + 1; 165 + limit *= seg_get_granularity(&descriptor); 166 + limit += base_address - 1; 166 167 if (limit < base_address) 167 168 limit = 0xffffffff; 168 169 169 - if (SEG_EXPAND_DOWN(descriptor)) { 170 - if (SEG_G_BIT(descriptor)) 170 + if (seg_expands_down(&descriptor)) { 171 + if (descriptor.g) { 171 172 seg_top = 0xffffffff; 172 - else { 173 + } else { 173 174 seg_top = base_address + (1 << 20); 174 175 if (seg_top < base_address) 175 176 seg_top = 0xffffffff; ··· 183 182 (address > limit) || (address < base_address) ? 0 : 184 183 ((limit - address) >= 254 ? 255 : limit - address + 1); 185 184 } 186 - if (SEG_EXECUTE_ONLY(descriptor) || 187 - (!SEG_WRITE_PERM(descriptor) && (FPU_modrm & FPU_WRITE_BIT))) { 185 + if (seg_execute_only(&descriptor) || 186 + (!seg_writable(&descriptor) && (FPU_modrm & FPU_WRITE_BIT))) { 188 187 access_limit = 0; 189 188 } 190 189 return address;
+13 -36
arch/x86/mm/fault.c
··· 1258 1258 * This routine handles page faults. It determines the address, 1259 1259 * and the problem, and then passes it off to one of the appropriate 1260 1260 * routines. 1261 - * 1262 - * This function must have noinline because both callers 1263 - * {,trace_}do_page_fault() have notrace on. Having this an actual function 1264 - * guarantees there's a function trace entry. 1265 1261 */ 1266 1262 static noinline void 1267 1263 __do_page_fault(struct pt_regs *regs, unsigned long error_code, ··· 1490 1494 } 1491 1495 NOKPROBE_SYMBOL(__do_page_fault); 1492 1496 1493 - dotraplinkage void notrace 1494 - do_page_fault(struct pt_regs *regs, unsigned long error_code) 1495 - { 1496 - unsigned long address = read_cr2(); /* Get the faulting address */ 1497 - enum ctx_state prev_state; 1498 - 1499 - /* 1500 - * We must have this function tagged with __kprobes, notrace and call 1501 - * read_cr2() before calling anything else. To avoid calling any kind 1502 - * of tracing machinery before we've observed the CR2 value. 1503 - * 1504 - * exception_{enter,exit}() contain all sorts of tracepoints. 1505 - */ 1506 - 1507 - prev_state = exception_enter(); 1508 - __do_page_fault(regs, error_code, address); 1509 - exception_exit(prev_state); 1510 - } 1511 - NOKPROBE_SYMBOL(do_page_fault); 1512 - 1513 - #ifdef CONFIG_TRACING 1514 1497 static nokprobe_inline void 1515 1498 trace_page_fault_entries(unsigned long address, struct pt_regs *regs, 1516 1499 unsigned long error_code) ··· 1500 1525 trace_page_fault_kernel(address, regs, error_code); 1501 1526 } 1502 1527 1528 + /* 1529 + * We must have this function blacklisted from kprobes, tagged with notrace 1530 + * and call read_cr2() before calling anything else. To avoid calling any 1531 + * kind of tracing machinery before we've observed the CR2 value. 1532 + * 1533 + * exception_{enter,exit}() contains all sorts of tracepoints. 1534 + */ 1503 1535 dotraplinkage void notrace 1504 - trace_do_page_fault(struct pt_regs *regs, unsigned long error_code) 1536 + do_page_fault(struct pt_regs *regs, unsigned long error_code) 1505 1537 { 1506 - /* 1507 - * The exception_enter and tracepoint processing could 1508 - * trigger another page faults (user space callchain 1509 - * reading) and destroy the original cr2 value, so read 1510 - * the faulting address now. 1511 - */ 1512 - unsigned long address = read_cr2(); 1538 + unsigned long address = read_cr2(); /* Get the faulting address */ 1513 1539 enum ctx_state prev_state; 1514 1540 1515 1541 prev_state = exception_enter(); 1516 - trace_page_fault_entries(address, regs, error_code); 1542 + if (trace_pagefault_enabled()) 1543 + trace_page_fault_entries(address, regs, error_code); 1544 + 1517 1545 __do_page_fault(regs, error_code, address); 1518 1546 exception_exit(prev_state); 1519 1547 } 1520 - NOKPROBE_SYMBOL(trace_do_page_fault); 1521 - #endif /* CONFIG_TRACING */ 1548 + NOKPROBE_SYMBOL(do_page_fault);
+71 -39
arch/x86/xen/enlighten_pv.c
··· 501 501 static inline bool desc_equal(const struct desc_struct *d1, 502 502 const struct desc_struct *d2) 503 503 { 504 - return d1->a == d2->a && d1->b == d2->b; 504 + return !memcmp(d1, d2, sizeof(*d1)); 505 505 } 506 506 507 507 static void load_TLS_descriptor(struct thread_struct *t, ··· 586 586 preempt_enable(); 587 587 } 588 588 589 + #ifdef CONFIG_X86_64 590 + struct trap_array_entry { 591 + void (*orig)(void); 592 + void (*xen)(void); 593 + bool ist_okay; 594 + }; 595 + 596 + static struct trap_array_entry trap_array[] = { 597 + { debug, xen_xendebug, true }, 598 + { int3, xen_xenint3, true }, 599 + { double_fault, xen_double_fault, true }, 600 + #ifdef CONFIG_X86_MCE 601 + { machine_check, xen_machine_check, true }, 602 + #endif 603 + { nmi, xen_nmi, true }, 604 + { overflow, xen_overflow, false }, 605 + #ifdef CONFIG_IA32_EMULATION 606 + { entry_INT80_compat, xen_entry_INT80_compat, false }, 607 + #endif 608 + { page_fault, xen_page_fault, false }, 609 + { divide_error, xen_divide_error, false }, 610 + { bounds, xen_bounds, false }, 611 + { invalid_op, xen_invalid_op, false }, 612 + { device_not_available, xen_device_not_available, false }, 613 + { coprocessor_segment_overrun, xen_coprocessor_segment_overrun, false }, 614 + { invalid_TSS, xen_invalid_TSS, false }, 615 + { segment_not_present, xen_segment_not_present, false }, 616 + { stack_segment, xen_stack_segment, false }, 617 + { general_protection, xen_general_protection, false }, 618 + { spurious_interrupt_bug, xen_spurious_interrupt_bug, false }, 619 + { coprocessor_error, xen_coprocessor_error, false }, 620 + { alignment_check, xen_alignment_check, false }, 621 + { simd_coprocessor_error, xen_simd_coprocessor_error, false }, 622 + }; 623 + 624 + static bool get_trap_addr(void **addr, unsigned int ist) 625 + { 626 + unsigned int nr; 627 + bool ist_okay = false; 628 + 629 + /* 630 + * Replace trap handler addresses by Xen specific ones. 631 + * Check for known traps using IST and whitelist them. 632 + * The debugger ones are the only ones we care about. 633 + * Xen will handle faults like double_fault, * so we should never see 634 + * them. Warn if there's an unexpected IST-using fault handler. 635 + */ 636 + for (nr = 0; nr < ARRAY_SIZE(trap_array); nr++) { 637 + struct trap_array_entry *entry = trap_array + nr; 638 + 639 + if (*addr == entry->orig) { 640 + *addr = entry->xen; 641 + ist_okay = entry->ist_okay; 642 + break; 643 + } 644 + } 645 + 646 + if (WARN_ON(ist != 0 && !ist_okay)) 647 + return false; 648 + 649 + return true; 650 + } 651 + #endif 652 + 589 653 static int cvt_gate_to_trap(int vector, const gate_desc *val, 590 654 struct trap_info *info) 591 655 { 592 656 unsigned long addr; 593 657 594 - if (val->type != GATE_TRAP && val->type != GATE_INTERRUPT) 658 + if (val->bits.type != GATE_TRAP && val->bits.type != GATE_INTERRUPT) 595 659 return 0; 596 660 597 661 info->vector = vector; 598 662 599 - addr = gate_offset(*val); 663 + addr = gate_offset(val); 600 664 #ifdef CONFIG_X86_64 601 - /* 602 - * Look for known traps using IST, and substitute them 603 - * appropriately. The debugger ones are the only ones we care 604 - * about. Xen will handle faults like double_fault, 605 - * so we should never see them. Warn if 606 - * there's an unexpected IST-using fault handler. 607 - */ 608 - if (addr == (unsigned long)debug) 609 - addr = (unsigned long)xen_debug; 610 - else if (addr == (unsigned long)int3) 611 - addr = (unsigned long)xen_int3; 612 - else if (addr == (unsigned long)stack_segment) 613 - addr = (unsigned long)xen_stack_segment; 614 - else if (addr == (unsigned long)double_fault) { 615 - /* Don't need to handle these */ 665 + if (!get_trap_addr((void **)&addr, val->bits.ist)) 616 666 return 0; 617 - #ifdef CONFIG_X86_MCE 618 - } else if (addr == (unsigned long)machine_check) { 619 - /* 620 - * when xen hypervisor inject vMCE to guest, 621 - * use native mce handler to handle it 622 - */ 623 - ; 624 - #endif 625 - } else if (addr == (unsigned long)nmi) 626 - /* 627 - * Use the native version as well. 628 - */ 629 - ; 630 - else { 631 - /* Some other trap using IST? */ 632 - if (WARN_ON(val->ist != 0)) 633 - return 0; 634 - } 635 667 #endif /* CONFIG_X86_64 */ 636 668 info->address = addr; 637 669 638 - info->cs = gate_segment(*val); 639 - info->flags = val->dpl; 670 + info->cs = gate_segment(val); 671 + info->flags = val->bits.dpl; 640 672 /* interrupt gates clear IF */ 641 - if (val->type == GATE_INTERRUPT) 673 + if (val->bits.type == GATE_INTERRUPT) 642 674 info->flags |= 1 << 2; 643 675 644 676 return 1;
-3
arch/x86/xen/irq.c
··· 123 123 124 124 .safe_halt = xen_safe_halt, 125 125 .halt = xen_halt, 126 - #ifdef CONFIG_X86_64 127 - .adjust_exception_frame = xen_adjust_exception_frame, 128 - #endif 129 126 }; 130 127 131 128 void __init xen_init_irq_ops(void)
+36 -5
arch/x86/xen/xen-asm_64.S
··· 16 16 17 17 #include <linux/linkage.h> 18 18 19 - ENTRY(xen_adjust_exception_frame) 20 - mov 8+0(%rsp), %rcx 21 - mov 8+8(%rsp), %r11 22 - ret $16 23 - ENDPROC(xen_adjust_exception_frame) 19 + .macro xen_pv_trap name 20 + ENTRY(xen_\name) 21 + pop %rcx 22 + pop %r11 23 + jmp \name 24 + END(xen_\name) 25 + .endm 26 + 27 + xen_pv_trap divide_error 28 + xen_pv_trap debug 29 + xen_pv_trap xendebug 30 + xen_pv_trap int3 31 + xen_pv_trap xenint3 32 + xen_pv_trap nmi 33 + xen_pv_trap overflow 34 + xen_pv_trap bounds 35 + xen_pv_trap invalid_op 36 + xen_pv_trap device_not_available 37 + xen_pv_trap double_fault 38 + xen_pv_trap coprocessor_segment_overrun 39 + xen_pv_trap invalid_TSS 40 + xen_pv_trap segment_not_present 41 + xen_pv_trap stack_segment 42 + xen_pv_trap general_protection 43 + xen_pv_trap page_fault 44 + xen_pv_trap spurious_interrupt_bug 45 + xen_pv_trap coprocessor_error 46 + xen_pv_trap alignment_check 47 + #ifdef CONFIG_X86_MCE 48 + xen_pv_trap machine_check 49 + #endif /* CONFIG_X86_MCE */ 50 + xen_pv_trap simd_coprocessor_error 51 + #ifdef CONFIG_IA32_EMULATION 52 + xen_pv_trap entry_INT80_compat 53 + #endif 54 + xen_pv_trap hypervisor_callback 24 55 25 56 hypercall_iret = hypercall_page + __HYPERVISOR_iret * 32 26 57 /*
-1
arch/x86/xen/xen-ops.h
··· 138 138 __visible void xen_iret(void); 139 139 __visible void xen_sysret32(void); 140 140 __visible void xen_sysret64(void); 141 - __visible void xen_adjust_exception_frame(void); 142 141 143 142 extern int xen_panic_handler_init(void); 144 143
+2 -4
drivers/xen/events/events_base.c
··· 1653 1653 return; 1654 1654 } 1655 1655 pr_info("Xen HVM callback vector for event delivery is enabled\n"); 1656 - /* in the restore case the vector has already been allocated */ 1657 - if (!test_bit(HYPERVISOR_CALLBACK_VECTOR, used_vectors)) 1658 - alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, 1659 - xen_hvm_callback_vector); 1656 + alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, 1657 + xen_hvm_callback_vector); 1660 1658 } 1661 1659 } 1662 1660 #else