[PATCH v9 7/7] arm64: kgdb: Roundup cpus using the debug IPI

From: Douglas Anderson
Date: Thu Jun 01 2023 - 17:37:47 EST


From: Sumit Garg <sumit.garg@xxxxxxxxxx>

Let's use the debug IPI for rounding up CPUs in kgdb. When the debug
IPI is backed by an NMI (or pseudo NMI) then this will let us debug
even hard locked CPUs. When the debug IPI isn't backed by an NMI then
this won't really have any huge benefit but it will still work.

Signed-off-by: Sumit Garg <sumit.garg@xxxxxxxxxx>
Signed-off-by: Douglas Anderson <dianders@xxxxxxxxxxxx>
---

Changes in v9:
- Remove fallback for when debug IPI isn't available.
- Renamed "NMI IPI" to "debug IPI" since it might not be backed by NMI.

arch/arm64/kernel/ipi_debug.c | 5 +++++
arch/arm64/kernel/kgdb.c | 14 ++++++++++++++
2 files changed, 19 insertions(+)

diff --git a/arch/arm64/kernel/ipi_debug.c b/arch/arm64/kernel/ipi_debug.c
index 6984ed507e1f..5794894d94f1 100644
--- a/arch/arm64/kernel/ipi_debug.c
+++ b/arch/arm64/kernel/ipi_debug.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>

@@ -40,6 +41,7 @@ void arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self)
static irqreturn_t ipi_debug_handler(int irq, void *data)
{
irqreturn_t ret = IRQ_NONE;
+ unsigned int cpu = smp_processor_id();

/*
* NOTE: Just like in arch_trigger_cpumask_backtrace(), we're calling
@@ -49,6 +51,9 @@ static irqreturn_t ipi_debug_handler(int irq, void *data)
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..9c4c47507cd4 100644
--- a/arch/arm64/kernel/kgdb.c
+++ b/arch/arm64/kernel/kgdb.c
@@ -20,6 +20,8 @@
#include <asm/patching.h>
#include <asm/traps.h>

+#include "ipi_debug.h"
+
struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = {
{ "x0", 8, offsetof(struct pt_regs, regs[0])},
{ "x1", 8, offsetof(struct pt_regs, regs[1])},
@@ -356,3 +358,15 @@ 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;
+
+ cpumask_copy(&mask, cpu_online_mask);
+ cpumask_clear_cpu(raw_smp_processor_id(), &mask);
+ if (cpumask_empty(&mask))
+ return;
+
+ arm64_debug_ipi(&mask);
+}
--
2.41.0.rc2.161.g9c6817b8e7-goog