summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2011-08-24 19:15:09 +0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2011-08-24 19:15:23 +0400
commit27e7318c3e47e4fac71fcb472623434063ccc7a5 (patch)
tree32dce32a4ec1c036093880c28157a77253041f6e
parent14c62e78dc1379185515be41903c4a667efc6d54 (diff)
downloadlinux-27e7318c3e47e4fac71fcb472623434063ccc7a5.tar.xz
[S390] nss,initrd: kernel image and initrd must be in different segments
When IPL'ing from a block device and an NSS should be created we must make sure that the kernel image and the initrd are in different 1MB segments. Otherwise creating the NSS will fail. So we make sure the initrd is 4MB behind the end of the kernel image like we do already when IPL via the VM reader is performed. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--arch/s390/kernel/early.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index 068f8465c4ee..f297456dba7a 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -396,17 +396,19 @@ static __init void detect_machine_facilities(void)
static __init void rescue_initrd(void)
{
#ifdef CONFIG_BLK_DEV_INITRD
+ unsigned long min_initrd_addr = (unsigned long) _end + (4UL << 20);
/*
- * Move the initrd right behind the bss section in case it starts
- * within the bss section. So we don't overwrite it when the bss
- * section gets cleared.
+ * Just like in case of IPL from VM reader we make sure there is a
+ * gap of 4MB between end of kernel and start of initrd.
+ * That way we can also be sure that saving an NSS will succeed,
+ * which however only requires different segments.
*/
if (!INITRD_START || !INITRD_SIZE)
return;
- if (INITRD_START >= (unsigned long) __bss_stop)
+ if (INITRD_START >= min_initrd_addr)
return;
- memmove(__bss_stop, (void *) INITRD_START, INITRD_SIZE);
- INITRD_START = (unsigned long) __bss_stop;
+ memmove((void *) min_initrd_addr, (void *) INITRD_START, INITRD_SIZE);
+ INITRD_START = min_initrd_addr;
#endif
}