Skip to content

Commit b17d19a

Browse files
guoren83palmer-dabbelt
authored andcommitted
riscv: kexec: Fixup irq controller broken in kexec crash path
If a crash happens on cpu3 and all interrupts are binding on cpu0, the bad irq routing will cause a crash kernel which can't receive any irq. Because crash kernel won't clean up all harts' PLIC enable bits in enable registers. This patch is similar to 9141a00 ("ARM: 7316/1: kexec: EOI active and mask all interrupts in kexec crash path") and 78fd584 ("arm64: kdump: implement machine_crash_shutdown()"), and PowerPC also has the same mechanism. Fixes: fba8a86 ("RISC-V: Add kexec support") Signed-off-by: Guo Ren <[email protected]> Signed-off-by: Guo Ren <[email protected]> Reviewed-by: Xianting Tian <[email protected]> Cc: Nick Kossifidis <[email protected]> Cc: Palmer Dabbelt <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent 9abf231 commit b17d19a

File tree

1 file changed

+35
-0
lines changed

1 file changed

+35
-0
lines changed

arch/riscv/kernel/machine_kexec.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#include <linux/compiler.h> /* For unreachable() */
1616
#include <linux/cpu.h> /* For cpu_down() */
1717
#include <linux/reboot.h>
18+
#include <linux/interrupt.h>
19+
#include <linux/irq.h>
1820

1921
/*
2022
* kexec_image_info - Print received image details
@@ -154,6 +156,37 @@ void crash_smp_send_stop(void)
154156
cpus_stopped = 1;
155157
}
156158

159+
static void machine_kexec_mask_interrupts(void)
160+
{
161+
unsigned int i;
162+
struct irq_desc *desc;
163+
164+
for_each_irq_desc(i, desc) {
165+
struct irq_chip *chip;
166+
int ret;
167+
168+
chip = irq_desc_get_chip(desc);
169+
if (!chip)
170+
continue;
171+
172+
/*
173+
* First try to remove the active state. If this
174+
* fails, try to EOI the interrupt.
175+
*/
176+
ret = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false);
177+
178+
if (ret && irqd_irq_inprogress(&desc->irq_data) &&
179+
chip->irq_eoi)
180+
chip->irq_eoi(&desc->irq_data);
181+
182+
if (chip->irq_mask)
183+
chip->irq_mask(&desc->irq_data);
184+
185+
if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
186+
chip->irq_disable(&desc->irq_data);
187+
}
188+
}
189+
157190
/*
158191
* machine_crash_shutdown - Prepare to kexec after a kernel crash
159192
*
@@ -169,6 +202,8 @@ machine_crash_shutdown(struct pt_regs *regs)
169202
crash_smp_send_stop();
170203

171204
crash_save_cpu(regs, smp_processor_id());
205+
machine_kexec_mask_interrupts();
206+
172207
pr_info("Starting crashdump kernel...\n");
173208
}
174209

0 commit comments

Comments
 (0)