| From 314dad22e3206eabc97acf04a6f81753d30e0520 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 15 Oct 2021 21:49:23 +0200 |
| Subject: parisc/kgdb: add kgdb_roundup() to make kgdb work with idle polling |
| |
| From: Sven Schnelle <svens@stackframe.org> |
| |
| [ Upstream commit 66e29fcda1824f0427966fbee2bd2c85bf362c82 ] |
| |
| With idle polling, IPIs are not sent when a CPU idle, but queued |
| and run later from do_idle(). The default kgdb_call_nmi_hook() |
| implementation gets the pointer to struct pt_regs from get_irq_reqs(), |
| which doesn't work in that case because it was not called from the |
| IPI interrupt handler. Fix it by defining our own kgdb_roundup() |
| function which sents an IPI_ENTER_KGDB. When that IPI is received |
| on the target CPU kgdb_nmicallback() is called. |
| |
| Signed-off-by: Sven Schnelle <svens@stackframe.org> |
| Signed-off-by: Helge Deller <deller@gmx.de> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| arch/parisc/kernel/smp.c | 19 +++++++++++++++++-- |
| 1 file changed, 17 insertions(+), 2 deletions(-) |
| |
| diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c |
| index e202c37e56af3..9997465c11820 100644 |
| --- a/arch/parisc/kernel/smp.c |
| +++ b/arch/parisc/kernel/smp.c |
| @@ -29,6 +29,7 @@ |
| #include <linux/bitops.h> |
| #include <linux/ftrace.h> |
| #include <linux/cpu.h> |
| +#include <linux/kgdb.h> |
| |
| #include <linux/atomic.h> |
| #include <asm/current.h> |
| @@ -71,7 +72,10 @@ enum ipi_message_type { |
| IPI_CALL_FUNC, |
| IPI_CPU_START, |
| IPI_CPU_STOP, |
| - IPI_CPU_TEST |
| + IPI_CPU_TEST, |
| +#ifdef CONFIG_KGDB |
| + IPI_ENTER_KGDB, |
| +#endif |
| }; |
| |
| |
| @@ -169,7 +173,12 @@ ipi_interrupt(int irq, void *dev_id) |
| case IPI_CPU_TEST: |
| smp_debug(100, KERN_DEBUG "CPU%d is alive!\n", this_cpu); |
| break; |
| - |
| +#ifdef CONFIG_KGDB |
| + case IPI_ENTER_KGDB: |
| + smp_debug(100, KERN_DEBUG "CPU%d ENTER_KGDB\n", this_cpu); |
| + kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs()); |
| + break; |
| +#endif |
| default: |
| printk(KERN_CRIT "Unknown IPI num on CPU%d: %lu\n", |
| this_cpu, which); |
| @@ -225,6 +234,12 @@ send_IPI_allbutself(enum ipi_message_type op) |
| } |
| } |
| |
| +#ifdef CONFIG_KGDB |
| +void kgdb_roundup_cpus(void) |
| +{ |
| + send_IPI_allbutself(IPI_ENTER_KGDB); |
| +} |
| +#endif |
| |
| inline void |
| smp_send_stop(void) { send_IPI_allbutself(IPI_CPU_STOP); } |
| -- |
| 2.33.0 |
| |