diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 9568049f36e35518d2dfeb77eeefb02339063e7b..6275da6438ac574bb3f768a8d1217cbec3506ec5 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -2242,9 +2242,19 @@ config ARM64_DEBUG_PRIORITY_MASKING If unsure, say N endif # ARM64_PSEUDO_NMI +config IPI_AS_NMI + bool "Support ipi triggerred as pseudo nmi" + depends on ARM64_PSEUDO_NMI + default n + help + This adds support to trigger ipi as pseudo nmi, which allows to have an IPI + leveraged to invoke NMI functions on other CPUs. Current prospective users + are NMI backtrace and KGDB CPUs round-up whose support is added via future + patches. + config NON_NMI_IPI_BACKTRACE bool "Support non nmi ipi backtrace" - depends on ARM64_PSEUDO_NMI + depends on IPI_AS_NMI default n help This adds support for non nmi ipi backtrace, which allows hungtask_monitor diff --git a/arch/arm64/kernel/kgdb.c b/arch/arm64/kernel/kgdb.c index 98d8c1027f06c10b6b6c42d87b7d67812c8900d8..5d8b6efaab0eb1d3f57ee403f919d93e0555a42b 100644 --- a/arch/arm64/kernel/kgdb.c +++ b/arch/arm64/kernel/kgdb.c @@ -358,6 +358,7 @@ int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt) *(u32 *)bpt->saved_instr); } +#ifdef CONFIG_IPI_AS_NMI void kgdb_roundup_cpus(void) { struct cpumask mask; @@ -374,3 +375,4 @@ void kgdb_roundup_cpus(void) arm64_send_nmi(&mask); } +#endif diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 8288549ca5f77de0059db1836369bdc0a8aeab24..82c7f1524d154c2bb53c80255bea0392b0addd5d 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -937,7 +937,9 @@ static void ipi_setup(int cpu) for (i = 0; i < nr_ipi; i++) enable_percpu_irq(ipi_irq_base + i, 0); +#ifdef CONFIG_IPI_AS_NMI dynamic_ipi_setup(cpu); +#endif } #ifdef CONFIG_HOTPLUG_CPU @@ -951,7 +953,9 @@ static void ipi_teardown(int cpu) for (i = 0; i < nr_ipi; i++) disable_percpu_irq(ipi_irq_base + i); +#ifdef CONFIG_IPI_AS_NMI dynamic_ipi_teardown(cpu); +#endif } #endif @@ -973,8 +977,10 @@ void __init set_smp_ipi_range(int ipi_base, int n) irq_set_status_flags(ipi_base + i, IRQ_HIDDEN); } +#ifdef CONFIG_IPI_AS_NMI if (n > nr_ipi) set_smp_dynamic_ipi(ipi_base + nr_ipi); +#endif ipi_irq_base = ipi_base; diff --git a/include/linux/nmi.h b/include/linux/nmi.h index 692f2759be55bff58addc2d6efadff9878772b7a..787b3ca80bb0ee759255ad5b0c5d99b5d6f825a4 100644 --- a/include/linux/nmi.h +++ b/include/linux/nmi.h @@ -154,7 +154,7 @@ static inline void touch_nmi_watchdog(void) * base function. Return whether such support was available, * to allow calling code to fall back to some other mechanism: */ -#ifdef arch_trigger_cpumask_backtrace +#if defined(arch_trigger_cpumask_backtrace) static inline bool trigger_all_cpu_backtrace(void) { return arch_trigger_cpumask_backtrace(cpu_online_mask, -1);