s390/mem_detect: handle online memory limit just once
authorVasily Gorbik <gor@linux.ibm.com>
Sat, 28 Jan 2023 22:55:04 +0000 (23:55 +0100)
committerHeiko Carstens <hca@linux.ibm.com>
Mon, 6 Feb 2023 10:13:54 +0000 (11:13 +0100)
Introduce mem_detect_truncate() to cut any online memory ranges above
established identity mapping size, so that mem_detect users wouldn't
have to do it over and over again.

Suggested-by: Alexander Gordeev <agordeev@linux.ibm.com>
Reviewed-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
arch/s390/boot/boot.h
arch/s390/boot/kaslr.c
arch/s390/boot/mem_detect.c
arch/s390/boot/startup.c
arch/s390/boot/vmem.c
arch/s390/kernel/setup.c
arch/s390/mm/kasan_init.c

index 939d27da8fbd24fb990d07712035d85572089126..e91bbb004efb20296e9eced33c08337ac102f5f7 100644 (file)
@@ -34,6 +34,7 @@ struct vmlinux_info {
 
 void startup_kernel(void);
 unsigned long detect_memory(unsigned long *safe_addr);
+void mem_detect_truncate(unsigned long limit);
 bool is_ipl_block_dump(void);
 void store_ipl_parmblock(void);
 unsigned long read_ipl_report(unsigned long safe_addr);
@@ -44,7 +45,7 @@ void print_missing_facilities(void);
 void sclp_early_setup_buffer(void);
 void print_pgm_check_info(void);
 unsigned long get_random_base(unsigned long safe_addr);
-void setup_vmem(unsigned long ident_map_size, unsigned long asce_limit);
+void setup_vmem(unsigned long asce_limit);
 void __printf(1, 2) decompressor_printk(const char *fmt, ...);
 void error(char *m);
 
index 58a8d8c8a10079305efebc4208d57961a7133a2f..bbf6860ebc45009ca5202be763a7f8bb781475d3 100644 (file)
@@ -176,8 +176,6 @@ unsigned long get_random_base(unsigned long safe_addr)
        unsigned long base_pos, max_pos, kernel_size;
        int i;
 
-       memory_limit = min(memory_limit, ident_map_size);
-
        /*
         * Avoid putting kernel in the end of physical memory
         * which kasan will use for shadow memory and early pgtable
index daa15931718359302f57e2f05022bcf80170305f..3058d397a9da40ed636f190a6dda88772b68c4c8 100644 (file)
@@ -171,3 +171,21 @@ unsigned long detect_memory(unsigned long *safe_addr)
 
        return max_physmem_end;
 }
+
+void mem_detect_truncate(unsigned long limit)
+{
+       struct mem_detect_block *block;
+       int i;
+
+       for (i = 0; i < mem_detect.count; i++) {
+               block = __get_mem_detect_block_ptr(i);
+               if (block->start >= limit) {
+                       mem_detect.count = i;
+                       break;
+               } else if (block->end > limit) {
+                       block->end = (u64)limit;
+                       mem_detect.count = i + 1;
+                       break;
+               }
+       }
+}
index 577ebec9971b0c9e4bf4385241696c2cd4f3a9ec..89beb31e982a1a675812a4df9d2ad201abd96019 100644 (file)
@@ -305,6 +305,7 @@ void startup_kernel(void)
        setup_ident_map_size(max_physmem_end);
        setup_vmalloc_size();
        asce_limit = setup_kernel_memory_layout();
+       mem_detect_truncate(ident_map_size);
 
        if (IS_ENABLED(CONFIG_RANDOMIZE_BASE) && kaslr_enabled) {
                random_lma = get_random_base(safe_addr);
@@ -336,7 +337,7 @@ void startup_kernel(void)
         */
        clear_bss_section();
        handle_relocs(__kaslr_offset);
-       setup_vmem(ident_map_size, asce_limit);
+       setup_vmem(asce_limit);
        copy_bootdata();
 
        if (__kaslr_offset) {
index a35c251c91235e2da131d2c28e3710c409b0b2d8..82ef57827042df8850a9c55f0ed10ef31432d83c 100644 (file)
@@ -39,7 +39,7 @@ static void boot_check_oom(void)
                error("out of memory on boot\n");
 }
 
-static void pgtable_populate_init(unsigned long ident_map_size)
+static void pgtable_populate_init(void)
 {
        unsigned long initrd_end;
        unsigned long kernel_end;
@@ -51,7 +51,7 @@ static void pgtable_populate_init(unsigned long ident_map_size)
                pgalloc_low = max(pgalloc_low, initrd_end);
        }
 
-       pgalloc_end = round_down(min(ident_map_size, get_mem_detect_end()), PAGE_SIZE);
+       pgalloc_end = round_down(get_mem_detect_end(), PAGE_SIZE);
        pgalloc_pos = pgalloc_end;
 
        boot_check_oom();
@@ -226,7 +226,7 @@ static void pgtable_populate(unsigned long addr, unsigned long end, enum populat
        }
 }
 
-void setup_vmem(unsigned long ident_map_size, unsigned long asce_limit)
+void setup_vmem(unsigned long asce_limit)
 {
        unsigned long start, end;
        unsigned long asce_type;
@@ -250,13 +250,10 @@ void setup_vmem(unsigned long ident_map_size, unsigned long asce_limit)
         * To prevent creation of a large page at address 0 first map
         * the lowcore and create the identity mapping only afterwards.
         */
-       pgtable_populate_init(ident_map_size);
+       pgtable_populate_init();
        pgtable_populate(0, sizeof(struct lowcore), POPULATE_ONE2ONE);
-       for_each_mem_detect_block(i, &start, &end) {
-               if (start >= ident_map_size)
-                       break;
-               pgtable_populate(start, min(end, ident_map_size), POPULATE_ONE2ONE);
-       }
+       for_each_mem_detect_block(i, &start, &end)
+               pgtable_populate(start, end, POPULATE_ONE2ONE);
        pgtable_populate(__abs_lowcore, __abs_lowcore + sizeof(struct lowcore),
                         POPULATE_ABS_LOWCORE);
        pgtable_populate(__memcpy_real_area, __memcpy_real_area + PAGE_SIZE,
index 7fad2c02a7c3e15c56c90521f542e5e101aaa568..d8f41ccfe54e62680c22750f00004a34904cdcff 100644 (file)
@@ -600,7 +600,6 @@ static void __init setup_resources(void)
 
 static void __init setup_memory_end(void)
 {
-       memblock_remove(ident_map_size, PHYS_ADDR_MAX - ident_map_size);
        max_pfn = max_low_pfn = PFN_DOWN(ident_map_size);
        pr_notice("The maximum memory size is %luMB\n", ident_map_size >> 20);
 }
index 9d4f3138b0e7a259c3a47d2cbe173c051696c7e7..1aaea718af735f1d9e8820667d8de15ce424dbc5 100644 (file)
@@ -247,8 +247,6 @@ void __init kasan_early_init(void)
         * The rest [memsize, ident_map_size] if memsize < ident_map_size
         * could be mapped/unmapped dynamically later during memory hotplug.
         */
-       memsize = min(memsize, ident_map_size);
-
        BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_START, P4D_SIZE));
        BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, P4D_SIZE));