diff options
| -rw-r--r-- | arch/x86/include/asm/apic.h | 27 | ||||
| -rw-r--r-- | arch/x86/include/asm/desc.h | 117 | ||||
| -rw-r--r-- | arch/x86/include/asm/entry_arch.h | 8 | ||||
| -rw-r--r-- | arch/x86/include/asm/hw_irq.h | 17 | ||||
| -rw-r--r-- | arch/x86/include/asm/mshyperv.h | 3 | ||||
| -rw-r--r-- | arch/x86/include/asm/trace/irq_vectors.h | 104 | ||||
| -rw-r--r-- | arch/x86/include/asm/uv/uv_bau.h | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/Makefile | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/apic.c | 69 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/common.c | 20 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/mcheck/therm_throt.c | 24 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/mcheck/threshold.c | 24 | ||||
| -rw-r--r-- | arch/x86/kernel/entry_32.S | 12 | ||||
| -rw-r--r-- | arch/x86/kernel/entry_64.S | 36 | ||||
| -rw-r--r-- | arch/x86/kernel/head_64.S | 8 | ||||
| -rw-r--r-- | arch/x86/kernel/irq.c | 33 | ||||
| -rw-r--r-- | arch/x86/kernel/irq_work.c | 24 | ||||
| -rw-r--r-- | arch/x86/kernel/smp.c | 65 | ||||
| -rw-r--r-- | arch/x86/kernel/tracepoint.c | 61 | ||||
| -rw-r--r-- | arch/x86/kernel/traps.c | 2 | ||||
| -rw-r--r-- | include/linux/tracepoint.h | 2 | ||||
| -rw-r--r-- | include/trace/define_trace.h | 5 | ||||
| -rw-r--r-- | include/trace/ftrace.h | 4 | ||||
| -rw-r--r-- | include/xen/events.h | 3 |
24 files changed, 602 insertions, 72 deletions
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index 338803422239..f8119b582c3c 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <asm/fixmap.h> | 12 | #include <asm/fixmap.h> |
| 13 | #include <asm/mpspec.h> | 13 | #include <asm/mpspec.h> |
| 14 | #include <asm/msr.h> | 14 | #include <asm/msr.h> |
| 15 | #include <asm/idle.h> | ||
| 15 | 16 | ||
| 16 | #define ARCH_APICTIMER_STOPS_ON_C3 1 | 17 | #define ARCH_APICTIMER_STOPS_ON_C3 1 |
| 17 | 18 | ||
| @@ -687,5 +688,31 @@ extern int default_check_phys_apicid_present(int phys_apicid); | |||
| 687 | #endif | 688 | #endif |
| 688 | 689 | ||
| 689 | #endif /* CONFIG_X86_LOCAL_APIC */ | 690 | #endif /* CONFIG_X86_LOCAL_APIC */ |
| 691 | extern void irq_enter(void); | ||
| 692 | extern void irq_exit(void); | ||
| 693 | |||
| 694 | static inline void entering_irq(void) | ||
| 695 | { | ||
| 696 | irq_enter(); | ||
| 697 | exit_idle(); | ||
| 698 | } | ||
| 699 | |||
| 700 | static inline void entering_ack_irq(void) | ||
| 701 | { | ||
| 702 | ack_APIC_irq(); | ||
| 703 | entering_irq(); | ||
| 704 | } | ||
| 705 | |||
| 706 | static inline void exiting_irq(void) | ||
| 707 | { | ||
| 708 | irq_exit(); | ||
| 709 | } | ||
| 710 | |||
| 711 | static inline void exiting_ack_irq(void) | ||
| 712 | { | ||
| 713 | irq_exit(); | ||
| 714 | /* Ack only at the end to avoid potential reentry */ | ||
| 715 | ack_APIC_irq(); | ||
| 716 | } | ||
| 690 | 717 | ||
| 691 | #endif /* _ASM_X86_APIC_H */ | 718 | #endif /* _ASM_X86_APIC_H */ |
diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h index 8bf1c06070d5..b90e5dfeee46 100644 --- a/arch/x86/include/asm/desc.h +++ b/arch/x86/include/asm/desc.h | |||
| @@ -36,8 +36,8 @@ static inline void fill_ldt(struct desc_struct *desc, const struct user_desc *in | |||
| 36 | 36 | ||
| 37 | extern struct desc_ptr idt_descr; | 37 | extern struct desc_ptr idt_descr; |
| 38 | extern gate_desc idt_table[]; | 38 | extern gate_desc idt_table[]; |
| 39 | extern struct desc_ptr nmi_idt_descr; | 39 | extern struct desc_ptr debug_idt_descr; |
| 40 | extern gate_desc nmi_idt_table[]; | 40 | extern gate_desc debug_idt_table[]; |
| 41 | 41 | ||
| 42 | struct gdt_page { | 42 | struct gdt_page { |
| 43 | struct desc_struct gdt[GDT_ENTRIES]; | 43 | struct desc_struct gdt[GDT_ENTRIES]; |
| @@ -316,7 +316,20 @@ static inline void set_nmi_gate(int gate, void *addr) | |||
| 316 | gate_desc s; | 316 | gate_desc s; |
| 317 | 317 | ||
| 318 | pack_gate(&s, GATE_INTERRUPT, (unsigned long)addr, 0, 0, __KERNEL_CS); | 318 | pack_gate(&s, GATE_INTERRUPT, (unsigned long)addr, 0, 0, __KERNEL_CS); |
| 319 | write_idt_entry(nmi_idt_table, gate, &s); | 319 | write_idt_entry(debug_idt_table, gate, &s); |
| 320 | } | ||
| 321 | #endif | ||
| 322 | |||
| 323 | #ifdef CONFIG_TRACING | ||
| 324 | extern struct desc_ptr trace_idt_descr; | ||
| 325 | extern gate_desc trace_idt_table[]; | ||
| 326 | static inline void write_trace_idt_entry(int entry, const gate_desc *gate) | ||
| 327 | { | ||
| 328 | write_idt_entry(trace_idt_table, entry, gate); | ||
| 329 | } | ||
| 330 | #else | ||
| 331 | static inline void write_trace_idt_entry(int entry, const gate_desc *gate) | ||
| 332 | { | ||
| 320 | } | 333 | } |
| 321 | #endif | 334 | #endif |
| 322 | 335 | ||
| @@ -331,6 +344,7 @@ static inline void _set_gate(int gate, unsigned type, void *addr, | |||
| 331 | * setup time | 344 | * setup time |
| 332 | */ | 345 | */ |
| 333 | write_idt_entry(idt_table, gate, &s); | 346 | write_idt_entry(idt_table, gate, &s); |
| 347 | write_trace_idt_entry(gate, &s); | ||
| 334 | } | 348 | } |
| 335 | 349 | ||
| 336 | /* | 350 | /* |
| @@ -360,12 +374,39 @@ static inline void alloc_system_vector(int vector) | |||
| 360 | } | 374 | } |
| 361 | } | 375 | } |
| 362 | 376 | ||
| 363 | static inline void alloc_intr_gate(unsigned int n, void *addr) | 377 | #ifdef CONFIG_TRACING |
| 378 | static inline void trace_set_intr_gate(unsigned int gate, void *addr) | ||
| 379 | { | ||
| 380 | gate_desc s; | ||
| 381 | |||
| 382 | pack_gate(&s, GATE_INTERRUPT, (unsigned long)addr, 0, 0, __KERNEL_CS); | ||
| 383 | write_idt_entry(trace_idt_table, gate, &s); | ||
| 384 | } | ||
| 385 | |||
| 386 | static inline void __trace_alloc_intr_gate(unsigned int n, void *addr) | ||
| 387 | { | ||
| 388 | trace_set_intr_gate(n, addr); | ||
| 389 | } | ||
| 390 | #else | ||
| 391 | static inline void trace_set_intr_gate(unsigned int gate, void *addr) | ||
| 392 | { | ||
| 393 | } | ||
| 394 | |||
| 395 | #define __trace_alloc_intr_gate(n, addr) | ||
| 396 | #endif | ||
| 397 | |||
| 398 | static inline void __alloc_intr_gate(unsigned int n, void *addr) | ||
| 364 | { | 399 | { |
| 365 | alloc_system_vector(n); | ||
| 366 | set_intr_gate(n, addr); | 400 | set_intr_gate(n, addr); |
| 367 | } | 401 | } |
| 368 | 402 | ||
| 403 | #define alloc_intr_gate(n, addr) \ | ||
| 404 | do { \ | ||
| 405 | alloc_system_vector(n); \ | ||
| 406 | __alloc_intr_gate(n, addr); \ | ||
| 407 | __trace_alloc_intr_gate(n, trace_##addr); \ | ||
| 408 | } while (0) | ||
| 409 | |||
| 369 | /* | 410 | /* |
| 370 | * This routine sets up an interrupt gate at directory privilege level 3. | 411 | * This routine sets up an interrupt gate at directory privilege level 3. |
| 371 | */ | 412 | */ |
| @@ -405,4 +446,70 @@ static inline void set_system_intr_gate_ist(int n, void *addr, unsigned ist) | |||
| 405 | _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS); | 446 | _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS); |
| 406 | } | 447 | } |
| 407 | 448 | ||
| 449 | #ifdef CONFIG_X86_64 | ||
| 450 | DECLARE_PER_CPU(u32, debug_idt_ctr); | ||
| 451 | static inline bool is_debug_idt_enabled(void) | ||
| 452 | { | ||
| 453 | if (this_cpu_read(debug_idt_ctr)) | ||
| 454 | return true; | ||
| 455 | |||
| 456 | return false; | ||
| 457 | } | ||
| 458 | |||
| 459 | static inline void load_debug_idt(void) | ||
| 460 | { | ||
| 461 | load_idt((const struct desc_ptr *)&debug_idt_descr); | ||
| 462 | } | ||
| 463 | #else | ||
| 464 | static inline bool is_debug_idt_enabled(void) | ||
| 465 | { | ||
| 466 | return false; | ||
| 467 | } | ||
| 468 | |||
| 469 | static inline void load_debug_idt(void) | ||
| 470 | { | ||
| 471 | } | ||
| 472 | #endif | ||
| 473 | |||
| 474 | #ifdef CONFIG_TRACING | ||
| 475 | extern atomic_t trace_idt_ctr; | ||
| 476 | static inline bool is_trace_idt_enabled(void) | ||
| 477 | { | ||
| 478 | if (atomic_read(&trace_idt_ctr)) | ||
| 479 | return true; | ||
| 480 | |||
| 481 | return false; | ||
| 482 | } | ||
| 483 | |||
| 484 | static inline void load_trace_idt(void) | ||
| 485 | { | ||
| 486 | load_idt((const struct desc_ptr *)&trace_idt_descr); | ||
| 487 | } | ||
| 488 | #else | ||
| 489 | static inline bool is_trace_idt_enabled(void) | ||
| 490 | { | ||
| 491 | return false; | ||
| 492 | } | ||
| 493 | |||
| 494 | static inline void load_trace_idt(void) | ||
| 495 | { | ||
| 496 | } | ||
| 497 | #endif | ||
| 498 | |||
| 499 | /* | ||
| 500 | * The load_current_idt() must be called with interrupts disabled | ||
| 501 | * to avoid races. That way the IDT will always be set back to the expected | ||
| 502 | * descriptor. It's also called when a CPU is being initialized, and | ||
| 503 | * that doesn't need to disable interrupts, as nothing should be | ||
| 504 | * bothering the CPU then. | ||
| 505 | */ | ||
| 506 | static inline void load_current_idt(void) | ||
| 507 | { | ||
| 508 | if (is_debug_idt_enabled()) | ||
| 509 | load_debug_idt(); | ||
| 510 | else if (is_trace_idt_enabled()) | ||
| 511 | load_trace_idt(); | ||
| 512 | else | ||
| 513 | load_idt((const struct desc_ptr *)&idt_descr); | ||
| 514 | } | ||
| 408 | #endif /* _ASM_X86_DESC_H */ | 515 | #endif /* _ASM_X86_DESC_H */ |
diff --git a/arch/x86/include/asm/entry_arch.h b/arch/x86/include/asm/entry_arch.h index 9bd4ecac72be..dc5fa661465f 100644 --- a/arch/x86/include/asm/entry_arch.h +++ b/arch/x86/include/asm/entry_arch.h | |||
| @@ -13,14 +13,16 @@ | |||
| 13 | BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR) | 13 | BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR) |
| 14 | BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) | 14 | BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) |
| 15 | BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR) | 15 | BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR) |
| 16 | BUILD_INTERRUPT(irq_move_cleanup_interrupt,IRQ_MOVE_CLEANUP_VECTOR) | 16 | BUILD_INTERRUPT3(irq_move_cleanup_interrupt, IRQ_MOVE_CLEANUP_VECTOR, |
| 17 | BUILD_INTERRUPT(reboot_interrupt,REBOOT_VECTOR) | 17 | smp_irq_move_cleanup_interrupt) |
| 18 | BUILD_INTERRUPT3(reboot_interrupt, REBOOT_VECTOR, smp_reboot_interrupt) | ||
| 18 | #endif | 19 | #endif |
| 19 | 20 | ||
| 20 | BUILD_INTERRUPT(x86_platform_ipi, X86_PLATFORM_IPI_VECTOR) | 21 | BUILD_INTERRUPT(x86_platform_ipi, X86_PLATFORM_IPI_VECTOR) |
| 21 | 22 | ||
| 22 | #ifdef CONFIG_HAVE_KVM | 23 | #ifdef CONFIG_HAVE_KVM |
| 23 | BUILD_INTERRUPT(kvm_posted_intr_ipi, POSTED_INTR_VECTOR) | 24 | BUILD_INTERRUPT3(kvm_posted_intr_ipi, POSTED_INTR_VECTOR, |
| 25 | smp_kvm_posted_intr_ipi) | ||
| 24 | #endif | 26 | #endif |
| 25 | 27 | ||
| 26 | /* | 28 | /* |
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h index 1da97efad08a..e4ac559c4a24 100644 --- a/arch/x86/include/asm/hw_irq.h +++ b/arch/x86/include/asm/hw_irq.h | |||
| @@ -77,6 +77,23 @@ extern void threshold_interrupt(void); | |||
| 77 | extern void call_function_interrupt(void); | 77 | extern void call_function_interrupt(void); |
| 78 | extern void call_function_single_interrupt(void); | 78 | extern void call_function_single_interrupt(void); |
| 79 | 79 | ||
| 80 | #ifdef CONFIG_TRACING | ||
| 81 | /* Interrupt handlers registered during init_IRQ */ | ||
| 82 | extern void trace_apic_timer_interrupt(void); | ||
| 83 | extern void trace_x86_platform_ipi(void); | ||
| 84 | extern void trace_error_interrupt(void); | ||
| 85 | extern void trace_irq_work_interrupt(void); | ||
| 86 | extern void trace_spurious_interrupt(void); | ||
| 87 | extern void trace_thermal_interrupt(void); | ||
| 88 | extern void trace_reschedule_interrupt(void); | ||
| 89 | extern void trace_threshold_interrupt(void); | ||
| 90 | extern void trace_call_function_interrupt(void); | ||
| 91 | extern void trace_call_function_single_interrupt(void); | ||
| 92 | #define trace_irq_move_cleanup_interrupt irq_move_cleanup_interrupt | ||
| 93 | #define trace_reboot_interrupt reboot_interrupt | ||
| 94 | #define trace_kvm_posted_intr_ipi kvm_posted_intr_ipi | ||
| 95 | #endif /* CONFIG_TRACING */ | ||
| 96 | |||
| 80 | /* IOAPIC */ | 97 | /* IOAPIC */ |
| 81 | #define IO_APIC_IRQ(x) (((x) >= NR_IRQS_LEGACY) || ((1<<(x)) & io_apic_irqs)) | 98 | #define IO_APIC_IRQ(x) (((x) >= NR_IRQS_LEGACY) || ((1<<(x)) & io_apic_irqs)) |
| 82 | extern unsigned long io_apic_irqs; | 99 | extern unsigned long io_apic_irqs; |
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index c2934be2446a..cd9c41938b8a 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h | |||
| @@ -12,6 +12,9 @@ struct ms_hyperv_info { | |||
| 12 | extern struct ms_hyperv_info ms_hyperv; | 12 | extern struct ms_hyperv_info ms_hyperv; |
| 13 | 13 | ||
| 14 | void hyperv_callback_vector(void); | 14 | void hyperv_callback_vector(void); |
| 15 | #ifdef CONFIG_TRACING | ||
| 16 | #define trace_hyperv_callback_vector hyperv_callback_vector | ||
| 17 | #endif | ||
| 15 | void hyperv_vector_handler(struct pt_regs *regs); | 18 | void hyperv_vector_handler(struct pt_regs *regs); |
| 16 | void hv_register_vmbus_handler(int irq, irq_handler_t handler); | 19 | void hv_register_vmbus_handler(int irq, irq_handler_t handler); |
| 17 | 20 | ||
diff --git a/arch/x86/include/asm/trace/irq_vectors.h b/arch/x86/include/asm/trace/irq_vectors.h new file mode 100644 index 000000000000..2874df24e7a4 --- /dev/null +++ b/arch/x86/include/asm/trace/irq_vectors.h | |||
| @@ -0,0 +1,104 @@ | |||
| 1 | #undef TRACE_SYSTEM | ||
| 2 | #define TRACE_SYSTEM irq_vectors | ||
| 3 | |||
| 4 | #if !defined(_TRACE_IRQ_VECTORS_H) || defined(TRACE_HEADER_MULTI_READ) | ||
| 5 | #define _TRACE_IRQ_VECTORS_H | ||
| 6 | |||
| 7 | #include <linux/tracepoint.h> | ||
| 8 | |||
| 9 | extern void trace_irq_vector_regfunc(void); | ||
| 10 | extern void trace_irq_vector_unregfunc(void); | ||
| 11 | |||
| 12 | DECLARE_EVENT_CLASS(x86_irq_vector, | ||
| 13 | |||
| 14 | TP_PROTO(int vector), | ||
| 15 | |||
| 16 | TP_ARGS(vector), | ||
| 17 | |||
| 18 | TP_STRUCT__entry( | ||
| 19 | __field( int, vector ) | ||
| 20 | ), | ||
| 21 | |||
| 22 | TP_fast_assign( | ||
| 23 | __entry->vector = vector; | ||
| 24 | ), | ||
| 25 | |||
| 26 | TP_printk("vector=%d", __entry->vector) ); | ||
| 27 | |||
| 28 | #define DEFINE_IRQ_VECTOR_EVENT(name) \ | ||
| 29 | DEFINE_EVENT_FN(x86_irq_vector, name##_entry, \ | ||
| 30 | TP_PROTO(int vector), \ | ||
| 31 | TP_ARGS(vector), \ | ||
| 32 | trace_irq_vector_regfunc, \ | ||
| 33 | trace_irq_vector_unregfunc); \ | ||
| 34 | DEFINE_EVENT_FN(x86_irq_vector, name##_exit, \ | ||
| 35 | TP_PROTO(int vector), \ | ||
| 36 | TP_ARGS(vector), \ | ||
| 37 | trace_irq_vector_regfunc, \ | ||
| 38 | trace_irq_vector_unregfunc); | ||
| 39 | |||
| 40 | |||
| 41 | /* | ||
| 42 | * local_timer - called when entering/exiting a local timer interrupt | ||
| 43 | * vector handler | ||
| 44 | */ | ||
| 45 | DEFINE_IRQ_VECTOR_EVENT(local_timer); | ||
| 46 | |||
| 47 | /* | ||
| 48 | * reschedule - called when entering/exiting a reschedule vector handler | ||
| 49 | */ | ||
| 50 | DEFINE_IRQ_VECTOR_EVENT(reschedule); | ||
| 51 | |||
| 52 | /* | ||
| 53 | * spurious_apic - called when entering/exiting a spurious apic vector handler | ||
| 54 | */ | ||
| 55 | DEFINE_IRQ_VECTOR_EVENT(spurious_apic); | ||
| 56 | |||
| 57 | /* | ||
| 58 | * error_apic - called when entering/exiting an error apic vector handler | ||
| 59 | */ | ||
| 60 | DEFINE_IRQ_VECTOR_EVENT(error_apic); | ||
| 61 | |||
| 62 | /* | ||
| 63 | * x86_platform_ipi - called when entering/exiting a x86 platform ipi interrupt | ||
| 64 | * vector handler | ||
| 65 | */ | ||
| 66 | DEFINE_IRQ_VECTOR_EVENT(x86_platform_ipi); | ||
| 67 | |||
| 68 | /* | ||
| 69 | * irq_work - called when entering/exiting a irq work interrupt | ||
| 70 | * vector handler | ||
| 71 | */ | ||
| 72 | DEFINE_IRQ_VECTOR_EVENT(irq_work); | ||
| 73 | |||
| 74 | /* | ||
| 75 | * call_function - called when entering/exiting a call function interrupt | ||
| 76 | * vector handler | ||
| 77 | */ | ||
| 78 | DEFINE_IRQ_VECTOR_EVENT(call_function); | ||
| 79 | |||
| 80 | /* | ||
| 81 | * call_function_single - called when entering/exiting a call function | ||
| 82 | * single interrupt vector handler | ||
| 83 | */ | ||
| 84 | DEFINE_IRQ_VECTOR_EVENT(call_function_single); | ||
| 85 | |||
| 86 | /* | ||
| 87 | * threshold_apic - called when entering/exiting a threshold apic interrupt | ||
| 88 | * vector handler | ||
| 89 | */ | ||
| 90 | DEFINE_IRQ_VECTOR_EVENT(threshold_apic); | ||
| 91 | |||
| 92 | /* | ||
| 93 | * thermal_apic - called when entering/exiting a thermal apic interrupt | ||
| 94 | * vector handler | ||
| 95 | */ | ||
| 96 | DEFINE_IRQ_VECTOR_EVENT(thermal_apic); | ||
| 97 | |||
| 98 | #undef TRACE_INCLUDE_PATH | ||
| 99 | #define TRACE_INCLUDE_PATH . | ||
| 100 | #define TRACE_INCLUDE_FILE irq_vectors | ||
| 101 | #endif /* _TRACE_IRQ_VECTORS_H */ | ||
| 102 | |||
| 103 | /* This part must be outside protection */ | ||
| 104 | #include <trace/define_trace.h> | ||
diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h index a06983cdc125..0b46ef261c77 100644 --- a/arch/x86/include/asm/uv/uv_bau.h +++ b/arch/x86/include/asm/uv/uv_bau.h | |||
| @@ -731,6 +731,9 @@ static inline void bau_cpubits_clear(struct bau_local_cpumask *dstp, int nbits) | |||
| 731 | } | 731 | } |
| 732 | 732 | ||
| 733 | extern void uv_bau_message_intr1(void); | 733 | extern void uv_bau_message_intr1(void); |
| 734 | #ifdef CONFIG_TRACING | ||
| 735 | #define trace_uv_bau_message_intr1 uv_bau_message_intr1 | ||
| 736 | #endif | ||
| 734 | extern void uv_bau_timeout_intr1(void); | 737 | extern void uv_bau_timeout_intr1(void); |
| 735 | 738 | ||
| 736 | struct atomic_short { | 739 | struct atomic_short { |
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 612ed3435c0d..88d99ea77723 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
| @@ -16,6 +16,8 @@ CFLAGS_REMOVE_ftrace.o = -pg | |||
| 16 | CFLAGS_REMOVE_early_printk.o = -pg | 16 | CFLAGS_REMOVE_early_printk.o = -pg |
| 17 | endif | 17 | endif |
| 18 | 18 | ||
| 19 | CFLAGS_irq.o := -I$(src)/../include/asm/trace | ||
| 20 | |||
| 19 | obj-y := process_$(BITS).o signal.o entry_$(BITS).o | 21 | obj-y := process_$(BITS).o signal.o entry_$(BITS).o |
| 20 | obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o | 22 | obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o |
| 21 | obj-y += time.o ioport.o ldt.o dumpstack.o nmi.o | 23 | obj-y += time.o ioport.o ldt.o dumpstack.o nmi.o |
| @@ -103,6 +105,7 @@ obj-$(CONFIG_OF) += devicetree.o | |||
| 103 | obj-$(CONFIG_UPROBES) += uprobes.o | 105 | obj-$(CONFIG_UPROBES) += uprobes.o |
| 104 | 106 | ||
| 105 | obj-$(CONFIG_PERF_EVENTS) += perf_regs.o | 107 | obj-$(CONFIG_PERF_EVENTS) += perf_regs.o |
| 108 | obj-$(CONFIG_TRACING) += tracepoint.o | ||
| 106 | 109 | ||
| 107 | ### | 110 | ### |
| 108 | # 64 bit specific files | 111 | # 64 bit specific files |
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 1600b1ca4f04..99663b59123a 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #include <linux/smp.h> | 35 | #include <linux/smp.h> |
| 36 | #include <linux/mm.h> | 36 | #include <linux/mm.h> |
| 37 | 37 | ||
| 38 | #include <asm/trace/irq_vectors.h> | ||
| 38 | #include <asm/irq_remapping.h> | 39 | #include <asm/irq_remapping.h> |
| 39 | #include <asm/perf_event.h> | 40 | #include <asm/perf_event.h> |
| 40 | #include <asm/x86_init.h> | 41 | #include <asm/x86_init.h> |
| @@ -919,17 +920,35 @@ void __irq_entry smp_apic_timer_interrupt(struct pt_regs *regs) | |||
| 919 | /* | 920 | /* |
| 920 | * NOTE! We'd better ACK the irq immediately, | 921 | * NOTE! We'd better ACK the irq immediately, |
| 921 | * because timer handling can be slow. | 922 | * because timer handling can be slow. |
| 923 | * | ||
| 924 | * update_process_times() expects us to have done irq_enter(). | ||
| 925 | * Besides, if we don't timer interrupts ignore the global | ||
| 926 | * interrupt lock, which is the WrongThing (tm) to do. | ||
| 922 | */ | 927 | */ |
| 923 | ack_APIC_irq(); | 928 | entering_ack_irq(); |
| 929 | local_apic_timer_interrupt(); | ||
| 930 | exiting_irq(); | ||
| 931 | |||
| 932 | set_irq_regs(old_regs); | ||
| 933 | } | ||
| 934 | |||
| 935 | void __irq_entry smp_trace_apic_timer_interrupt(struct pt_regs *regs) | ||
| 936 | { | ||
| 937 | struct pt_regs *old_regs = set_irq_regs(regs); | ||
| 938 | |||
| 924 | /* | 939 | /* |
| 940 | * NOTE! We'd better ACK the irq immediately, | ||
| 941 | * because timer handling can be slow. | ||
| 942 | * | ||
| 925 | * update_process_times() expects us to have done irq_enter(). | 943 | * update_process_times() expects us to have done irq_enter(). |
| 926 | * Besides, if we don't timer interrupts ignore the global | 944 | * Besides, if we don't timer interrupts ignore the global |
| 927 | * interrupt lock, which is the WrongThing (tm) to do. | 945 | * interrupt lock, which is the WrongThing (tm) to do. |
| 928 | */ | 946 | */ |
| 929 | irq_enter(); | 947 | entering_ack_irq(); |
| 930 | exit_idle(); | 948 | trace_local_timer_entry(LOCAL_TIMER_VECTOR); |
| 931 | local_apic_timer_interrupt(); | 949 | local_apic_timer_interrupt(); |
| 932 | irq_exit(); | 950 | trace_local_timer_exit(LOCAL_TIMER_VECTOR); |
| 951 | exiting_irq(); | ||
| 933 | 952 | ||
| 934 | set_irq_regs(old_regs); | 953 | set_irq_regs(old_regs); |
| 935 | } | 954 | } |
| @@ -1907,12 +1926,10 @@ int __init APIC_init_uniprocessor(void) | |||
| 1907 | /* | 1926 | /* |
| 1908 | * This interrupt should _never_ happen with our APIC/SMP architecture | 1927 | * This interrupt should _never_ happen with our APIC/SMP architecture |
| 1909 | */ | 1928 | */ |
| 1910 | void smp_spurious_interrupt(struct pt_regs *regs) | 1929 | static inline void __smp_spurious_interrupt(void) |
| 1911 | { | 1930 | { |
| 1912 | u32 v; | 1931 | u32 v; |
| 1913 | 1932 | ||
| 1914 | irq_enter(); | ||
| 1915 | exit_idle(); | ||
| 1916 | /* | 1933 | /* |
| 1917 | * Check if this really is a spurious interrupt and ACK it | 1934 | * Check if this really is a spurious interrupt and ACK it |
| 1918 | * if it is a vectored one. Just in case... | 1935 | * if it is a vectored one. Just in case... |
| @@ -1927,13 +1944,28 @@ void smp_spurious_interrupt(struct pt_regs *regs) | |||
| 1927 | /* see sw-dev-man vol 3, chapter 7.4.13.5 */ | 1944 | /* see sw-dev-man vol 3, chapter 7.4.13.5 */ |
| 1928 | pr_info("spurious APIC interrupt on CPU#%d, " | 1945 | pr_info("spurious APIC interrupt on CPU#%d, " |
| 1929 | "should never happen.\n", smp_processor_id()); | 1946 | "should never happen.\n", smp_processor_id()); |
| 1930 | irq_exit(); | 1947 | } |
| 1948 | |||
| 1949 | void smp_spurious_interrupt(struct pt_regs *regs) | ||
| 1950 | { | ||
| 1951 | entering_irq(); | ||
| 1952 | __smp_spurious_interrupt(); | ||
| 1953 | exiting_irq(); | ||
| 1954 | } | ||
| 1955 | |||
| 1956 | void smp_trace_spurious_interrupt(struct pt_regs *regs) | ||
| 1957 | { | ||
| 1958 | entering_irq(); | ||
| 1959 | trace_spurious_apic_entry(SPURIOUS_APIC_VECTOR); | ||
| 1960 | __smp_spurious_interrupt(); | ||
| 1961 | trace_spurious_apic_exit(SPURIOUS_APIC_VECTOR); | ||
| 1962 | exiting_irq(); | ||
| 1931 | } | 1963 | } |
| 1932 | 1964 | ||
| 1933 | /* | 1965 | /* |
| 1934 | * This interrupt should never happen with our APIC/SMP architecture | 1966 | * This interrupt should never happen with our APIC/SMP architecture |
| 1935 | */ | 1967 | */ |
| 1936 | void smp_error_interrupt(struct pt_regs *regs) | 1968 | static inline void __smp_error_interrupt(struct pt_regs *regs) |
| 1937 | { | 1969 | { |
| 1938 | u32 v0, v1; | 1970 | u32 v0, v1; |
| 1939 | u32 i = 0; | 1971 | u32 i = 0; |
| @@ -1948,8 +1980,6 @@ void smp_error_interrupt(struct pt_regs *regs) | |||
| 1948 | "Illegal register address", /* APIC Error Bit 7 */ | 1980 | "Illegal register address", /* APIC Error Bit 7 */ |
| 1949 | }; | 1981 | }; |
| 1950 | 1982 | ||
| 1951 | irq_enter(); | ||
| 1952 | exit_idle(); | ||
| 1953 | /* First tickle the hardware, only then report what went on. -- REW */ | 1983 | /* First tickle the hardware, only then report what went on. -- REW */ |
| 1954 | v0 = apic_read(APIC_ESR); | 1984 | v0 = apic_read(APIC_ESR); |
| 1955 | apic_write(APIC_ESR, 0); | 1985 | apic_write(APIC_ESR, 0); |
| @@ -1970,7 +2000,22 @@ void smp_error_interrupt(struct pt_regs *regs) | |||
| 1970 | 2000 | ||
| 1971 | apic_printk(APIC_DEBUG, KERN_CONT "\n"); | 2001 | apic_printk(APIC_DEBUG, KERN_CONT "\n"); |
| 1972 | 2002 | ||
| 1973 | irq_exit(); | 2003 | } |
| 2004 | |||
| 2005 | void smp_error_interrupt(struct pt_regs *regs) | ||
| 2006 | { | ||
| 2007 | entering_irq(); | ||
| 2008 | __smp_error_interrupt(regs); | ||
| 2009 | exiting_irq(); | ||
| 2010 | } | ||
| 2011 | |||
| 2012 | void smp_trace_error_interrupt(struct pt_regs *regs) | ||
| 2013 | { | ||
| 2014 | entering_irq(); | ||
| 2015 | trace_error_apic_entry(ERROR_APIC_VECTOR); | ||
| 2016 | __smp_error_interrupt(regs); | ||
| 2017 | trace_error_apic_exit(ERROR_APIC_VECTOR); | ||
| 2018 | exiting_irq(); | ||
| 1974 | } | 2019 | } |
| 1975 | 2020 | ||
| 1976 | /** | 2021 | /** |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index a4a07c0acb1f..548bd039784e 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
| @@ -1072,8 +1072,8 @@ __setup("clearcpuid=", setup_disablecpuid); | |||
| 1072 | 1072 | ||
| 1073 | #ifdef CONFIG_X86_64 | 1073 | #ifdef CONFIG_X86_64 |
| 1074 | struct desc_ptr idt_descr = { NR_VECTORS * 16 - 1, (unsigned long) idt_table }; | 1074 | struct desc_ptr idt_descr = { NR_VECTORS * 16 - 1, (unsigned long) idt_table }; |
| 1075 | struct desc_ptr nmi_idt_descr = { NR_VECTORS * 16 - 1, | 1075 | struct desc_ptr debug_idt_descr = { NR_VECTORS * 16 - 1, |
| 1076 | (unsigned long) nmi_idt_table }; | 1076 | (unsigned long) debug_idt_table }; |
| 1077 | 1077 | ||
| 1078 | DEFINE_PER_CPU_FIRST(union irq_stack_union, | 1078 | DEFINE_PER_CPU_FIRST(union irq_stack_union, |
| 1079 | irq_stack_union) __aligned(PAGE_SIZE); | 1079 | irq_stack_union) __aligned(PAGE_SIZE); |
| @@ -1149,20 +1149,20 @@ int is_debug_stack(unsigned long addr) | |||
| 1149 | addr > (__get_cpu_var(debug_stack_addr) - DEBUG_STKSZ)); | 1149 | addr > (__get_cpu_var(debug_stack_addr) - DEBUG_STKSZ)); |
| 1150 | } | 1150 | } |
| 1151 | 1151 | ||
| 1152 | static DEFINE_PER_CPU(u32, debug_stack_use_ctr); | 1152 | DEFINE_PER_CPU(u32, debug_idt_ctr); |
| 1153 | 1153 | ||
| 1154 | void debug_stack_set_zero(void) | 1154 | void debug_stack_set_zero(void) |
| 1155 | { | 1155 | { |
| 1156 | this_cpu_inc(debug_stack_use_ctr); | 1156 | this_cpu_inc(debug_idt_ctr); |
| 1157 | load_idt((const struct desc_ptr *)&nmi_idt_descr); | 1157 | load_current_idt(); |
| 1158 | } | 1158 | } |
| 1159 | 1159 | ||
| 1160 | void debug_stack_reset(void) | 1160 | void debug_stack_reset(void) |
| 1161 | { | 1161 | { |
| 1162 | if (WARN_ON(!this_cpu_read(debug_stack_use_ctr))) | 1162 | if (WARN_ON(!this_cpu_read(debug_idt_ctr))) |
| 1163 | return; | 1163 | return; |
| 1164 | if (this_cpu_dec_return(debug_stack_use_ctr) == 0) | 1164 | if (this_cpu_dec_return(debug_idt_ctr) == 0) |
| 1165 | load_idt((const struct desc_ptr *)&idt_descr); | 1165 | load_current_idt(); |
| 1166 | } | 1166 | } |
| 1167 | 1167 | ||
| 1168 | #else /* CONFIG_X86_64 */ | 1168 | #else /* CONFIG_X86_64 */ |
| @@ -1258,7 +1258,7 @@ void __cpuinit cpu_init(void) | |||
| 1258 | switch_to_new_gdt(cpu); | 1258 | switch_to_new_gdt(cpu); |
| 1259 | loadsegment(fs, 0); | 1259 | loadsegment(fs, 0); |
| 1260 | 1260 | ||
| 1261 | load_idt((const struct desc_ptr *)&idt_descr); | 1261 | load_current_idt(); |
| 1262 | 1262 | ||
| 1263 | memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8); | 1263 | memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8); |
| 1264 | syscall_init(); | 1264 | syscall_init(); |
| @@ -1335,7 +1335,7 @@ void __cpuinit cpu_init(void) | |||
| 1335 | if (cpu_has_vme || cpu_has_tsc || cpu_has_de) | 1335 | if (cpu_has_vme || cpu_has_tsc || cpu_has_de) |
| 1336 | clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); | 1336 | clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); |
| 1337 | 1337 | ||
| 1338 | load_idt(&idt_descr); | 1338 | load_current_idt(); |
| 1339 | switch_to_new_gdt(cpu); | 1339 | switch_to_new_gdt(cpu); |
| 1340 | 1340 | ||
| 1341 | /* | 1341 | /* |
diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c index 47a1870279aa..2f3a7995e56a 100644 --- a/arch/x86/kernel/cpu/mcheck/therm_throt.c +++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <asm/idle.h> | 29 | #include <asm/idle.h> |
| 30 | #include <asm/mce.h> | 30 | #include <asm/mce.h> |
| 31 | #include <asm/msr.h> | 31 | #include <asm/msr.h> |
| 32 | #include <asm/trace/irq_vectors.h> | ||
| 32 | 33 | ||
| 33 | /* How long to wait between reporting thermal events */ | 34 | /* How long to wait between reporting thermal events */ |
| 34 | #define CHECK_INTERVAL (300 * HZ) | 35 | #define CHECK_INTERVAL (300 * HZ) |
| @@ -378,15 +379,26 @@ static void unexpected_thermal_interrupt(void) | |||
| 378 | 379 | ||
| 379 | static void (*smp_thermal_vector)(void) = unexpected_thermal_interrupt; | 380 | static void (*smp_thermal_vector)(void) = unexpected_thermal_interrupt; |
| 380 | 381 | ||
| 381 | asmlinkage void smp_thermal_interrupt(struct pt_regs *regs) | 382 | static inline void __smp_thermal_interrupt(void) |
| 382 | { | 383 | { |
| 383 | irq_enter(); | ||
| 384 | exit_idle(); | ||
| 385 | inc_irq_stat(irq_thermal_count); | 384 | inc_irq_stat(irq_thermal_count); |
| 386 | smp_thermal_vector(); | 385 | smp_thermal_vector(); |
| 387 | irq_exit(); | 386 | } |
| 388 | /* Ack only at the end to avoid potential reentry */ | 387 | |
| 389 | ack_APIC_irq(); | 388 | asmlinkage void smp_thermal_interrupt(struct pt_regs *regs) |
| 389 | { | ||
| 390 | entering_irq(); | ||
| 391 | __smp_thermal_interrupt(); | ||
| 392 | exiting_ack_irq(); | ||
| 393 | } | ||
| 394 | |||
| 395 | asmlinkage void smp_trace_thermal_interrupt(struct pt_regs *regs) | ||
| 396 | { | ||
| 397 | entering_irq(); | ||
| 398 | trace_thermal_apic_entry(THERMAL_APIC_VECTOR); | ||
| 399 | __smp_thermal_interrupt(); | ||
| 400 | trace_thermal_apic_exit(THERMAL_APIC_VECTOR); | ||
| 401 | exiting_ack_irq(); | ||
| 390 | } | 402 | } |
| 391 | 403 | ||
| 392 | /* Thermal monitoring depends on APIC, ACPI and clock modulation */ | 404 | /* Thermal monitoring depends on APIC, ACPI and clock modulation */ |
diff --git a/arch/x86/kernel/cpu/mcheck/threshold.c b/arch/x86/kernel/cpu/mcheck/threshold.c index aa578cadb940..fe6b1c86645b 100644 --- a/arch/x86/kernel/cpu/mcheck/threshold.c +++ b/arch/x86/kernel/cpu/mcheck/threshold.c | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include <asm/apic.h> | 8 | #include <asm/apic.h> |
| 9 | #include <asm/idle.h> | 9 | #include <asm/idle.h> |
| 10 | #include <asm/mce.h> | 10 | #include <asm/mce.h> |
| 11 | #include <asm/trace/irq_vectors.h> | ||
| 11 | 12 | ||
| 12 | static void default_threshold_interrupt(void) | 13 | static void default_threshold_interrupt(void) |
| 13 | { | 14 | { |
| @@ -17,13 +18,24 @@ static void default_threshold_interrupt(void) | |||
| 17 | 18 | ||
| 18 | void (*mce_threshold_vector)(void) = default_threshold_interrupt; | 19 | void (*mce_threshold_vector)(void) = default_threshold_interrupt; |
| 19 | 20 | ||
| 20 | asmlinkage void smp_threshold_interrupt(void) | 21 | static inline void __smp_threshold_interrupt(void) |
| 21 | { | 22 | { |
| 22 | irq_enter(); | ||
| 23 | exit_idle(); | ||
| 24 | inc_irq_stat(irq_threshold_count); | 23 | inc_irq_stat(irq_threshold_count); |
| 25 | mce_threshold_vector(); | 24 | mce_threshold_vector(); |
| 26 | irq_exit(); | 25 | } |
| 27 | /* Ack only at the end to avoid potential reentry */ | 26 | |
| 28 | ack_APIC_irq(); | 27 | asmlinkage void smp_threshold_interrupt(void) |
| 28 | { | ||
| 29 | entering_irq(); | ||
| 30 | __smp_threshold_interrupt(); | ||
| 31 | exiting_ack_irq(); | ||
| 32 | } | ||
| 33 | |||
| 34 | asmlinkage void smp_trace_threshold_interrupt(void) | ||
| 35 | { | ||
| 36 | entering_irq(); | ||
| 37 | trace_threshold_apic_entry(THRESHOLD_APIC_VECTOR); | ||
| 38 | __smp_threshold_interrupt(); | ||
| 39 | trace_threshold_apic_exit(THRESHOLD_APIC_VECTOR); | ||
| 40 | exiting_ack_irq(); | ||
| 29 | } | 41 | } |
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 8f3e2dec1df3..2cfbc3a3a2dd 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S | |||
| @@ -801,7 +801,17 @@ ENTRY(name) \ | |||
| 801 | CFI_ENDPROC; \ | 801 | CFI_ENDPROC; \ |
| 802 | ENDPROC(name) | 802 | ENDPROC(name) |
| 803 | 803 | ||
| 804 | #define BUILD_INTERRUPT(name, nr) BUILD_INTERRUPT3(name, nr, smp_##name) | 804 | |
| 805 | #ifdef CONFIG_TRACING | ||
| 806 | #define TRACE_BUILD_INTERRUPT(name, nr) \ | ||
| 807 | BUILD_INTERRUPT3(trace_##name, nr, smp_trace_##name) | ||
| 808 | #else | ||
| 809 | #define TRACE_BUILD_INTERRUPT(name, nr) | ||
| 810 | #endif | ||
| 811 | |||
| 812 | #define BUILD_INTERRUPT(name, nr) \ | ||
| 813 | BUILD_INTERRUPT3(name, nr, smp_##name); \ | ||
| 814 | TRACE_BUILD_INTERRUPT(name, nr) | ||
| 805 | 815 | ||
| 806 | /* The include is where all of the SMP etc. interrupts come from */ | 816 | /* The include is where all of the SMP etc. interrupts come from */ |
| 807 | #include <asm/entry_arch.h> | 817 | #include <asm/entry_arch.h> |
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 5fe1fb2d1490..1b69951a81e2 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
| @@ -1138,7 +1138,7 @@ END(common_interrupt) | |||
| 1138 | /* | 1138 | /* |
| 1139 | * APIC interrupts. | 1139 | * APIC interrupts. |
| 1140 | */ | 1140 | */ |
| 1141 | .macro apicinterrupt num sym do_sym | 1141 | .macro apicinterrupt3 num sym do_sym |
| 1142 | ENTRY(\sym) | 1142 | ENTRY(\sym) |
| 1143 | INTR_FRAME | 1143 | INTR_FRAME |
| 1144 | ASM_CLAC | 1144 | ASM_CLAC |
| @@ -1150,15 +1150,32 @@ ENTRY(\sym) | |||
| 1150 | END(\sym) | 1150 | END(\sym) |
| 1151 | .endm | 1151 | .endm |
| 1152 | 1152 | ||
| 1153 | #ifdef CONFIG_TRACING | ||
| 1154 | #define trace(sym) trace_##sym | ||
| 1155 | #define smp_trace(sym) smp_trace_##sym | ||
| 1156 | |||
| 1157 | .macro trace_apicinterrupt num sym | ||
| 1158 | apicinterrupt3 \num trace(\sym) smp_trace(\sym) | ||
| 1159 | .endm | ||
| 1160 | #else | ||
| 1161 | .macro trace_apicinterrupt num sym do_sym | ||
| 1162 | .endm | ||
| 1163 | #endif | ||
| 1164 | |||
| 1165 | .macro apicinterrupt num sym do_sym | ||
| 1166 | apicinterrupt3 \num \sym \do_sym | ||
| 1167 | trace_apicinterrupt \num \sym | ||
| 1168 | .endm | ||
| 1169 | |||
| 1153 | #ifdef CONFIG_SMP | 1170 | #ifdef CONFIG_SMP |
| 1154 | apicinterrupt IRQ_MOVE_CLEANUP_VECTOR \ | 1171 | apicinterrupt3 IRQ_MOVE_CLEANUP_VECTOR \ |
| 1155 | irq_move_cleanup_interrupt smp_irq_move_cleanup_interrupt | 1172 | irq_move_cleanup_interrupt smp_irq_move_cleanup_interrupt |
| 1156 | apicinterrupt REBOOT_VECTOR \ | 1173 | apicinterrupt3 REBOOT_VECTOR \ |
| 1157 | reboot_interrupt smp_reboot_interrupt | 1174 | reboot_interrupt smp_reboot_interrupt |
| 1158 | #endif | 1175 | #endif |
| 1159 | 1176 | ||
| 1160 | #ifdef CONFIG_X86_UV | 1177 | #ifdef CONFIG_X86_UV |
| 1161 | apicinterrupt UV_BAU_MESSAGE \ | 1178 | apicinterrupt3 UV_BAU_MESSAGE \ |
| 1162 | uv_bau_message_intr1 uv_bau_message_interrupt | 1179 | uv_bau_message_intr1 uv_bau_message_interrupt |
| 1163 | #endif | 1180 | #endif |
| 1164 | apicinterrupt LOCAL_TIMER_VECTOR \ | 1181 | apicinterrupt LOCAL_TIMER_VECTOR \ |
| @@ -1167,14 +1184,19 @@ apicinterrupt X86_PLATFORM_IPI_VECTOR \ | |||
| 1167 | x86_platform_ipi smp_x86_platform_ipi | 1184 | x86_platform_ipi smp_x86_platform_ipi |
| 1168 | 1185 | ||
| 1169 | #ifdef CONFIG_HAVE_KVM | 1186 | #ifdef CONFIG_HAVE_KVM |
| 1170 | apicinterrupt POSTED_INTR_VECTOR \ | 1187 | apicinterrupt3 POSTED_INTR_VECTOR \ |
| 1171 | kvm_posted_intr_ipi smp_kvm_posted_intr_ipi | 1188 | kvm_posted_intr_ipi smp_kvm_posted_intr_ipi |
| 1172 | #endif | 1189 | #endif |
| 1173 | 1190 | ||
| 1191 | #ifdef CONFIG_X86_MCE_THRESHOLD | ||
| 1174 | apicinterrupt THRESHOLD_APIC_VECTOR \ | 1192 | apicinterrupt THRESHOLD_APIC_VECTOR \ |
| 1175 | threshold_interrupt smp_threshold_interrupt | 1193 | threshold_interrupt smp_threshold_interrupt |
| 1194 | #endif | ||
| 1195 | |||
| 1196 | #ifdef CONFIG_X86_THERMAL_VECTOR | ||
| 1176 | apicinterrupt THERMAL_APIC_VECTOR \ | 1197 | apicinterrupt THERMAL_APIC_VECTOR \ |
| 1177 | thermal_interrupt smp_thermal_interrupt | 1198 | thermal_interrupt smp_thermal_interrupt |
| 1199 | #endif | ||
| 1178 | 1200 | ||
| 1179 | #ifdef CONFIG_SMP | 1201 | #ifdef CONFIG_SMP |
| 1180 | apicinterrupt CALL_FUNCTION_SINGLE_VECTOR \ | 1202 | apicinterrupt CALL_FUNCTION_SINGLE_VECTOR \ |
| @@ -1451,13 +1473,13 @@ ENTRY(xen_failsafe_callback) | |||
| 1451 | CFI_ENDPROC | 1473 | CFI_ENDPROC |
| 1452 | END(xen_failsafe_callback) | 1474 | END(xen_failsafe_callback) |
| 1453 | 1475 | ||
| 1454 | apicinterrupt HYPERVISOR_CALLBACK_VECTOR \ | 1476 | apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \ |
| 1455 | xen_hvm_callback_vector xen_evtchn_do_upcall | 1477 | xen_hvm_callback_vector xen_evtchn_do_upcall |
| 1456 | 1478 | ||
| 1457 | #endif /* CONFIG_XEN */ | 1479 | #endif /* CONFIG_XEN */ |
| 1458 | 1480 | ||
| 1459 | #if IS_ENABLED(CONFIG_HYPERV) | 1481 | #if IS_ENABLED(CONFIG_HYPERV) |
| 1460 | apicinterrupt HYPERVISOR_CALLBACK_VECTOR \ | 1482 | apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \ |
| 1461 | hyperv_callback_vector hyperv_vector_handler | 1483 | hyperv_callback_vector hyperv_vector_handler |
| 1462 | #endif /* CONFIG_HYPERV */ | 1484 | #endif /* CONFIG_HYPERV */ |
| 1463 | 1485 | ||
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 321d65ebaffe..5e4d8a8a5c40 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S | |||
| @@ -518,9 +518,15 @@ ENTRY(idt_table) | |||
| 518 | .skip IDT_ENTRIES * 16 | 518 | .skip IDT_ENTRIES * 16 |
| 519 | 519 | ||
| 520 | .align L1_CACHE_BYTES | 520 | .align L1_CACHE_BYTES |
| 521 | ENTRY(nmi_idt_table) | 521 | ENTRY(debug_idt_table) |
| 522 | .skip IDT_ENTRIES * 16 | 522 | .skip IDT_ENTRIES * 16 |
| 523 | 523 | ||
| 524 | #ifdef CONFIG_TRACING | ||
| 525 | .align L1_CACHE_BYTES | ||
| 526 | ENTRY(trace_idt_table) | ||
| 527 | .skip IDT_ENTRIES * 16 | ||
| 528 | #endif | ||
| 529 | |||
| 524 | __PAGE_ALIGNED_BSS | 530 | __PAGE_ALIGNED_BSS |
| 525 | NEXT_PAGE(empty_zero_page) | 531 | NEXT_PAGE(empty_zero_page) |
| 526 | .skip PAGE_SIZE | 532 | .skip PAGE_SIZE |
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index ac0631d8996f..3a8185c042a2 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c | |||
| @@ -18,6 +18,9 @@ | |||
| 18 | #include <asm/mce.h> | 18 | #include <asm/mce.h> |
| 19 | #include <asm/hw_irq.h> | 19 | #include <asm/hw_irq.h> |
| 20 | 20 | ||
| 21 | #define CREATE_TRACE_POINTS | ||
| 22 | #include <asm/trace/irq_vectors.h> | ||
| 23 | |||
| 21 | atomic_t irq_err_count; | 24 | atomic_t irq_err_count; |
| 22 | 25 | ||
| 23 | /* Function pointer for generic interrupt vector handling */ | 26 | /* Function pointer for generic interrupt vector handling */ |
| @@ -204,23 +207,21 @@ unsigned int __irq_entry do_IRQ(struct pt_regs *regs) | |||
| 204 | /* | 207 | /* |
| 205 | * Handler for X86_PLATFORM_IPI_VECTOR. | 208 | * Handler for X86_PLATFORM_IPI_VECTOR. |
| 206 | */ | 209 | */ |
| 207 | void smp_x86_platform_ipi(struct pt_regs *regs) | 210 | void __smp_x86_platform_ipi(void) |
| 208 | { | 211 | { |
| 209 | struct pt_regs *old_regs = set_irq_regs(regs); | ||
| 210 | |||
| 211 | ack_APIC_irq(); | ||
| 212 | |||
| 213 | irq_enter(); | ||
| 214 | |||
| 215 | exit_idle(); | ||
| 216 | |||
| 217 | inc_irq_stat(x86_platform_ipis); | 212 | inc_irq_stat(x86_platform_ipis); |
| 218 | 213 | ||
| 219 | if (x86_platform_ipi_callback) | 214 | if (x86_platform_ipi_callback) |
| 220 | x86_platform_ipi_callback(); | 215 | x86_platform_ipi_callback(); |
| 216 | } | ||
| 221 | 217 | ||
| 222 | irq_exit(); | 218 | void smp_x86_platform_ipi(struct pt_regs *regs) |
| 219 | { | ||
| 220 | struct pt_regs *old_regs = set_irq_regs(regs); | ||
| 223 | 221 | ||
| 222 | entering_ack_irq(); | ||
| 223 | __smp_x86_platform_ipi(); | ||
| 224 | exiting_irq(); | ||
| 224 | set_irq_regs(old_regs); | 225 | set_irq_regs(old_regs); |
| 225 | } | 226 | } |
| 226 | 227 | ||
| @@ -246,6 +247,18 @@ void smp_kvm_posted_intr_ipi(struct pt_regs *regs) | |||
| 246 | } | 247 | } |
| 247 | #endif | 248 | #endif |
| 248 | 249 | ||
| 250 | void smp_trace_x86_platform_ipi(struct pt_regs *regs) | ||
| 251 | { | ||
| 252 | struct pt_regs *old_regs = set_irq_regs(regs); | ||
| 253 | |||
| 254 | entering_ack_irq(); | ||
| 255 | trace_x86_platform_ipi_entry(X86_PLATFORM_IPI_VECTOR); | ||
| 256 | __smp_x86_platform_ipi(); | ||
| 257 | trace_x86_platform_ipi_exit(X86_PLATFORM_IPI_VECTOR); | ||
| 258 | exiting_irq(); | ||
| 259 | set_irq_regs(old_regs); | ||
| 260 | } | ||
| 261 | |||
| 249 | EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq); | 262 | EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq); |
| 250 | 263 | ||
| 251 | #ifdef CONFIG_HOTPLUG_CPU | 264 | #ifdef CONFIG_HOTPLUG_CPU |
diff --git a/arch/x86/kernel/irq_work.c b/arch/x86/kernel/irq_work.c index ca8f703a1e70..636a55e4a13c 100644 --- a/arch/x86/kernel/irq_work.c +++ b/arch/x86/kernel/irq_work.c | |||
| @@ -8,14 +8,34 @@ | |||
| 8 | #include <linux/irq_work.h> | 8 | #include <linux/irq_work.h> |
| 9 | #include <linux/hardirq.h> | 9 | #include <linux/hardirq.h> |
| 10 | #include <asm/apic.h> | 10 | #include <asm/apic.h> |
| 11 | #include <asm/trace/irq_vectors.h> | ||
| 11 | 12 | ||
| 12 | void smp_irq_work_interrupt(struct pt_regs *regs) | 13 | static inline void irq_work_entering_irq(void) |
| 13 | { | 14 | { |
| 14 | irq_enter(); | 15 | irq_enter(); |
| 15 | ack_APIC_irq(); | 16 | ack_APIC_irq(); |
| 17 | } | ||
| 18 | |||
| 19 | static inline void __smp_irq_work_interrupt(void) | ||
| 20 | { | ||
| 16 | inc_irq_stat(apic_irq_work_irqs); | 21 | inc_irq_stat(apic_irq_work_irqs); |
| 17 | irq_work_run(); | 22 | irq_work_run(); |
| 18 | irq_exit(); | 23 | } |
| 24 | |||
| 25 | void smp_irq_work_interrupt(struct pt_regs *regs) | ||
| 26 | { | ||
| 27 | irq_work_entering_irq(); | ||
| 28 | __smp_irq_work_interrupt(); | ||
| 29 | exiting_irq(); | ||
| 30 | } | ||
| 31 | |||
| 32 | void smp_trace_irq_work_interrupt(struct pt_regs *regs) | ||
| 33 | { | ||
| 34 | irq_work_entering_irq(); | ||
| 35 | trace_irq_work_entry(IRQ_WORK_VECTOR); | ||
| 36 | __smp_irq_work_interrupt(); | ||
| 37 | trace_irq_work_exit(IRQ_WORK_VECTOR); | ||
| 38 | exiting_irq(); | ||
| 19 | } | 39 | } |
| 20 | 40 | ||
| 21 | void arch_irq_work_raise(void) | 41 | void arch_irq_work_raise(void) |
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c index 48d2b7ded422..f4fe0b8879e0 100644 --- a/arch/x86/kernel/smp.c +++ b/arch/x86/kernel/smp.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include <asm/proto.h> | 30 | #include <asm/proto.h> |
| 31 | #include <asm/apic.h> | 31 | #include <asm/apic.h> |
| 32 | #include <asm/nmi.h> | 32 | #include <asm/nmi.h> |
| 33 | #include <asm/trace/irq_vectors.h> | ||
| 33 | /* | 34 | /* |
| 34 | * Some notes on x86 processor bugs affecting SMP operation: | 35 | * Some notes on x86 processor bugs affecting SMP operation: |
| 35 | * | 36 | * |
| @@ -249,32 +250,80 @@ finish: | |||
| 249 | /* | 250 | /* |
| 250 | * Reschedule call back. | 251 | * Reschedule call back. |
| 251 | */ | 252 | */ |
| 252 | void smp_reschedule_interrupt(struct pt_regs *regs) | 253 | static inline void __smp_reschedule_interrupt(void) |
| 253 | { | 254 | { |
| 254 | ack_APIC_irq(); | ||
| 255 | inc_irq_stat(irq_resched_count); | 255 | inc_irq_stat(irq_resched_count); |
| 256 | scheduler_ipi(); | 256 | scheduler_ipi(); |
| 257 | } | ||
| 258 | |||
| 259 | void smp_reschedule_interrupt(struct pt_regs *regs) | ||
| 260 | { | ||
| 261 | ack_APIC_irq(); | ||
| 262 | __smp_reschedule_interrupt(); | ||
| 257 | /* | 263 | /* |
| 258 | * KVM uses this interrupt to force a cpu out of guest mode | 264 | * KVM uses this interrupt to force a cpu out of guest mode |
| 259 | */ | 265 | */ |
| 260 | } | 266 | } |
| 261 | 267 | ||
| 262 | void smp_call_function_interrupt(struct pt_regs *regs) | 268 | void smp_trace_reschedule_interrupt(struct pt_regs *regs) |
| 269 | { | ||
| 270 | ack_APIC_irq(); | ||
| 271 | trace_reschedule_entry(RESCHEDULE_VECTOR); | ||
| 272 | __smp_reschedule_interrupt(); | ||
| 273 | trace_reschedule_exit(RESCHEDULE_VECTOR); | ||
| 274 | /* | ||
| 275 | * KVM uses this interrupt to force a cpu out of guest mode | ||
| 276 | */ | ||
| 277 | } | ||
| 278 | |||
| 279 | static inline void call_function_entering_irq(void) | ||
| 263 | { | 280 | { |
| 264 | ack_APIC_irq(); | 281 | ack_APIC_irq(); |
| 265 | irq_enter(); | 282 | irq_enter(); |
| 283 | } | ||
| 284 | |||
| 285 | static inline void __smp_call_function_interrupt(void) | ||
| 286 | { | ||
| 266 | generic_smp_call_function_interrupt(); | 287 | generic_smp_call_function_interrupt(); |
| 267 | inc_irq_stat(irq_call_count); | 288 | inc_irq_stat(irq_call_count); |
| 268 | irq_exit(); | ||
| 269 | } | 289 | } |
| 270 | 290 | ||
| 271 | void smp_call_function_single_interrupt(struct pt_regs *regs) | 291 | void smp_call_function_interrupt(struct pt_regs *regs) |
| 292 | { | ||
| 293 | call_function_entering_irq(); | ||
| 294 | __smp_call_function_interrupt(); | ||
| 295 | exiting_irq(); | ||
| 296 | } | ||
| 297 | |||
| 298 | void smp_trace_call_function_interrupt(struct pt_regs *regs) | ||
| 299 | { | ||
| 300 | call_function_entering_irq(); | ||
| 301 | trace_call_function_entry(CALL_FUNCTION_VECTOR); | ||
| 302 | __smp_call_function_interrupt(); | ||
| 303 | trace_call_function_exit(CALL_FUNCTION_VECTOR); | ||
| 304 | exiting_irq(); | ||
| 305 | } | ||
| 306 | |||
| 307 | static inline void __smp_call_function_single_interrupt(void) | ||
| 272 | { | 308 | { |
| 273 | ack_APIC_irq(); | ||
| 274 | irq_enter(); | ||
| 275 | generic_smp_call_function_single_interrupt(); | 309 | generic_smp_call_function_single_interrupt(); |
| 276 | inc_irq_stat(irq_call_count); | 310 | inc_irq_stat(irq_call_count); |
| 277 | irq_exit(); | 311 | } |
| 312 | |||
| 313 | void smp_call_function_single_interrupt(struct pt_regs *regs) | ||
| 314 | { | ||
| 315 | call_function_entering_irq(); | ||
| 316 | __smp_call_function_single_interrupt(); | ||
| 317 | exiting_irq(); | ||
| 318 | } | ||
| 319 | |||
| 320 | void smp_trace_call_function_single_interrupt(struct pt_regs *regs) | ||
| 321 | { | ||
| 322 | call_function_entering_irq(); | ||
| 323 | trace_call_function_single_entry(CALL_FUNCTION_SINGLE_VECTOR); | ||
| 324 | __smp_call_function_single_interrupt(); | ||
| 325 | trace_call_function_single_exit(CALL_FUNCTION_SINGLE_VECTOR); | ||
| 326 | exiting_irq(); | ||
| 278 | } | 327 | } |
| 279 | 328 | ||
| 280 | static int __init nonmi_ipi_setup(char *str) | 329 | static int __init nonmi_ipi_setup(char *str) |
diff --git a/arch/x86/kernel/tracepoint.c b/arch/x86/kernel/tracepoint.c new file mode 100644 index 000000000000..4e584a8d6edd --- /dev/null +++ b/arch/x86/kernel/tracepoint.c | |||
| @@ -0,0 +1,61 @@ | |||
| 1 | /* | ||
| 2 | * Code for supporting irq vector tracepoints. | ||
| 3 | * | ||
| 4 | * Copyright (C) 2013 Seiji Aguchi <seiji.aguchi@hds.com> | ||
| 5 | * | ||
| 6 | */ | ||
| 7 | #include <asm/hw_irq.h> | ||
| 8 | #include <asm/desc.h> | ||
| 9 | #include <linux/atomic.h> | ||
| 10 | |||
| 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 }; | ||
| 14 | |||
| 15 | #ifndef CONFIG_X86_64 | ||
| 16 | gate_desc trace_idt_table[NR_VECTORS] __page_aligned_data | ||
| 17 | = { { { { 0, 0 } } }, }; | ||
| 18 | #endif | ||
| 19 | |||
| 20 | static int trace_irq_vector_refcount; | ||
| 21 | static DEFINE_MUTEX(irq_vector_mutex); | ||
| 22 | |||
| 23 | static void set_trace_idt_ctr(int val) | ||
| 24 | { | ||
| 25 | atomic_set(&trace_idt_ctr, val); | ||
| 26 | /* Ensure the trace_idt_ctr is set before sending IPI */ | ||
| 27 | wmb(); | ||
| 28 | } | ||
| 29 | |||
| 30 | static void switch_idt(void *arg) | ||
| 31 | { | ||
| 32 | unsigned long flags; | ||
| 33 | |||
| 34 | local_irq_save(flags); | ||
| 35 | load_current_idt(); | ||
| 36 | local_irq_restore(flags); | ||
| 37 | } | ||
| 38 | |||
| 39 | void trace_irq_vector_regfunc(void) | ||
| 40 | { | ||
| 41 | mutex_lock(&irq_vector_mutex); | ||
| 42 | if (!trace_irq_vector_refcount) { | ||
| 43 | set_trace_idt_ctr(1); | ||
| 44 | smp_call_function(switch_idt, NULL, 0); | ||
| 45 | switch_idt(NULL); | ||
| 46 | } | ||
| 47 | trace_irq_vector_refcount++; | ||
| 48 | mutex_unlock(&irq_vector_mutex); | ||
| 49 | } | ||
| 50 | |||
| 51 | void trace_irq_vector_unregfunc(void) | ||
| 52 | { | ||
| 53 | mutex_lock(&irq_vector_mutex); | ||
| 54 | trace_irq_vector_refcount--; | ||
| 55 | if (!trace_irq_vector_refcount) { | ||
| 56 | set_trace_idt_ctr(0); | ||
| 57 | smp_call_function(switch_idt, NULL, 0); | ||
| 58 | switch_idt(NULL); | ||
| 59 | } | ||
| 60 | mutex_unlock(&irq_vector_mutex); | ||
| 61 | } | ||
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index ee3d8e510504..b0865e88d3cc 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
| @@ -788,7 +788,7 @@ void __init trap_init(void) | |||
| 788 | x86_init.irqs.trap_init(); | 788 | x86_init.irqs.trap_init(); |
| 789 | 789 | ||
| 790 | #ifdef CONFIG_X86_64 | 790 | #ifdef CONFIG_X86_64 |
| 791 | memcpy(&nmi_idt_table, &idt_table, IDT_ENTRIES * 16); | 791 | memcpy(&debug_idt_table, &idt_table, IDT_ENTRIES * 16); |
| 792 | set_nmi_gate(X86_TRAP_DB, &debug); | 792 | set_nmi_gate(X86_TRAP_DB, &debug); |
| 793 | set_nmi_gate(X86_TRAP_BP, &int3); | 793 | set_nmi_gate(X86_TRAP_BP, &int3); |
| 794 | #endif | 794 | #endif |
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index f8e084d0fc77..ebeab360d851 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h | |||
| @@ -378,6 +378,8 @@ static inline void tracepoint_synchronize_unregister(void) | |||
| 378 | #define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print) | 378 | #define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print) |
| 379 | #define DEFINE_EVENT(template, name, proto, args) \ | 379 | #define DEFINE_EVENT(template, name, proto, args) \ |
| 380 | DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) | 380 | DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) |
| 381 | #define DEFINE_EVENT_FN(template, name, proto, args, reg, unreg)\ | ||
| 382 | DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) | ||
| 381 | #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ | 383 | #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ |
| 382 | DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) | 384 | DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) |
| 383 | #define DEFINE_EVENT_CONDITION(template, name, proto, \ | 385 | #define DEFINE_EVENT_CONDITION(template, name, proto, \ |
diff --git a/include/trace/define_trace.h b/include/trace/define_trace.h index 1905ca8dd399..02e1003568a4 100644 --- a/include/trace/define_trace.h +++ b/include/trace/define_trace.h | |||
| @@ -44,6 +44,10 @@ | |||
| 44 | #define DEFINE_EVENT(template, name, proto, args) \ | 44 | #define DEFINE_EVENT(template, name, proto, args) \ |
| 45 | DEFINE_TRACE(name) | 45 | DEFINE_TRACE(name) |
| 46 | 46 | ||
| 47 | #undef DEFINE_EVENT_FN | ||
| 48 | #define DEFINE_EVENT_FN(template, name, proto, args, reg, unreg) \ | ||
| 49 | DEFINE_TRACE_FN(name, reg, unreg) | ||
| 50 | |||
| 47 | #undef DEFINE_EVENT_PRINT | 51 | #undef DEFINE_EVENT_PRINT |
| 48 | #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ | 52 | #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ |
| 49 | DEFINE_TRACE(name) | 53 | DEFINE_TRACE(name) |
| @@ -91,6 +95,7 @@ | |||
| 91 | #undef TRACE_EVENT_CONDITION | 95 | #undef TRACE_EVENT_CONDITION |
| 92 | #undef DECLARE_EVENT_CLASS | 96 | #undef DECLARE_EVENT_CLASS |
| 93 | #undef DEFINE_EVENT | 97 | #undef DEFINE_EVENT |
| 98 | #undef DEFINE_EVENT_FN | ||
| 94 | #undef DEFINE_EVENT_PRINT | 99 | #undef DEFINE_EVENT_PRINT |
| 95 | #undef DEFINE_EVENT_CONDITION | 100 | #undef DEFINE_EVENT_CONDITION |
| 96 | #undef TRACE_HEADER_MULTI_READ | 101 | #undef TRACE_HEADER_MULTI_READ |
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 19edd7facaa1..d615f78cc6b6 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h | |||
| @@ -71,6 +71,10 @@ | |||
| 71 | static struct ftrace_event_call __used \ | 71 | static struct ftrace_event_call __used \ |
| 72 | __attribute__((__aligned__(4))) event_##name | 72 | __attribute__((__aligned__(4))) event_##name |
| 73 | 73 | ||
| 74 | #undef DEFINE_EVENT_FN | ||
| 75 | #define DEFINE_EVENT_FN(template, name, proto, args, reg, unreg) \ | ||
| 76 | DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) | ||
| 77 | |||
| 74 | #undef DEFINE_EVENT_PRINT | 78 | #undef DEFINE_EVENT_PRINT |
| 75 | #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ | 79 | #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ |
| 76 | DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) | 80 | DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) |
diff --git a/include/xen/events.h b/include/xen/events.h index b2b27c6a0f7b..c9ea10ee2273 100644 --- a/include/xen/events.h +++ b/include/xen/events.h | |||
| @@ -76,6 +76,9 @@ unsigned irq_from_evtchn(unsigned int evtchn); | |||
| 76 | 76 | ||
| 77 | /* Xen HVM evtchn vector callback */ | 77 | /* Xen HVM evtchn vector callback */ |
| 78 | void xen_hvm_callback_vector(void); | 78 | void xen_hvm_callback_vector(void); |
| 79 | #ifdef CONFIG_TRACING | ||
| 80 | #define trace_xen_hvm_callback_vector xen_hvm_callback_vector | ||
| 81 | #endif | ||
| 79 | extern int xen_have_vector_callback; | 82 | extern int xen_have_vector_callback; |
| 80 | int xen_set_callback_via(uint64_t via); | 83 | int xen_set_callback_via(uint64_t via); |
| 81 | void xen_evtchn_do_upcall(struct pt_regs *regs); | 84 | void xen_evtchn_do_upcall(struct pt_regs *regs); |
