riscv: kexec: Fxiup crash_save percpu and machine_kexec_mask_interrupts
Subsystems (2)
v5 cover riscv: kexec: Fxiup crash_save percpu and machine_kexec_mask_interrupts
From: Guo Ren <[email protected]>
Current riscv kexec can't crash_save percpu states and disable interrupts properly. The patch series fix them, make kexec work correct.
Changlogs:
v5:
- Remove the patch which isn't relate to riscv
- Add fixup crash_smp_send_stop test result
v4:
https://lore.kernel.org/linux-riscv/[email protected]/
- Add cpu_ops[cpu]->cpu_stop() in ipi_cpu_crash_stop
- Wording optimization in comments
V3:
https://lore.kernel.org/linux-riscv/[email protected]/
- Fixup compile problem with !SMP, which reported by [email protected]
- Cleanup declarations in asm/smp.h
- Add reviewed-by
V2:
https://lore.kernel.org/linux-riscv/[email protected]/
- Add Fixes tags
- Remove extern from bool smp_crash_stop_failed(void)
V1:
https://lore.kernel.org/linux-riscv/[email protected]/
Guo Ren (2):
riscv: kexec: Fixup irq controller broken in kexec crash path
riscv: kexec: Fixup crash_smp_send_stop without multi cores
arch/riscv/include/asm/smp.h | 3 + arch/riscv/kernel/machine_kexec.c | 46 +++++++++++---- arch/riscv/kernel/smp.c | 97 ++++++++++++++++++++++++++++++- 3 files changed, 133 insertions(+), 13 deletions(-)
Signature · 1 line
2.36.1
PATCH v5 1/2 riscv: kexec: Fixup irq controller broken in kexec crash path
From: Guo Ren <[email protected]>
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 9141a003a491 ("ARM: 7316/1:
kexec: EOI active and mask all interrupts in kexec crash path") and 78fd584cdec0 ("arm64: kdump: implement machine_crash_shutdown()"), and PowerPC also has the same mechanism.
--- arch/riscv/kernel/machine_kexec.c | 35 +++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+)
arch/riscv/kernel/machine_kexec.c +35 -0
@@ -15,6 +15,8 @@#include <linux/compiler.h> /* For unreachable() */ #include <linux/cpu.h> /* For cpu_down() */ #include <linux/reboot.h> +#include <linux/interrupt.h> +#include <linux/irq.h> /* * kexec_image_info - Print received image details
@@ -154,6 +156,37 @@ void crash_smp_send_stop(void) cpus_stopped =1 ; } +static void machine_kexec_mask_interrupts (void ) +{ +unsigned int i; +struct irq_desc *desc; + +for_each_irq_desc (i, desc) { +struct irq_chip *chip; +int ret; + + chip =irq_desc_get_chip (desc); +if (!chip) +continue ; + +/* +* First try to remove the active state. If this +* fails, try to EOI the interrupt. +*/ + ret =irq_set_irqchip_state (i,IRQCHIP_STATE_ACTIVE , false); + +if (ret &&irqd_irq_inprogress (&desc->irq_data) && + chip->irq_eoi) + chip->irq_eoi (&desc->irq_data); + +if (chip->irq_mask) + chip->irq_mask (&desc->irq_data); + +if (chip->irq_disable && !irqd_irq_disabled (&desc->irq_data)) + chip->irq_disable (&desc->irq_data); + } +} +/* * machine_crash_shutdown - Prepare to kexec after a kernel crash *
@@ -169,6 +202,8 @@ machine_crash_shutdown(struct pt_regs *regs)crash_smp_send_stop ();crash_save_cpu (regs,smp_processor_id ()); +machine_kexec_mask_interrupts (); +pr_info ("Starting crashdump kernel...\n" ); }
Signature · 1 line
2.36.1
PATCH v5 2/2 riscv: kexec: Fixup crash_smp_send_stop without multi cores
In reply to [email protected]From: Guo Ren <[email protected]>
Current crash_smp_send_stop is the same as the generic one in kernel/panic and misses crash_save_cpu in percpu. This patch is inspired by 78fd584cdec0 ("arm64: kdump: implement machine_crash_shutdown()") and adds the same mechanism for riscv.
Before this patch, test result:
crash> help -r
CPU 0: [OFFLINE]
CPU 1:
epc : ffffffff80009ff0 ra : ffffffff800b789a sp : ff2000001098bb40
gp : ffffffff815fca60 tp : ff60000004680000 t0 : 6666666666663c5b t1 : 0000000000000000 t2 : 666666666666663c s0 : ff2000001098bc90 s1 : ffffffff81600798 a0 : ff2000001098bb48 a1 : 0000000000000000 a2 : 0000000000000000 a3 : 0000000000000001 a4 : 0000000000000000 a5 : ff60000004690800 a6 : 0000000000000000 a7 : 0000000000000000 s2 : ff2000001098bb48 s3 : ffffffff81093ec8 s4 : ffffffff816004ac s5 : 0000000000000000 s6 : 0000000000000007 s7 : ffffffff80e7f720 s8 : 00fffffffffff3f0 s9 : 0000000000000007 s10: 00aaaaaaaab98700
s11: 0000000000000001 t3 : ffffffff819a8097 t4 : ffffffff819a8097 t5 : ffffffff819a8098 t6 : ff2000001098b9a8
CPU 2: [OFFLINE]
CPU 3: [OFFLINE]
After this patch, test result:
crash> help -r
CPU 0:
epc : ffffffff80003f34 ra : ffffffff808caa7c sp : ffffffff81403eb0
gp : ffffffff815fcb48 tp : ffffffff81413400 t0 : 0000000000000000 t1 : 0000000000000000 t2 : 0000000000000000 s0 : ffffffff81403ec0 s1 : 0000000000000000 a0 : 0000000000000000 a1 : 0000000000000000 a2 : 0000000000000000 a3 : 0000000000000000 a4 : 0000000000000000 a5 : 0000000000000000 a6 : 0000000000000000 a7 : 0000000000000000 s2 : ffffffff816001c8 s3 : ffffffff81600370 s4 : ffffffff80c32e18 s5 : ffffffff819d3018 s6 : ffffffff810e2110 s7 : 0000000000000000 s8 : 0000000000000000 s9 : 0000000080039eac s10: 0000000000000000
s11: 0000000000000000 t3 : 0000000000000000 t4 : 0000000000000000 t5 : 0000000000000000 t6 : 0000000000000000
CPU 1:
epc : ffffffff80003f34 ra : ffffffff808caa7c sp : ff2000000068bf30
gp : ffffffff815fcb48 tp : ff6000000240d400 t0 : 0000000000000000 t1 : 0000000000000000 t2 : 0000000000000000 s0 : ff2000000068bf40 s1 : 0000000000000001 a0 : 0000000000000000 a1 : 0000000000000000 a2 : 0000000000000000 a3 : 0000000000000000 a4 : 0000000000000000 a5 : 0000000000000000 a6 : 0000000000000000 a7 : 0000000000000000 s2 : ffffffff816001c8 s3 : ffffffff81600370 s4 : ffffffff80c32e18 s5 : ffffffff819d3018 s6 : ffffffff810e2110 s7 : 0000000000000000 s8 : 0000000000000000 s9 : 0000000080039ea8 s10: 0000000000000000
s11: 0000000000000000 t3 : 0000000000000000 t4 : 0000000000000000 t5 : 0000000000000000 t6 : 0000000000000000
CPU 2:
epc : ffffffff80003f34 ra : ffffffff808caa7c sp : ff20000000693f30
gp : ffffffff815fcb48 tp : ff6000000240e900 t0 : 0000000000000000 t1 : 0000000000000000 t2 : 0000000000000000 s0 : ff20000000693f40 s1 : 0000000000000002 a0 : 0000000000000000 a1 : 0000000000000000 a2 : 0000000000000000 a3 : 0000000000000000 a4 : 0000000000000000 a5 : 0000000000000000 a6 : 0000000000000000 a7 : 0000000000000000 s2 : ffffffff816001c8 s3 : ffffffff81600370 s4 : ffffffff80c32e18 s5 : ffffffff819d3018 s6 : ffffffff810e2110 s7 : 0000000000000000 s8 : 0000000000000000 s9 : 0000000080039eb0 s10: 0000000000000000
s11: 0000000000000000 t3 : 0000000000000000 t4 : 0000000000000000 t5 : 0000000000000000 t6 : 0000000000000000
CPU 3:
epc : ffffffff8000a1e4 ra : ffffffff800b7bba sp : ff200000109bbb40
gp : ffffffff815fcb48 tp : ff6000000373aa00 t0 : 6666666666663c5b t1 : 0000000000000000 t2 : 666666666666663c s0 : ff200000109bbc90 s1 : ffffffff816007a0 a0 : ff200000109bbb48 a1 : 0000000000000000 a2 : 0000000000000000 a3 : 0000000000000001 a4 : 0000000000000000 a5 : ff60000002c61c00 a6 : 0000000000000000 a7 : 0000000000000000 s2 : ff200000109bbb48 s3 : ffffffff810941a8 s4 : ffffffff816004b4 s5 : 0000000000000000 s6 : 0000000000000007 s7 : ffffffff80e7f7a0 s8 : 00fffffffffff3f0 s9 : 0000000000000007 s10: 00aaaaaaaab98700
s11: 0000000000000001 t3 : ffffffff819a8097 t4 : ffffffff819a8097 t5 : ffffffff819a8098 t6 : ff200000109bb9a8
--- arch/riscv/include/asm/smp.h | 3 + arch/riscv/kernel/machine_kexec.c | 21 ++----- arch/riscv/kernel/smp.c | 97 ++++++++++++++++++++++++++++++- 3 files changed, 103 insertions(+), 18 deletions(-)
arch/riscv/include/asm/smp.h +3 -0
@@ -50,6 +50,9 @@ void riscv_set_ipi_ops(const struct riscv_ipi_ops *ops);/* Clear IPI for current CPU */ void riscv_clear_ipi (void ); +/* Check other CPUs stop or not */ +bool smp_crash_stop_failed (void ); +/* Secondary hart entry */ asmlinkage void smp_callin(void);
arch/riscv/kernel/machine_kexec.c +5 -16
@@ -140,22 +140,6 @@ void machine_shutdown(void)#endif } -/* Override the weak function in kernel/panic.c */ -void crash_smp_send_stop (void ) -{ -static int cpus_stopped; - -/* -* This function can be called twice in panic path, but obviously -* we execute this only once. -*/ -if (cpus_stopped) -return ; - -smp_send_stop (); - cpus_stopped =1 ; -} -static void machine_kexec_mask_interrupts (void ) {unsigned int i;
@@ -230,6 +214,11 @@ machine_kexec(struct kimage *image)void *control_code_buffer =page_address (image->control_code_page);riscv_kexec_method kexec_method =NULL ; +#ifdef CONFIG_SMP +WARN (smp_crash_stop_failed (), +"Some CPUs may be stale, kdump will be unreliable.\n" ); +#endif +if (image->type !=KEXEC_TYPE_CRASH ) kexec_method = control_code_buffer;else
arch/riscv/kernel/smp.c +95 -2
144 lines not on this page · raw message
Signature · 1 line
2.36.1