Skip to content

Commit 983f121

Browse files
Jinjie Ruanpalmer-dabbelt
Jinjie Ruan
authored andcommitted
RISC-V: Implement kgdb_roundup_cpus() to enable future NMI Roundup
Until now, the generic weak kgdb_roundup_cpus() has been used for kgdb on RISCV. A custom one allows to debug CPUs that are stuck with interrupts disabled with NMI support in the future. And using an IPI is better than the generic one since it avoids the potential situation described in the generic kgdb_call_nmi_hook(). As Andrew pointed out, once there is NMI support, we can easily extend this and the CPU backtrace support to use NMIs. After this patch, the kgdb test show that: # echo g > /proc/sysrq-trigger [2]kdb> btc btc: cpu status: Currently on cpu 2 Available cpus: 0-1(-), 2, 3(-) Stack traceback for pid 0 0xffffffff81c13a40 0 0 1 0 - 0xffffffff81c14510 swapper/0 CPU: 0 PID: 0 Comm: swapper/0 Not tainted 6.10.0-g3120273055b6-dirty #51 Hardware name: riscv-virtio,qemu (DT) Call Trace: [<ffffffff80006c48>] dump_backtrace+0x28/0x30 [<ffffffff80fceb38>] show_stack+0x38/0x44 [<ffffffff80fe6a04>] dump_stack_lvl+0x58/0x7a [<ffffffff80fe6a3e>] dump_stack+0x18/0x20 [<ffffffff801143fa>] kgdb_cpu_enter+0x682/0x6b2 [<ffffffff801144ca>] kgdb_nmicallback+0xa0/0xac [<ffffffff8000a392>] handle_IPI+0x9c/0x120 [<ffffffff800a2baa>] handle_percpu_devid_irq+0xa4/0x1e4 [<ffffffff8009cca8>] generic_handle_domain_irq+0x28/0x36 [<ffffffff800a9e5c>] ipi_mux_process+0xe8/0x110 [<ffffffff806e1e30>] imsic_handle_irq+0xf8/0x13a [<ffffffff8009cca8>] generic_handle_domain_irq+0x28/0x36 [<ffffffff806dff12>] riscv_intc_aia_irq+0x2e/0x40 [<ffffffff80fe6ab0>] handle_riscv_irq+0x54/0x86 [<ffffffff80ff2e4a>] call_on_irq_stack+0x32/0x40 Rebased on Ryo Takakura's "RISC-V: Enable IPI CPU Backtrace" patch. Signed-off-by: Jinjie Ruan <[email protected]> Reviewed-by: Andrew Jones <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent 8f1534e commit 983f121

File tree

1 file changed

+25
-2
lines changed

1 file changed

+25
-2
lines changed

arch/riscv/kernel/smp.c

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <linux/interrupt.h>
1414
#include <linux/module.h>
1515
#include <linux/kexec.h>
16+
#include <linux/kgdb.h>
1617
#include <linux/percpu.h>
1718
#include <linux/profile.h>
1819
#include <linux/smp.h>
@@ -35,6 +36,7 @@ enum ipi_message_type {
3536
IPI_IRQ_WORK,
3637
IPI_TIMER,
3738
IPI_CPU_BACKTRACE,
39+
IPI_KGDB_ROUNDUP,
3840
IPI_MAX
3941
};
4042

@@ -115,6 +117,7 @@ void arch_irq_work_raise(void)
115117

116118
static irqreturn_t handle_IPI(int irq, void *data)
117119
{
120+
unsigned int cpu = smp_processor_id();
118121
int ipi = irq - ipi_virq_base;
119122

120123
switch (ipi) {
@@ -128,7 +131,7 @@ static irqreturn_t handle_IPI(int irq, void *data)
128131
ipi_stop();
129132
break;
130133
case IPI_CPU_CRASH_STOP:
131-
ipi_cpu_crash_stop(smp_processor_id(), get_irq_regs());
134+
ipi_cpu_crash_stop(cpu, get_irq_regs());
132135
break;
133136
case IPI_IRQ_WORK:
134137
irq_work_run();
@@ -141,8 +144,11 @@ static irqreturn_t handle_IPI(int irq, void *data)
141144
case IPI_CPU_BACKTRACE:
142145
nmi_cpu_backtrace(get_irq_regs());
143146
break;
147+
case IPI_KGDB_ROUNDUP:
148+
kgdb_nmicallback(cpu, get_irq_regs());
149+
break;
144150
default:
145-
pr_warn("CPU%d: unhandled IPI%d\n", smp_processor_id(), ipi);
151+
pr_warn("CPU%d: unhandled IPI%d\n", cpu, ipi);
146152
break;
147153
}
148154

@@ -209,6 +215,7 @@ static const char * const ipi_names[] = {
209215
[IPI_IRQ_WORK] = "IRQ work interrupts",
210216
[IPI_TIMER] = "Timer broadcast interrupts",
211217
[IPI_CPU_BACKTRACE] = "CPU backtrace interrupts",
218+
[IPI_KGDB_ROUNDUP] = "KGDB roundup interrupts",
212219
};
213220

214221
void show_ipi_stats(struct seq_file *p, int prec)
@@ -339,3 +346,19 @@ void arch_trigger_cpumask_backtrace(const cpumask_t *mask, int exclude_cpu)
339346
{
340347
nmi_trigger_cpumask_backtrace(mask, exclude_cpu, riscv_backtrace_ipi);
341348
}
349+
350+
#ifdef CONFIG_KGDB
351+
void kgdb_roundup_cpus(void)
352+
{
353+
int this_cpu = raw_smp_processor_id();
354+
int cpu;
355+
356+
for_each_online_cpu(cpu) {
357+
/* No need to roundup ourselves */
358+
if (cpu == this_cpu)
359+
continue;
360+
361+
send_ipi_single(cpu, IPI_KGDB_ROUNDUP);
362+
}
363+
}
364+
#endif

0 commit comments

Comments
 (0)