[S390] fix "mem=" handling in case of standby memory
authorHeiko Carstens <heiko.carstens@de.ibm.com>
Thu, 19 Feb 2009 14:19:01 +0000 (15:19 +0100)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Thu, 19 Feb 2009 14:19:19 +0000 (15:19 +0100)
Standby memory detected with the sclp interface gets always registered
with add_memory calls without considering the limitationt that the
"mem=" kernel paramater implies.
So fix this and only register standby memory that is below the specified
limit.
This fixes zfcpdump since it uses "mem=32M". In case there is appr.
2GB standby memory present all of usable memory would be used for the
struct pages needed for standby memory.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/include/asm/setup.h
arch/s390/kernel/setup.c
drivers/s390/char/sclp_cmd.c

index 2bd9faeb3919a0a3b7fae325769c3042db144d44..e8bd6ac22c996e40378654d7bdad1b9824ac826f 100644 (file)
@@ -43,6 +43,8 @@ struct mem_chunk {
 
 extern struct mem_chunk memory_chunk[];
 extern unsigned long real_memory_size;
+extern int memory_end_set;
+extern unsigned long memory_end;
 
 void detect_memory_layout(struct mem_chunk chunk[]);
 
index d825f4950e4e2f721e89de76fc98fe3dad91971b..c5cfb6185eaca51eb5e9ee3667d1c4d06ee22a52 100644 (file)
@@ -82,7 +82,9 @@ char elf_platform[ELF_PLATFORM_SIZE];
 
 struct mem_chunk __initdata memory_chunk[MEMORY_CHUNKS];
 volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */
-static unsigned long __initdata memory_end;
+
+int __initdata memory_end_set;
+unsigned long __initdata memory_end;
 
 /*
  * This is set up by the setup-routine at boot-time
@@ -281,6 +283,7 @@ void (*pm_power_off)(void) = machine_power_off;
 static int __init early_parse_mem(char *p)
 {
        memory_end = memparse(p, &p);
+       memory_end_set = 1;
        return 0;
 }
 early_param("mem", early_parse_mem);
@@ -508,8 +511,10 @@ static void __init setup_memory_end(void)
        int i;
 
 #if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE)
-       if (ipl_info.type == IPL_TYPE_FCP_DUMP)
+       if (ipl_info.type == IPL_TYPE_FCP_DUMP) {
                memory_end = ZFCPDUMP_HSA_SIZE;
+               memory_end_set = 1;
+       }
 #endif
        memory_size = 0;
        memory_end &= PAGE_MASK;
index 506390496416ea1163d12919042a6f0d0d34df34..77ab6e34a100b758bc3047888e78f1962a90146d 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/memory.h>
 #include <asm/chpid.h>
 #include <asm/sclp.h>
+#include <asm/setup.h>
 
 #include "sclp.h"
 
@@ -474,6 +475,10 @@ static void __init add_memory_merged(u16 rn)
                goto skip_add;
        if (start + size > VMEM_MAX_PHYS)
                size = VMEM_MAX_PHYS - start;
+       if (memory_end_set && (start >= memory_end))
+               goto skip_add;
+       if (memory_end_set && (start + size > memory_end))
+               size = memory_end - start;
        add_memory(0, start, size);
 skip_add:
        first_rn = rn;