powerpc/64s: Move HMI IRQ stat from percpu variable to paca.
authorMahesh Salgaonkar <mahesh@linux.ibm.com>
Tue, 23 Jun 2020 10:27:50 +0000 (15:57 +0530)
committerMichael Ellerman <mpe@ellerman.id.au>
Wed, 29 Jul 2020 13:47:53 +0000 (23:47 +1000)
With the proposed change in percpu bootmem allocator to use page
mapping [1], the percpu first chunk memory area can come from vmalloc
ranges. This makes the HMI (Hypervisor Maintenance Interrupt) handler
crash the kernel whenever percpu variable is accessed in real mode.
This patch fixes this issue by moving the HMI IRQ stat inside paca for
safe access in realmode.

[1] https://lore.kernel.org/linuxppc-dev/20200608070904.387440-1-aneesh.kumar@linux.ibm.com/

Suggested-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Signed-off-by: Mahesh Salgaonkar <mahesh@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/159290806973.3642154.5244613424529764050.stgit@jupiter
arch/powerpc/include/asm/hardirq.h
arch/powerpc/include/asm/paca.h
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/mce.c
arch/powerpc/kvm/book3s_hv_ras.c

index f1e9067bd5ac1090e271b6430ba271d64397fc84..f133b5930ae15e188a6db7df2e1f0d1050ac688b 100644 (file)
@@ -13,7 +13,6 @@ typedef struct {
        unsigned int pmu_irqs;
        unsigned int mce_exceptions;
        unsigned int spurious_irqs;
-       unsigned int hmi_exceptions;
        unsigned int sreset_irqs;
 #ifdef CONFIG_PPC_WATCHDOG
        unsigned int soft_nmi_irqs;
index 45a839a7c6cfa609d60f197d81929c06c664ee49..cc07c399306e56d79abfa0c93366ba3ce48ba54d 100644 (file)
@@ -225,6 +225,7 @@ struct paca_struct {
        u16 in_mce;
        u8 hmi_event_available;         /* HMI event is available */
        u8 hmi_p9_special_emu;          /* HMI P9 special emulation */
+       u32 hmi_irqs;                   /* HMI irq stat */
 #endif
        u8 ftrace_enabled;              /* Hard disable ftrace */
 
index 05b1cc0e009e43f755ceba40b01b59e7921b7956..bf21ebd36190057ca460f5b8c696d7f968664d6d 100644 (file)
@@ -621,13 +621,14 @@ int arch_show_interrupts(struct seq_file *p, int prec)
                seq_printf(p, "%10u ", per_cpu(irq_stat, j).mce_exceptions);
        seq_printf(p, "  Machine check exceptions\n");
 
+#ifdef CONFIG_PPC_BOOK3S_64
        if (cpu_has_feature(CPU_FTR_HVMODE)) {
                seq_printf(p, "%*s: ", prec, "HMI");
                for_each_online_cpu(j)
-                       seq_printf(p, "%10u ",
-                                       per_cpu(irq_stat, j).hmi_exceptions);
+                       seq_printf(p, "%10u ", paca_ptrs[j]->hmi_irqs);
                seq_printf(p, "  Hypervisor Maintenance Interrupts\n");
        }
+#endif
 
        seq_printf(p, "%*s: ", prec, "NMI");
        for_each_online_cpu(j)
@@ -665,7 +666,9 @@ u64 arch_irq_stat_cpu(unsigned int cpu)
        sum += per_cpu(irq_stat, cpu).mce_exceptions;
        sum += per_cpu(irq_stat, cpu).spurious_irqs;
        sum += per_cpu(irq_stat, cpu).timer_irqs_others;
-       sum += per_cpu(irq_stat, cpu).hmi_exceptions;
+#ifdef CONFIG_PPC_BOOK3S_64
+       sum += paca_ptrs[cpu]->hmi_irqs;
+#endif
        sum += per_cpu(irq_stat, cpu).sreset_irqs;
 #ifdef CONFIG_PPC_WATCHDOG
        sum += per_cpu(irq_stat, cpu).soft_nmi_irqs;
index c2fa8ee63720e354402a623a0556c49b848f571f..ada59f6c4298f496ad9e44d0096112e1206ac151 100644 (file)
@@ -727,7 +727,7 @@ long hmi_exception_realmode(struct pt_regs *regs)
 {      
        int ret;
 
-       __this_cpu_inc(irq_stat.hmi_exceptions);
+       local_paca->hmi_irqs++;
 
        ret = hmi_handle_debugtrig(regs);
        if (ret >= 0)
index 79f7d07ef674c849e9d0dd75a1ddab72111def60..6028628ea3acf02504801fed7ad5feaae8201ece 100644 (file)
@@ -244,7 +244,7 @@ long kvmppc_realmode_hmi_handler(void)
 {
        bool resync_req;
 
-       __this_cpu_inc(irq_stat.hmi_exceptions);
+       local_paca->hmi_irqs++;
 
        if (hmi_handle_debugtrig(NULL) >= 0)
                return 1;