aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/include/asm/setup.h2
-rw-r--r--arch/s390/kernel/crash_dump.c2
-rw-r--r--arch/s390/kernel/early.c1
-rw-r--r--arch/s390/kernel/setup.c2
-rw-r--r--arch/s390/mm/mem_detect.c23
5 files changed, 23 insertions, 7 deletions
diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h
index 270fcd0fbf1a..2765e40d8739 100644
--- a/arch/s390/include/asm/setup.h
+++ b/arch/s390/include/asm/setup.h
@@ -46,7 +46,7 @@ extern struct mem_chunk memory_chunk[];
46extern int memory_end_set; 46extern int memory_end_set;
47extern unsigned long memory_end; 47extern unsigned long memory_end;
48 48
49void detect_memory_layout(struct mem_chunk chunk[]); 49void detect_memory_layout(struct mem_chunk chunk[], unsigned long maxsize);
50void create_mem_hole(struct mem_chunk memory_chunk[], unsigned long addr, 50void create_mem_hole(struct mem_chunk memory_chunk[], unsigned long addr,
51 unsigned long size, int type); 51 unsigned long size, int type);
52 52
diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c
index fb8d8781a011..30b7f63aa4e8 100644
--- a/arch/s390/kernel/crash_dump.c
+++ b/arch/s390/kernel/crash_dump.c
@@ -88,7 +88,7 @@ static struct mem_chunk *get_memory_layout(void)
88 struct mem_chunk *chunk_array; 88 struct mem_chunk *chunk_array;
89 89
90 chunk_array = kzalloc_panic(MEMORY_CHUNKS * sizeof(struct mem_chunk)); 90 chunk_array = kzalloc_panic(MEMORY_CHUNKS * sizeof(struct mem_chunk));
91 detect_memory_layout(chunk_array); 91 detect_memory_layout(chunk_array, 0);
92 create_mem_hole(chunk_array, OLDMEM_BASE, OLDMEM_SIZE, CHUNK_CRASHK); 92 create_mem_hole(chunk_array, OLDMEM_BASE, OLDMEM_SIZE, CHUNK_CRASHK);
93 return chunk_array; 93 return chunk_array;
94} 94}
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index bda011e2f8ae..dc8770d7173c 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -482,7 +482,6 @@ void __init startup_init(void)
482 detect_machine_facilities(); 482 detect_machine_facilities();
483 setup_topology(); 483 setup_topology();
484 sclp_facilities_detect(); 484 sclp_facilities_detect();
485 detect_memory_layout(memory_chunk);
486#ifdef CONFIG_DYNAMIC_FTRACE 485#ifdef CONFIG_DYNAMIC_FTRACE
487 S390_lowcore.ftrace_func = (unsigned long)ftrace_caller; 486 S390_lowcore.ftrace_func = (unsigned long)ftrace_caller;
488#endif 487#endif
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 555f1895972e..cdd9ec0a6fc0 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -1066,7 +1066,7 @@ void __init setup_arch(char **cmdline_p)
1066 memcpy(&uaccess, &uaccess_std, sizeof(uaccess)); 1066 memcpy(&uaccess, &uaccess_std, sizeof(uaccess));
1067 1067
1068 parse_early_param(); 1068 parse_early_param();
1069 1069 detect_memory_layout(memory_chunk, memory_end);
1070 os_info_init(); 1070 os_info_init();
1071 setup_ipl(); 1071 setup_ipl();
1072 reserve_oldmem(); 1072 reserve_oldmem();
diff --git a/arch/s390/mm/mem_detect.c b/arch/s390/mm/mem_detect.c
index 854c08448de1..ec00576bf8d5 100644
--- a/arch/s390/mm/mem_detect.c
+++ b/arch/s390/mm/mem_detect.c
@@ -12,7 +12,7 @@
12 12
13#define ADDR2G (1ULL << 31) 13#define ADDR2G (1ULL << 31)
14 14
15static void find_memory_chunks(struct mem_chunk chunk[]) 15static void find_memory_chunks(struct mem_chunk chunk[], unsigned long maxsize)
16{ 16{
17 unsigned long long memsize, rnmax, rzm; 17 unsigned long long memsize, rnmax, rzm;
18 unsigned long addr = 0, size; 18 unsigned long addr = 0, size;
@@ -27,6 +27,8 @@ static void find_memory_chunks(struct mem_chunk chunk[])
27 rzm = min(ADDR2G, rzm); 27 rzm = min(ADDR2G, rzm);
28 memsize = memsize ? min(ADDR2G, memsize) : ADDR2G; 28 memsize = memsize ? min(ADDR2G, memsize) : ADDR2G;
29 } 29 }
30 if (maxsize)
31 memsize = memsize ? min((unsigned long)memsize, maxsize) : maxsize;
30 do { 32 do {
31 size = 0; 33 size = 0;
32 type = tprot(addr); 34 type = tprot(addr);
@@ -36,6 +38,8 @@ static void find_memory_chunks(struct mem_chunk chunk[])
36 break; 38 break;
37 } while (type == tprot(addr + size)); 39 } while (type == tprot(addr + size));
38 if (type == CHUNK_READ_WRITE || type == CHUNK_READ_ONLY) { 40 if (type == CHUNK_READ_WRITE || type == CHUNK_READ_ONLY) {
41 if (memsize && (addr + size > memsize))
42 size = memsize - addr;
39 chunk[i].addr = addr; 43 chunk[i].addr = addr;
40 chunk[i].size = size; 44 chunk[i].size = size;
41 chunk[i].type = type; 45 chunk[i].type = type;
@@ -45,7 +49,20 @@ static void find_memory_chunks(struct mem_chunk chunk[])
45 } while (addr < memsize && i < MEMORY_CHUNKS); 49 } while (addr < memsize && i < MEMORY_CHUNKS);
46} 50}
47 51
48void detect_memory_layout(struct mem_chunk chunk[]) 52/**
53 * detect_memory_layout - fill mem_chunk array with memory layout data
54 * @chunk: mem_chunk array to be filled
55 * @maxsize: maximum address where memory detection should stop
56 *
57 * Fills the passed in memory chunk array with the memory layout of the
58 * machine. The array must have a size of at least MEMORY_CHUNKS and will
59 * be fully initialized afterwards.
60 * If the maxsize paramater has a value > 0 memory detection will stop at
61 * that address. It is guaranteed that all chunks have an ending address
62 * that is smaller than maxsize.
63 * If maxsize is 0 all memory will be detected.
64 */
65void detect_memory_layout(struct mem_chunk chunk[], unsigned long maxsize)
49{ 66{
50 unsigned long flags, flags_dat, cr0; 67 unsigned long flags, flags_dat, cr0;
51 68
@@ -69,7 +86,7 @@ void detect_memory_layout(struct mem_chunk chunk[])
69 } 86 }
70 __ctl_store(cr0, 0, 0); 87 __ctl_store(cr0, 0, 0);
71 __ctl_clear_bit(0, 28); 88 __ctl_clear_bit(0, 28);
72 find_memory_chunks(chunk); 89 find_memory_chunks(chunk, maxsize);
73 __ctl_load(cr0, 0, 0); 90 __ctl_load(cr0, 0, 0);
74out: 91out:
75 __arch_local_irq_ssm(flags_dat); 92 __arch_local_irq_ssm(flags_dat);