Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc/64s: Move HMI IRQ stat from percpu variable to paca.

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

authored by

Mahesh Salgaonkar and committed by
Michael Ellerman
ada68a66 d3c61954

+9 -6
-1
arch/powerpc/include/asm/hardirq.h
··· 13 13 unsigned int pmu_irqs; 14 14 unsigned int mce_exceptions; 15 15 unsigned int spurious_irqs; 16 - unsigned int hmi_exceptions; 17 16 unsigned int sreset_irqs; 18 17 #ifdef CONFIG_PPC_WATCHDOG 19 18 unsigned int soft_nmi_irqs;
+1
arch/powerpc/include/asm/paca.h
··· 225 225 u16 in_mce; 226 226 u8 hmi_event_available; /* HMI event is available */ 227 227 u8 hmi_p9_special_emu; /* HMI P9 special emulation */ 228 + u32 hmi_irqs; /* HMI irq stat */ 228 229 #endif 229 230 u8 ftrace_enabled; /* Hard disable ftrace */ 230 231
+6 -3
arch/powerpc/kernel/irq.c
··· 621 621 seq_printf(p, "%10u ", per_cpu(irq_stat, j).mce_exceptions); 622 622 seq_printf(p, " Machine check exceptions\n"); 623 623 624 + #ifdef CONFIG_PPC_BOOK3S_64 624 625 if (cpu_has_feature(CPU_FTR_HVMODE)) { 625 626 seq_printf(p, "%*s: ", prec, "HMI"); 626 627 for_each_online_cpu(j) 627 - seq_printf(p, "%10u ", 628 - per_cpu(irq_stat, j).hmi_exceptions); 628 + seq_printf(p, "%10u ", paca_ptrs[j]->hmi_irqs); 629 629 seq_printf(p, " Hypervisor Maintenance Interrupts\n"); 630 630 } 631 + #endif 631 632 632 633 seq_printf(p, "%*s: ", prec, "NMI"); 633 634 for_each_online_cpu(j) ··· 666 665 sum += per_cpu(irq_stat, cpu).mce_exceptions; 667 666 sum += per_cpu(irq_stat, cpu).spurious_irqs; 668 667 sum += per_cpu(irq_stat, cpu).timer_irqs_others; 669 - sum += per_cpu(irq_stat, cpu).hmi_exceptions; 668 + #ifdef CONFIG_PPC_BOOK3S_64 669 + sum += paca_ptrs[cpu]->hmi_irqs; 670 + #endif 670 671 sum += per_cpu(irq_stat, cpu).sreset_irqs; 671 672 #ifdef CONFIG_PPC_WATCHDOG 672 673 sum += per_cpu(irq_stat, cpu).soft_nmi_irqs;
+1 -1
arch/powerpc/kernel/mce.c
··· 727 727 { 728 728 int ret; 729 729 730 - __this_cpu_inc(irq_stat.hmi_exceptions); 730 + local_paca->hmi_irqs++; 731 731 732 732 ret = hmi_handle_debugtrig(regs); 733 733 if (ret >= 0)
+1 -1
arch/powerpc/kvm/book3s_hv_ras.c
··· 244 244 { 245 245 bool resync_req; 246 246 247 - __this_cpu_inc(irq_stat.hmi_exceptions); 247 + local_paca->hmi_irqs++; 248 248 249 249 if (hmi_handle_debugtrig(NULL) >= 0) 250 250 return 1;