From: Sumit Garg sumit.garg@linaro.org
maillist inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I8PLUM?from=project-issue CVE: NA Reference: https://lore.kernel.org/all/1604317487-14543-8-git-send-email-sumit.garg@lin...
-------------------------------------------------
arm64 platforms with GICv3 or later supports pseudo NMIs which can be leveraged to roundup CPUs which are stuck in hard lockup state with interrupts disabled that wouldn't be possible with a normal IPI.
So instead switch to roundup CPUs using IPI turned as NMI. And in case a particular arm64 platform doesn't supports pseudo NMIs, it will switch back to default kgdb CPUs roundup mechanism.
Signed-off-by: Sumit Garg sumit.garg@linaro.org Signed-off-by: Wei Li liwei391@huawei.com Reviewed-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Signed-off-by: Ruan Jinjie ruanjinjie@huawei.com Signed-off-by: Liao Chen liaochen4@huawei.com --- arch/arm64/kernel/ipi_nmi.c | 5 +++++ arch/arm64/kernel/kgdb.c | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+)
diff --git a/arch/arm64/kernel/ipi_nmi.c b/arch/arm64/kernel/ipi_nmi.c index d1053f1a4101..9249e8b100aa 100644 --- a/arch/arm64/kernel/ipi_nmi.c +++ b/arch/arm64/kernel/ipi_nmi.c @@ -8,6 +8,7 @@
#include <linux/interrupt.h> #include <linux/irq.h> +#include <linux/kgdb.h> #include <linux/nmi.h> #include <linux/smp.h>
@@ -45,10 +46,14 @@ bool arch_trigger_cpumask_backtrace(const cpumask_t *mask, int exclude_cpu) static irqreturn_t ipi_nmi_handler(int irq, void *data) { irqreturn_t ret = IRQ_NONE; + unsigned int cpu = smp_processor_id();
if (nmi_cpu_backtrace(get_irq_regs())) ret = IRQ_HANDLED;
+ if (!kgdb_nmicallback(cpu, get_irq_regs())) + ret = IRQ_HANDLED; + return ret; }
diff --git a/arch/arm64/kernel/kgdb.c b/arch/arm64/kernel/kgdb.c index 4e1f983df3d1..98d8c1027f06 100644 --- a/arch/arm64/kernel/kgdb.c +++ b/arch/arm64/kernel/kgdb.c @@ -17,6 +17,7 @@
#include <asm/debug-monitors.h> #include <asm/insn.h> +#include <asm/nmi.h> #include <asm/patching.h> #include <asm/traps.h>
@@ -356,3 +357,20 @@ int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt) return aarch64_insn_write((void *)bpt->bpt_addr, *(u32 *)bpt->saved_instr); } + +void kgdb_roundup_cpus(void) +{ + struct cpumask mask; + + if (!arm64_supports_nmi()) { + kgdb_smp_call_nmi_hook(); + return; + } + + cpumask_copy(&mask, cpu_online_mask); + cpumask_clear_cpu(raw_smp_processor_id(), &mask); + if (cpumask_empty(&mask)) + return; + + arm64_send_nmi(&mask); +}