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); | ||
