s390/boot: Reduce size of identity mapping on overlap
authorAlexander Gordeev <agordeev@linux.ibm.com>
Tue, 11 Jul 2023 05:58:24 +0000 (07:58 +0200)
committerAlexander Gordeev <agordeev@linux.ibm.com>
Wed, 17 Apr 2024 11:37:59 +0000 (13:37 +0200)
In case vmemmap array could overlap with vmalloc area on
virtual memory layout setup, the size of vmalloc area
is decreased. That could result in less memory than user
requested with vmalloc= kernel command line parameter.
Instead, reduce the size of identity mapping (and the
size of vmemmap array as result) to avoid such overlap.

Further, currently the virtual memmory allocation "rolls"
from top to bottom and it is only VMALLOC_START that could
get increased due to the overlap. Change that to decrease-
only, which makes the whole allocation algorithm more easy
to comprehend.

Acked-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
arch/s390/boot/startup.c

index eee742b88cc89d64f87975e28972806928b940b6..069ecc81332f36ece8b4f460322d62750b9d8a89 100644 (file)
@@ -318,7 +318,10 @@ static unsigned long setup_kernel_memory_layout(void)
        ident_map_size = min(ident_map_size, vmemmap_start);
        vmemmap_size = SECTION_ALIGN_UP(ident_map_size / PAGE_SIZE) * sizeof(struct page);
        /* make sure vmemmap doesn't overlay with vmalloc area */
-       VMALLOC_START = max(vmemmap_start + vmemmap_size, VMALLOC_START);
+       if (vmemmap_start + vmemmap_size > VMALLOC_START) {
+               vmemmap_size = SECTION_ALIGN_DOWN(ident_map_size / PAGE_SIZE) * sizeof(struct page);
+               ident_map_size = vmemmap_size / sizeof(struct page) * PAGE_SIZE;
+       }
        vmemmap = (struct page *)vmemmap_start;
        /* maximum address for which linear mapping could be created (DCSS, memory) */
        BUILD_BUG_ON(MAX_DCSS_ADDR > (1UL << MAX_PHYSMEM_BITS));