From 9c15e852a524d55ab768cf48c97f5c684f876af2 Mon Sep 17 00:00:00 2001 From: Haren Myneni Date: Fri, 10 Feb 2006 01:51:05 -0800 Subject: [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 Acked-by: "Eric W. Biederman" Cc: Vivek Goyal Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- init/initramfs.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'init') diff --git a/init/initramfs.c b/init/initramfs.c index 0c5d9a3f951..637344b0598 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) extern char __initramfs_start[], __initramfs_end[]; #ifdef CONFIG_BLK_DEV_INITRD #include +#include 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; } -- cgit v1.2.3 From 02df360bf38ca2acb78ddee9fd28262e9474153c Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 10 Feb 2006 01:51:06 -0800 Subject: [PATCH] remove bogus comment from init/main.c Remove bogus comment from init function which could lead to the assumption that cpu_possible_map is setup in smp_prepare_cpus(). Signed-off-by: Heiko Carstens Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- init/main.c | 1 - 1 file changed, 1 deletion(-) (limited to 'init') diff --git a/init/main.c b/init/main.c index 7c79da57d3a..4c194c47395 100644 --- a/init/main.c +++ b/init/main.c @@ -668,7 +668,6 @@ static int init(void * unused) */ child_reaper = current; - /* Sets up cpus_possible() */ smp_prepare_cpus(max_cpus); do_pre_smp_initcalls(); -- cgit v1.2.3