diff options
Diffstat (limited to 'init')
-rw-r--r-- | init/initramfs.c | 53 |
1 files changed, 30 insertions, 23 deletions
diff --git a/init/initramfs.c b/init/initramfs.c index c322e1099f43..5fda9557a134 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -518,37 +518,35 @@ extern unsigned long __initramfs_size; #include <linux/initrd.h> #include <linux/kexec.h> -static void __init free_initrd(void) -{ #ifdef CONFIG_KEXEC_CORE +static bool kexec_free_initrd(void) +{ unsigned long crashk_start = (unsigned long)__va(crashk_res.start); unsigned long crashk_end = (unsigned long)__va(crashk_res.end); -#endif - if (do_retain_initrd) - goto skip; -#ifdef CONFIG_KEXEC_CORE /* * If the initrd region is overlapped with crashkernel reserved region, * free only memory that is not part of crashkernel region. */ - if (initrd_start < crashk_end && initrd_end > crashk_start) { - /* - * Initialize initrd memory region since the kexec boot does - * not do. - */ - memset((void *)initrd_start, 0, initrd_end - initrd_start); - if (initrd_start < crashk_start) - free_initrd_mem(initrd_start, crashk_start); - if (initrd_end > crashk_end) - free_initrd_mem(crashk_end, initrd_end); - } else -#endif - free_initrd_mem(initrd_start, initrd_end); -skip: - initrd_start = 0; - initrd_end = 0; + if (initrd_start >= crashk_end || initrd_end <= crashk_start) + return false; + + /* + * Initialize initrd memory region since the kexec boot does not do. + */ + memset((void *)initrd_start, 0, initrd_end - initrd_start); + if (initrd_start < crashk_start) + free_initrd_mem(initrd_start, crashk_start); + if (initrd_end > crashk_end) + free_initrd_mem(crashk_end, initrd_end); + return true; } +#else +static inline bool kexec_free_initrd(void) +{ + return false; +} +#endif /* CONFIG_KEXEC_CORE */ #ifdef CONFIG_BLK_DEV_RAM #define BUF_SIZE 1024 @@ -642,7 +640,16 @@ static int __init populate_rootfs(void) printk(KERN_EMERG "Initramfs unpacking failed: %s\n", err); #endif } - free_initrd(); + + /* + * If the initrd region is overlapped with crashkernel reserved region, + * free only memory that is not part of crashkernel region. + */ + if (!do_retain_initrd && !kexec_free_initrd()) + free_initrd_mem(initrd_start, initrd_end); + initrd_start = 0; + initrd_end = 0; + flush_delayed_fput(); return 0; } |