diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2006-12-04 09:40:56 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2006-12-04 09:40:56 -0500 |
commit | 8b62bc9642300471737bc3b77b2a4a2ead46dedb (patch) | |
tree | 0e510eac55df04ad244b74149c1fd7b8cc75e5e4 | |
parent | ce26a8532fd062ccd3f3c589a4be269a2dc20f00 (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.S | 3 | ||||
-rw-r--r-- | arch/s390/kernel/head64.S | 4 | ||||
-rw-r--r-- | arch/s390/kernel/setup.c | 49 | ||||
-rw-r--r-- | include/asm-s390/pgtable.h | 15 |
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); | |||
62 | unsigned int console_mode = 0; | 62 | unsigned int console_mode = 0; |
63 | unsigned int console_devno = -1; | 63 | unsigned int console_devno = -1; |
64 | unsigned int console_irq = -1; | 64 | unsigned int console_irq = -1; |
65 | unsigned long memory_size = 0; | ||
66 | unsigned long machine_flags = 0; | 65 | unsigned long machine_flags = 0; |
67 | 66 | ||
68 | struct mem_chunk memory_chunk[MEMORY_CHUNKS]; | 67 | struct mem_chunk memory_chunk[MEMORY_CHUNKS]; |
@@ -486,6 +485,37 @@ setup_resources(void) | |||
486 | } | 485 | } |
487 | } | 486 | } |
488 | 487 | ||
488 | static 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 | |||
489 | static void __init | 519 | static void __init |
490 | setup_memory(void) | 520 | setup_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 | |