aboutsummaryrefslogtreecommitdiffstats
path: root/init/initramfs.c
diff options
context:
space:
mode:
authorHaren Myneni <haren@us.ibm.com>2006-02-10 04:51:05 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-02-10 11:13:12 -0500
commit9c15e852a524d55ab768cf48c97f5c684f876af2 (patch)
tree897cc70b792652599e7f135e4cb4aeff82a3f2b8 /init/initramfs.c
parentafcd024183d8a6eae7e489ce50b2485c5ae4f662 (diff)
[PATCH] kexec: fix in free initrd when overlapped with crashkernel region
It is possible that the reserved crashkernel region can be overlapped with initrd since the bootloader sets the initrd location. When the initrd region is freed, the second kernel memory will not be contiguous. The Kexec_load can cause an oops since there is no contiguous memory to write the second kernel or this memory could be used in the first kernel itself and may not be part of the dump. For example, on powerpc, the initrd is located at 36MB and the crashkernel starts at 32MB. The kexec_load caused panic since writing into non-allocated memory (after 36MB). We could see the similar issue even on other archs. One possibility is to move the initrd outside of crashkernel region. But, the initrd region will be freed anyway before the system is up. This patch fixes this issue and frees only regions that are not part of crashkernel memory in case overlaps. Signed-off-by: Haren Myneni <haren@us.ibm.com> Acked-by: "Eric W. Biederman" <ebiederm@xmission.com> Cc: Vivek Goyal <vgoyal@in.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'init/initramfs.c')
-rw-r--r--init/initramfs.c24
1 files changed, 23 insertions, 1 deletions
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)
466extern char __initramfs_start[], __initramfs_end[]; 466extern 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
470static void __init free_initrd(void) 471static 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}