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/include/asm/irq.h b/arch/arm64/include/asm/irq.h index ab4d006a223c093118423720e38e0daa607dec13..9e5f1c3a61d74a792b8da0b4d9be079a0755e0da 100644 --- a/arch/arm64/include/asm/irq.h +++ b/arch/arm64/include/asm/irq.h @@ -6,7 +6,7 @@ #include -#ifdef CONFIG_SMP +#if defined(CONFIG_SMP) && defined(CONFIG_IPI_AS_NMI) extern bool arch_trigger_cpumask_backtrace(const cpumask_t *mask, int exclude_cpu); #define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index 31859e7741a5bb5eed868a9b4fff843348523a1c..905bb8a14a900cd66c4fec95295a01a43dae4227 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -34,7 +34,7 @@ obj-y := debug-monitors.o entry.o irq.o fpsimd.o \ cpufeature.o alternative.o cacheinfo.o \ smp.o smp_spin_table.o topology.o smccc-call.o \ syscall.o proton-pack.o idreg-override.o idle.o \ - patching.o ipi_nmi.o + patching.o obj-$(CONFIG_AARCH32_EL0) += binfmt_elf32.o sys32.o signal32.o \ sys_compat.o @@ -79,6 +79,7 @@ obj-y += vdso-wrap.o obj-$(CONFIG_COMPAT_VDSO) += vdso32-wrap.o obj-$(CONFIG_ARM64_ILP32) += vdso-ilp32/ obj-$(CONFIG_UNWIND_PATCH_PAC_INTO_SCS) += patch-scs.o +obj-$(CONFIG_IPI_AS_NMI) += ipi_nmi.o CFLAGS_patch-scs.o += -mbranch-protection=none # Force dependency (vdso*-wrap.S includes vdso.so through incbin) 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/kgdb.h b/include/linux/kgdb.h index f28bea121891a3d70b4e0ac19cdcba1f251bb512..e5eb98b320bddf5afb3c864fb9914c50a3130540 100644 --- a/include/linux/kgdb.h +++ b/include/linux/kgdb.h @@ -199,6 +199,7 @@ kgdb_arch_handle_qxfer_pkt(char *remcom_in_buffer, extern void kgdb_call_nmi_hook(void *ignored); +#ifdef CONFIG_IPI_AS_NMI /** * kgdb_smp_call_nmi_hook - Provide default fallback mechanism to * round-up CPUs @@ -210,6 +211,7 @@ extern void kgdb_call_nmi_hook(void *ignored); */ extern void kgdb_smp_call_nmi_hook(void); +#endif /** * kgdb_roundup_cpus - Get other CPUs into a holding pattern diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c index 46aa536205bc88de26123b1bf5899883b422c9af..d0eb4b85b3903045897c55fc95fe6296cbda47c1 100644 --- a/kernel/debug/debug_core.c +++ b/kernel/debug/debug_core.c @@ -238,7 +238,11 @@ NOKPROBE_SYMBOL(kgdb_call_nmi_hook); static DEFINE_PER_CPU(call_single_data_t, kgdb_roundup_csd) = CSD_INIT(kgdb_call_nmi_hook, NULL); +#ifdef CONFIG_IPI_AS_NMI void kgdb_smp_call_nmi_hook(void) +#else +void __weak kgdb_roundup_cpus(void) +#endif { call_single_data_t *csd; int this_cpu = raw_smp_processor_id(); @@ -269,12 +273,14 @@ void kgdb_smp_call_nmi_hook(void) kgdb_info[cpu].rounding_up = false; } } +#ifdef CONFIG_IPI_AS_NMI NOKPROBE_SYMBOL(kgdb_smp_call_nmi_hook); void __weak kgdb_roundup_cpus(void) { kgdb_smp_call_nmi_hook(); } +#endif NOKPROBE_SYMBOL(kgdb_roundup_cpus); #endif