]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - arch/x86/kernel/irq.c
Merge branch 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[karo-tx-linux.git] / arch / x86 / kernel / irq.c
index e010847583d7895c7c301a4fe74329691496ed74..f8062aaf5df9c830ec287f6774ad270e13d34b32 100644 (file)
@@ -139,10 +139,13 @@ int arch_show_interrupts(struct seq_file *p, int prec)
        seq_puts(p, "  Machine check polls\n");
 #endif
 #if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN)
-       seq_printf(p, "%*s: ", prec, "HYP");
-       for_each_online_cpu(j)
-               seq_printf(p, "%10u ", irq_stats(j)->irq_hv_callback_count);
-       seq_puts(p, "  Hypervisor callback interrupts\n");
+       if (test_bit(HYPERVISOR_CALLBACK_VECTOR, used_vectors)) {
+               seq_printf(p, "%*s: ", prec, "HYP");
+               for_each_online_cpu(j)
+                       seq_printf(p, "%10u ",
+                                  irq_stats(j)->irq_hv_callback_count);
+               seq_puts(p, "  Hypervisor callback interrupts\n");
+       }
 #endif
        seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count));
 #if defined(CONFIG_X86_IO_APIC)
@@ -215,8 +218,23 @@ __visible unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
        /* high bit used in ret_from_ code  */
        unsigned vector = ~regs->orig_ax;
 
+       /*
+        * NB: Unlike exception entries, IRQ entries do not reliably
+        * handle context tracking in the low-level entry code.  This is
+        * because syscall entries execute briefly with IRQs on before
+        * updating context tracking state, so we can take an IRQ from
+        * kernel mode with CONTEXT_USER.  The low-level entry code only
+        * updates the context if we came from user mode, so we won't
+        * switch to CONTEXT_KERNEL.  We'll fix that once the syscall
+        * code is cleaned up enough that we can cleanly defer enabling
+        * IRQs.
+        */
+
        entering_irq();
 
+       /* entering_irq() tells RCU that we're not quiescent.  Check it. */
+       RCU_LOCKDEP_WARN(!rcu_is_watching(), "IRQ failed to wake up RCU");
+
        desc = __this_cpu_read(vector_irq[vector]);
 
        if (!handle_irq(desc, regs)) {