Merge branch 'x86/ras' into x86/core, to fix conflicts
[deliverable/linux.git] / arch / x86 / kernel / irq.c
index e5952c22553241e2ceea5d5fd6f1f7b758cc960e..88b366487b0e44b613e83d412febfad74381ca92 100644 (file)
 #define CREATE_TRACE_POINTS
 #include <asm/trace/irq_vectors.h>
 
+DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
+EXPORT_PER_CPU_SYMBOL(irq_stat);
+
+DEFINE_PER_CPU(struct pt_regs *, irq_regs);
+EXPORT_PER_CPU_SYMBOL(irq_regs);
+
 atomic_t irq_err_count;
 
 /* Function pointer for generic interrupt vector handling */
@@ -116,6 +122,12 @@ int arch_show_interrupts(struct seq_file *p, int prec)
                seq_printf(p, "%10u ", irq_stats(j)->irq_threshold_count);
        seq_puts(p, "  Threshold APIC interrupts\n");
 #endif
+#ifdef CONFIG_X86_MCE_AMD
+       seq_printf(p, "%*s: ", prec, "DFR");
+       for_each_online_cpu(j)
+               seq_printf(p, "%10u ", irq_stats(j)->irq_deferred_error_count);
+       seq_puts(p, "  Deferred Error APIC interrupts\n");
+#endif
 #ifdef CONFIG_X86_MCE
        seq_printf(p, "%*s: ", prec, "MCE");
        for_each_online_cpu(j)
@@ -135,6 +147,18 @@ int arch_show_interrupts(struct seq_file *p, int prec)
        seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count));
 #if defined(CONFIG_X86_IO_APIC)
        seq_printf(p, "%*s: %10u\n", prec, "MIS", atomic_read(&irq_mis_count));
+#endif
+#ifdef CONFIG_HAVE_KVM
+       seq_printf(p, "%*s: ", prec, "PIN");
+       for_each_online_cpu(j)
+               seq_printf(p, "%10u ", irq_stats(j)->kvm_posted_intr_ipis);
+       seq_puts(p, "  Posted-interrupt notification event\n");
+
+       seq_printf(p, "%*s: ", prec, "PIW");
+       for_each_online_cpu(j)
+               seq_printf(p, "%10u ",
+                          irq_stats(j)->kvm_posted_intr_wakeup_ipis);
+       seq_puts(p, "  Posted-interrupt wakeup event\n");
 #endif
        return 0;
 }
@@ -192,8 +216,7 @@ __visible unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
        unsigned vector = ~regs->orig_ax;
        unsigned irq;
 
-       irq_enter();
-       exit_idle();
+       entering_irq();
 
        irq = __this_cpu_read(vector_irq[vector]);
 
@@ -209,7 +232,7 @@ __visible unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
                }
        }
 
-       irq_exit();
+       exiting_irq();
 
        set_irq_regs(old_regs);
        return 1;
@@ -237,6 +260,18 @@ __visible void smp_x86_platform_ipi(struct pt_regs *regs)
 }
 
 #ifdef CONFIG_HAVE_KVM
+static void dummy_handler(void) {}
+static void (*kvm_posted_intr_wakeup_handler)(void) = dummy_handler;
+
+void kvm_set_posted_intr_wakeup_handler(void (*handler)(void))
+{
+       if (handler)
+               kvm_posted_intr_wakeup_handler = handler;
+       else
+               kvm_posted_intr_wakeup_handler = dummy_handler;
+}
+EXPORT_SYMBOL_GPL(kvm_set_posted_intr_wakeup_handler);
+
 /*
  * Handler for POSTED_INTERRUPT_VECTOR.
  */
@@ -244,16 +279,23 @@ __visible void smp_kvm_posted_intr_ipi(struct pt_regs *regs)
 {
        struct pt_regs *old_regs = set_irq_regs(regs);
 
-       ack_APIC_irq();
-
-       irq_enter();
-
-       exit_idle();
-
+       entering_ack_irq();
        inc_irq_stat(kvm_posted_intr_ipis);
+       exiting_irq();
+       set_irq_regs(old_regs);
+}
 
-       irq_exit();
+/*
+ * Handler for POSTED_INTERRUPT_WAKEUP_VECTOR.
+ */
+__visible void smp_kvm_posted_intr_wakeup_ipi(struct pt_regs *regs)
+{
+       struct pt_regs *old_regs = set_irq_regs(regs);
 
+       entering_ack_irq();
+       inc_irq_stat(kvm_posted_intr_wakeup_ipis);
+       kvm_posted_intr_wakeup_handler();
+       exiting_irq();
        set_irq_regs(old_regs);
 }
 #endif
This page took 0.030076 seconds and 5 git commands to generate.