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. Signed-off-by: Dengcheng Zhu <dzhu@xxxxxxxxxxxx> --- 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 48c06c2..294fae167 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