diff options
-rw-r--r-- | include/linux/kexec.h | 1 | ||||
-rw-r--r-- | init/initramfs.c | 24 |
2 files changed, 24 insertions, 1 deletions
diff --git a/include/linux/kexec.h b/include/linux/kexec.h index a311f58c8a7c..cfb3410e32b1 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <linux/list.h> | 6 | #include <linux/list.h> |
7 | #include <linux/linkage.h> | 7 | #include <linux/linkage.h> |
8 | #include <linux/compat.h> | 8 | #include <linux/compat.h> |
9 | #include <linux/ioport.h> | ||
9 | #include <asm/kexec.h> | 10 | #include <asm/kexec.h> |
10 | 11 | ||
11 | /* Verify architecture specific macros are defined */ | 12 | /* Verify architecture specific macros are defined */ |
diff --git a/init/initramfs.c b/init/initramfs.c index 0c5d9a3f951b..637344b05981 100644 --- a/init/initramfs.c +++ b/init/initramfs.c | |||
@@ -466,10 +466,32 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only) | |||
466 | extern char __initramfs_start[], __initramfs_end[]; | 466 | extern char __initramfs_start[], __initramfs_end[]; |
467 | #ifdef CONFIG_BLK_DEV_INITRD | 467 | #ifdef CONFIG_BLK_DEV_INITRD |
468 | #include <linux/initrd.h> | 468 | #include <linux/initrd.h> |
469 | #include <linux/kexec.h> | ||
469 | 470 | ||
470 | static void __init free_initrd(void) | 471 | static void __init free_initrd(void) |
471 | { | 472 | { |
472 | free_initrd_mem(initrd_start, initrd_end); | 473 | #ifdef CONFIG_KEXEC |
474 | unsigned long crashk_start = (unsigned long)__va(crashk_res.start); | ||
475 | unsigned long crashk_end = (unsigned long)__va(crashk_res.end); | ||
476 | |||
477 | /* | ||
478 | * If the initrd region is overlapped with crashkernel reserved region, | ||
479 | * free only memory that is not part of crashkernel region. | ||
480 | */ | ||
481 | if (initrd_start < crashk_end && initrd_end > crashk_start) { | ||
482 | /* | ||
483 | * Initialize initrd memory region since the kexec boot does | ||
484 | * not do. | ||
485 | */ | ||
486 | memset((void *)initrd_start, 0, initrd_end - initrd_start); | ||
487 | if (initrd_start < crashk_start) | ||
488 | free_initrd_mem(initrd_start, crashk_start); | ||
489 | if (initrd_end > crashk_end) | ||
490 | free_initrd_mem(crashk_end, initrd_end); | ||
491 | } else | ||
492 | #endif | ||
493 | free_initrd_mem(initrd_start, initrd_end); | ||
494 | |||
473 | initrd_start = 0; | 495 | initrd_start = 0; |
474 | initrd_end = 0; | 496 | initrd_end = 0; |
475 | } | 497 | } |