kexec does not disable the outer cache before disabling the inner caches in cpu_proc_fin(). So L2 is enabled across the kexec jump. When the new kernel enables chaches again, it randomly crashes. Disabling L2 before calling cpu_proc_fin() cures the problem. Add a disable function to the outer_cache_fns struct and call it before calling cpu_proc_fin(). Signed-off-by: Thomas Gleixner Index: linux-2.6/arch/arm/include/asm/outercache.h =================================================================== --- linux-2.6.orig/arch/arm/include/asm/outercache.h +++ linux-2.6/arch/arm/include/asm/outercache.h @@ -28,6 +28,7 @@ struct outer_cache_fns { #ifdef CONFIG_OUTER_CACHE_SYNC void (*sync)(void); #endif + void (*disable)(void); }; #ifdef CONFIG_OUTER_CACHE @@ -50,6 +51,12 @@ static inline void outer_flush_range(uns outer_cache.flush_range(start, end); } +static inline void outer_cache_disable(void) +{ + if (outer_cache.disable) + outer_cache.disable(); +} + #else static inline void outer_inv_range(unsigned long start, unsigned long end) @@ -58,6 +65,7 @@ static inline void outer_clean_range(uns { } static inline void outer_flush_range(unsigned long start, unsigned long end) { } +static inline void outer_cache_disable(void) { } #endif Index: linux-2.6/arch/arm/kernel/machine_kexec.c =================================================================== --- linux-2.6.orig/arch/arm/kernel/machine_kexec.c +++ linux-2.6/arch/arm/kernel/machine_kexec.c @@ -74,6 +74,7 @@ void machine_kexec(struct kimage *image) (unsigned long) reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE); printk(KERN_INFO "Bye!\n"); + outer_cache_disable(); cpu_proc_fin(); setup_mm_for_reboot(0); /* mode is not used, so just pass 0*/ cpu_reset(reboot_code_buffer_phys);