#include <linux/list.h>
#include <linux/linkage.h>
#include <linux/compat.h>
+#include <linux/ioport.h>
#include <asm/kexec.h>
/* Verify architecture specific macros are defined */
extern char __initramfs_start[], __initramfs_end[];
#ifdef CONFIG_BLK_DEV_INITRD
#include <linux/initrd.h>
+#include <linux/kexec.h>
static void __init free_initrd(void)
{
- free_initrd_mem(initrd_start, initrd_end);
+#ifdef CONFIG_KEXEC
+ unsigned long crashk_start = (unsigned long)__va(crashk_res.start);
+ unsigned long crashk_end = (unsigned long)__va(crashk_res.end);
+
+ /*
+ * 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);
+
initrd_start = 0;
initrd_end = 0;
}