Instead of __flush_cache_all(), simply flush local icache range. In systems without IOCU, flushing system wide caches require sending IPIs. But other CPUs have disabled local IRQs waiting for the reboot signal. It will then cause system hang. This patch fixes this problem. Tested-by: Rachel Mozes <rachel.mozes@xxxxxxxxx> Reported-by: Rachel Mozes <rachel.mozes@xxxxxxxxx> Signed-off-by: Dengcheng Zhu <dzhu@xxxxxxxxxxxx> --- Changes: * Code style adjustments. arch/mips/kernel/machine_kexec.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/arch/mips/kernel/machine_kexec.c b/arch/mips/kernel/machine_kexec.c index 1679408..6e3f7c8 100644 --- a/arch/mips/kernel/machine_kexec.c +++ b/arch/mips/kernel/machine_kexec.c @@ -139,7 +139,16 @@ machine_kexec(struct kimage *image) printk("Will call new kernel at %08lx\n", image->start); printk("Bye ...\n"); - __flush_cache_all(); + /* + * __flush_cache_all() is expensive but unnecessary. More + * importantly, it could freeze the system as it may need to send + * IPIs, whereas other CPUs have been waiting for the reboot signal + * (kexec_ready_to_reboot) with local irqs disabled, because + * machine_crash_shutdown() has been called prior to entering + * this function - machine_kexec(). + */ + local_flush_icache_range(reboot_code_buffer, + reboot_code_buffer + relocate_new_kernel_size); #ifdef CONFIG_SMP atomic_set(&kexec_ready_to_reboot, 1); -- 2.7.4