aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2006-12-04 09:40:56 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2006-12-04 09:40:56 -0500
commit8b62bc9642300471737bc3b77b2a4a2ead46dedb (patch)
tree0e510eac55df04ad244b74149c1fd7b8cc75e5e4
parentce26a8532fd062ccd3f3c589a4be269a2dc20f00 (diff)
[S390] Memory detection fixes.
VMALLOC_END on 31bit should be 0x8000000UL instead of 0x7fffffffL. The page mask which is used to make sure memory_end is on 4MB/2MB boundary is wrong and not needed. Therefore remove it. Make sure a vmalloc area does also exist and work on (future) machines with 4TB and more memory. 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/head31.S3
-rw-r--r--arch/s390/kernel/head64.S4
-rw-r--r--arch/s390/kernel/setup.c49
-rw-r--r--include/asm-s390/pgtable.h15
4 files changed, 44 insertions, 27 deletions
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S
index 9817c327aab1..4388b3309e0c 100644
--- a/arch/s390/kernel/head31.S
+++ b/arch/s390/kernel/head31.S
@@ -177,8 +177,6 @@ startup_continue:
177 st %r0,4(%r3) # store size of chunk 177 st %r0,4(%r3) # store size of chunk
178 st %r6,8(%r3) # store type of chunk 178 st %r6,8(%r3) # store type of chunk
179 la %r3,12(%r3) 179 la %r3,12(%r3)
180 l %r4,.Lmemsize-.LPG1(%r13) # address of variable memory_size
181 st %r5,0(%r4) # store last end to memory size
182 ahi %r10,-1 # update chunk number 180 ahi %r10,-1 # update chunk number
183.Lchkloop: 181.Lchkloop:
184 lr %r6,%r7 # set access code to last cc 182 lr %r6,%r7 # set access code to last cc
@@ -293,7 +291,6 @@ startup_continue:
293.Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg 291.Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg
294.Lpcidte:.long 0x00080000,0x80000000 + .Lchkidte 292.Lpcidte:.long 0x00080000,0x80000000 + .Lchkidte
295.Lpcdiag9c:.long 0x00080000,0x80000000 + .Lchkdiag9c 293.Lpcdiag9c:.long 0x00080000,0x80000000 + .Lchkdiag9c
296.Lmemsize:.long memory_size
297.Lmchunk:.long memory_chunk 294.Lmchunk:.long memory_chunk
298.Lmflags:.long machine_flags 295.Lmflags:.long machine_flags
299.Lbss_bgn: .long __bss_start 296.Lbss_bgn: .long __bss_start
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
index cc6dbc57eb90..c526279e1123 100644
--- a/arch/s390/kernel/head64.S
+++ b/arch/s390/kernel/head64.S
@@ -81,8 +81,6 @@ startup_continue:
81 aghi %r1,1 # size is one more than end 81 aghi %r1,1 # size is one more than end
82 larl %r2,memory_chunk 82 larl %r2,memory_chunk
83 stg %r1,8(%r2) # store size of chunk 83 stg %r1,8(%r2) # store size of chunk
84 larl %r2,memory_size
85 stg %r1,0(%r2) # set memory size
86 j .Ldonemem 84 j .Ldonemem
87 85
88.Lslowmemdetect: 86.Lslowmemdetect:
@@ -188,8 +186,6 @@ startup_continue:
188 stg %r0,8(%r3) # store size of chunk 186 stg %r0,8(%r3) # store size of chunk
189 st %r6,20(%r3) # store type of chunk 187 st %r6,20(%r3) # store type of chunk
190 la %r3,24(%r3) 188 la %r3,24(%r3)
191 larl %r8,memory_size
192 stg %r5,0(%r8) # store memory size
193 ahi %r10,-1 # update chunk number 189 ahi %r10,-1 # update chunk number
194.Lchkloop: 190.Lchkloop:
195 lr %r6,%r7 # set access code to last cc 191 lr %r6,%r7 # set access code to last cc
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index b1a8ad967f9c..b928fecdc743 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -62,7 +62,6 @@ EXPORT_SYMBOL_GPL(uaccess);
62unsigned int console_mode = 0; 62unsigned int console_mode = 0;
63unsigned int console_devno = -1; 63unsigned int console_devno = -1;
64unsigned int console_irq = -1; 64unsigned int console_irq = -1;
65unsigned long memory_size = 0;
66unsigned long machine_flags = 0; 65unsigned long machine_flags = 0;
67 66
68struct mem_chunk memory_chunk[MEMORY_CHUNKS]; 67struct mem_chunk memory_chunk[MEMORY_CHUNKS];
@@ -486,6 +485,37 @@ setup_resources(void)
486 } 485 }
487} 486}
488 487
488static void __init setup_memory_end(void)
489{
490 unsigned long real_size, memory_size;
491 unsigned long max_mem, max_phys;
492 int i;
493
494 memory_size = real_size = 0;
495 max_phys = VMALLOC_END - VMALLOC_MIN_SIZE;
496 memory_end &= PAGE_MASK;
497
498 max_mem = memory_end ? min(max_phys, memory_end) : max_phys;
499
500 for (i = 0; i < MEMORY_CHUNKS; i++) {
501 struct mem_chunk *chunk = &memory_chunk[i];
502
503 real_size = max(real_size, chunk->addr + chunk->size);
504 if (chunk->addr >= max_mem) {
505 memset(chunk, 0, sizeof(*chunk));
506 continue;
507 }
508 if (chunk->addr + chunk->size > max_mem)
509 chunk->size = max_mem - chunk->addr;
510 memory_size = max(memory_size, chunk->addr + chunk->size);
511 }
512 if (!memory_end)
513 memory_end = memory_size;
514 if (real_size > memory_end)
515 printk("More memory detected than supported. Unused: %luk\n",
516 (real_size - memory_end) >> 10);
517}
518
489static void __init 519static void __init
490setup_memory(void) 520setup_memory(void)
491{ 521{
@@ -642,8 +672,6 @@ setup_arch(char **cmdline_p)
642 init_mm.end_data = (unsigned long) &_edata; 672 init_mm.end_data = (unsigned long) &_edata;
643 init_mm.brk = (unsigned long) &_end; 673 init_mm.brk = (unsigned long) &_end;
644 674
645 memory_end = memory_size;
646
647 if (MACHINE_HAS_MVCOS) 675 if (MACHINE_HAS_MVCOS)
648 memcpy(&uaccess, &uaccess_mvcos, sizeof(uaccess)); 676 memcpy(&uaccess, &uaccess_mvcos, sizeof(uaccess));
649 else 677 else
@@ -651,20 +679,7 @@ setup_arch(char **cmdline_p)
651 679
652 parse_early_param(); 680 parse_early_param();
653 681
654#ifndef CONFIG_64BIT 682 setup_memory_end();
655 memory_end &= ~0x400000UL;
656
657 /*
658 * We need some free virtual space to be able to do vmalloc.
659 * On a machine with 2GB memory we make sure that we have at
660 * least 128 MB free space for vmalloc.
661 */
662 if (memory_end > 1920*1024*1024)
663 memory_end = 1920*1024*1024;
664#else /* CONFIG_64BIT */
665 memory_end &= ~0x200000UL;
666#endif /* CONFIG_64BIT */
667
668 setup_memory(); 683 setup_memory();
669 setup_resources(); 684 setup_resources();
670 setup_lowcore(); 685 setup_lowcore();
diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h
index 36bb6dacf008..2d968a69ed1f 100644
--- a/include/asm-s390/pgtable.h
+++ b/include/asm-s390/pgtable.h
@@ -110,13 +110,22 @@ extern char empty_zero_page[PAGE_SIZE];
110#define VMALLOC_OFFSET (8*1024*1024) 110#define VMALLOC_OFFSET (8*1024*1024)
111#define VMALLOC_START (((unsigned long) high_memory + VMALLOC_OFFSET) \ 111#define VMALLOC_START (((unsigned long) high_memory + VMALLOC_OFFSET) \
112 & ~(VMALLOC_OFFSET-1)) 112 & ~(VMALLOC_OFFSET-1))
113
114/*
115 * We need some free virtual space to be able to do vmalloc.
116 * VMALLOC_MIN_SIZE defines the minimum size of the vmalloc
117 * area. On a machine with 2GB memory we make sure that we
118 * have at least 128MB free space for vmalloc. On a machine
119 * with 4TB we make sure we have at least 1GB.
120 */
113#ifndef __s390x__ 121#ifndef __s390x__
114# define VMALLOC_END (0x7fffffffL) 122#define VMALLOC_MIN_SIZE 0x8000000UL
123#define VMALLOC_END 0x80000000UL
115#else /* __s390x__ */ 124#else /* __s390x__ */
116# define VMALLOC_END (0x40000000000L) 125#define VMALLOC_MIN_SIZE 0x40000000UL
126#define VMALLOC_END 0x40000000000UL
117#endif /* __s390x__ */ 127#endif /* __s390x__ */
118 128
119
120/* 129/*
121 * A 31 bit pagetable entry of S390 has following format: 130 * A 31 bit pagetable entry of S390 has following format:
122 * | PFRA | | OS | 131 * | PFRA | | OS |