1c1cc1552SCatalin Marinas /* 2c1cc1552SCatalin Marinas * Based on arch/arm/mm/init.c 3c1cc1552SCatalin Marinas * 4c1cc1552SCatalin Marinas * Copyright (C) 1995-2005 Russell King 5c1cc1552SCatalin Marinas * Copyright (C) 2012 ARM Ltd. 6c1cc1552SCatalin Marinas * 7c1cc1552SCatalin Marinas * This program is free software; you can redistribute it and/or modify 8c1cc1552SCatalin Marinas * it under the terms of the GNU General Public License version 2 as 9c1cc1552SCatalin Marinas * published by the Free Software Foundation. 10c1cc1552SCatalin Marinas * 11c1cc1552SCatalin Marinas * This program is distributed in the hope that it will be useful, 12c1cc1552SCatalin Marinas * but WITHOUT ANY WARRANTY; without even the implied warranty of 13c1cc1552SCatalin Marinas * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14c1cc1552SCatalin Marinas * GNU General Public License for more details. 15c1cc1552SCatalin Marinas * 16c1cc1552SCatalin Marinas * You should have received a copy of the GNU General Public License 17c1cc1552SCatalin Marinas * along with this program. If not, see <http://www.gnu.org/licenses/>. 18c1cc1552SCatalin Marinas */ 19c1cc1552SCatalin Marinas 20c1cc1552SCatalin Marinas #include <linux/kernel.h> 21c1cc1552SCatalin Marinas #include <linux/export.h> 22c1cc1552SCatalin Marinas #include <linux/errno.h> 23c1cc1552SCatalin Marinas #include <linux/swap.h> 24c1cc1552SCatalin Marinas #include <linux/init.h> 25c1cc1552SCatalin Marinas #include <linux/bootmem.h> 26c1cc1552SCatalin Marinas #include <linux/mman.h> 27c1cc1552SCatalin Marinas #include <linux/nodemask.h> 28c1cc1552SCatalin Marinas #include <linux/initrd.h> 29c1cc1552SCatalin Marinas #include <linux/gfp.h> 30c1cc1552SCatalin Marinas #include <linux/memblock.h> 31c1cc1552SCatalin Marinas #include <linux/sort.h> 32c1cc1552SCatalin Marinas #include <linux/of_fdt.h> 3319e7640dSCatalin Marinas #include <linux/dma-mapping.h> 346ac2104dSLaura Abbott #include <linux/dma-contiguous.h> 3586c8b27aSLeif Lindholm #include <linux/efi.h> 36a1e50a82SCatalin Marinas #include <linux/swiotlb.h> 37c1cc1552SCatalin Marinas 3808375198SCatalin Marinas #include <asm/fixmap.h> 39aa03c428SMark Rutland #include <asm/memory.h> 40c1cc1552SCatalin Marinas #include <asm/sections.h> 41c1cc1552SCatalin Marinas #include <asm/setup.h> 42c1cc1552SCatalin Marinas #include <asm/sizes.h> 43c1cc1552SCatalin Marinas #include <asm/tlb.h> 44e039ee4eSAndre Przywara #include <asm/alternative.h> 45c1cc1552SCatalin Marinas 46c1cc1552SCatalin Marinas #include "mm.h" 47c1cc1552SCatalin Marinas 48c1cc1552SCatalin Marinas phys_addr_t memstart_addr __read_mostly = 0; 49a1e50a82SCatalin Marinas phys_addr_t arm64_dma_phys_limit __read_mostly; 50c1cc1552SCatalin Marinas 51ec2eaa73SRob Herring #ifdef CONFIG_BLK_DEV_INITRD 52c1cc1552SCatalin Marinas static int __init early_initrd(char *p) 53c1cc1552SCatalin Marinas { 54c1cc1552SCatalin Marinas unsigned long start, size; 55c1cc1552SCatalin Marinas char *endp; 56c1cc1552SCatalin Marinas 57c1cc1552SCatalin Marinas start = memparse(p, &endp); 58c1cc1552SCatalin Marinas if (*endp == ',') { 59c1cc1552SCatalin Marinas size = memparse(endp + 1, NULL); 60c1cc1552SCatalin Marinas 61ec2eaa73SRob Herring initrd_start = (unsigned long)__va(start); 62ec2eaa73SRob Herring initrd_end = (unsigned long)__va(start + size); 63c1cc1552SCatalin Marinas } 64c1cc1552SCatalin Marinas return 0; 65c1cc1552SCatalin Marinas } 66c1cc1552SCatalin Marinas early_param("initrd", early_initrd); 67ec2eaa73SRob Herring #endif 68c1cc1552SCatalin Marinas 69d50314a6SCatalin Marinas /* 70d50314a6SCatalin Marinas * Return the maximum physical address for ZONE_DMA (DMA_BIT_MASK(32)). It 71d50314a6SCatalin Marinas * currently assumes that for memory starting above 4G, 32-bit devices will 72d50314a6SCatalin Marinas * use a DMA offset. 73d50314a6SCatalin Marinas */ 74d50314a6SCatalin Marinas static phys_addr_t max_zone_dma_phys(void) 75d50314a6SCatalin Marinas { 76d50314a6SCatalin Marinas phys_addr_t offset = memblock_start_of_DRAM() & GENMASK_ULL(63, 32); 77d50314a6SCatalin Marinas return min(offset + (1ULL << 32), memblock_end_of_DRAM()); 78d50314a6SCatalin Marinas } 79d50314a6SCatalin Marinas 80c1cc1552SCatalin Marinas static void __init zone_sizes_init(unsigned long min, unsigned long max) 81c1cc1552SCatalin Marinas { 82c1cc1552SCatalin Marinas struct memblock_region *reg; 83c1cc1552SCatalin Marinas unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES]; 8419e7640dSCatalin Marinas unsigned long max_dma = min; 85c1cc1552SCatalin Marinas 86c1cc1552SCatalin Marinas memset(zone_size, 0, sizeof(zone_size)); 87c1cc1552SCatalin Marinas 88c1cc1552SCatalin Marinas /* 4GB maximum for 32-bit only capable devices */ 89*86a5906eSRobin Murphy #ifdef CONFIG_ZONE_DMA 90a1e50a82SCatalin Marinas max_dma = PFN_DOWN(arm64_dma_phys_limit); 9119e7640dSCatalin Marinas zone_size[ZONE_DMA] = max_dma - min; 92*86a5906eSRobin Murphy #endif 9319e7640dSCatalin Marinas zone_size[ZONE_NORMAL] = max - max_dma; 94c1cc1552SCatalin Marinas 95c1cc1552SCatalin Marinas memcpy(zhole_size, zone_size, sizeof(zhole_size)); 96c1cc1552SCatalin Marinas 97c1cc1552SCatalin Marinas for_each_memblock(memory, reg) { 98c1cc1552SCatalin Marinas unsigned long start = memblock_region_memory_base_pfn(reg); 99c1cc1552SCatalin Marinas unsigned long end = memblock_region_memory_end_pfn(reg); 100c1cc1552SCatalin Marinas 101c1cc1552SCatalin Marinas if (start >= max) 102c1cc1552SCatalin Marinas continue; 10319e7640dSCatalin Marinas 104*86a5906eSRobin Murphy #ifdef CONFIG_ZONE_DMA 105*86a5906eSRobin Murphy if (start < max_dma) { 10619e7640dSCatalin Marinas unsigned long dma_end = min(end, max_dma); 10719e7640dSCatalin Marinas zhole_size[ZONE_DMA] -= dma_end - start; 108c1cc1552SCatalin Marinas } 109*86a5906eSRobin Murphy #endif 11019e7640dSCatalin Marinas if (end > max_dma) { 111c1cc1552SCatalin Marinas unsigned long normal_end = min(end, max); 11219e7640dSCatalin Marinas unsigned long normal_start = max(start, max_dma); 113c1cc1552SCatalin Marinas zhole_size[ZONE_NORMAL] -= normal_end - normal_start; 114c1cc1552SCatalin Marinas } 115c1cc1552SCatalin Marinas } 116c1cc1552SCatalin Marinas 117c1cc1552SCatalin Marinas free_area_init_node(0, zone_size, min, zhole_size); 118c1cc1552SCatalin Marinas } 119c1cc1552SCatalin Marinas 120c1cc1552SCatalin Marinas #ifdef CONFIG_HAVE_ARCH_PFN_VALID 121c1cc1552SCatalin Marinas int pfn_valid(unsigned long pfn) 122c1cc1552SCatalin Marinas { 123c1cc1552SCatalin Marinas return memblock_is_memory(pfn << PAGE_SHIFT); 124c1cc1552SCatalin Marinas } 125c1cc1552SCatalin Marinas EXPORT_SYMBOL(pfn_valid); 126c1cc1552SCatalin Marinas #endif 127c1cc1552SCatalin Marinas 128c1cc1552SCatalin Marinas #ifndef CONFIG_SPARSEMEM 129c1cc1552SCatalin Marinas static void arm64_memory_present(void) 130c1cc1552SCatalin Marinas { 131c1cc1552SCatalin Marinas } 132c1cc1552SCatalin Marinas #else 133c1cc1552SCatalin Marinas static void arm64_memory_present(void) 134c1cc1552SCatalin Marinas { 135c1cc1552SCatalin Marinas struct memblock_region *reg; 136c1cc1552SCatalin Marinas 137c1cc1552SCatalin Marinas for_each_memblock(memory, reg) 138c1cc1552SCatalin Marinas memory_present(0, memblock_region_memory_base_pfn(reg), 139c1cc1552SCatalin Marinas memblock_region_memory_end_pfn(reg)); 140c1cc1552SCatalin Marinas } 141c1cc1552SCatalin Marinas #endif 142c1cc1552SCatalin Marinas 1436083fe74SMark Rutland static phys_addr_t memory_limit = (phys_addr_t)ULLONG_MAX; 1446083fe74SMark Rutland 1456083fe74SMark Rutland /* 1466083fe74SMark Rutland * Limit the memory size that was specified via FDT. 1476083fe74SMark Rutland */ 1486083fe74SMark Rutland static int __init early_mem(char *p) 1496083fe74SMark Rutland { 1506083fe74SMark Rutland if (!p) 1516083fe74SMark Rutland return 1; 1526083fe74SMark Rutland 1536083fe74SMark Rutland memory_limit = memparse(p, &p) & PAGE_MASK; 1546083fe74SMark Rutland pr_notice("Memory limited to %lldMB\n", memory_limit >> 20); 1556083fe74SMark Rutland 1566083fe74SMark Rutland return 0; 1576083fe74SMark Rutland } 1586083fe74SMark Rutland early_param("mem", early_mem); 1596083fe74SMark Rutland 160c1cc1552SCatalin Marinas void __init arm64_memblock_init(void) 161c1cc1552SCatalin Marinas { 1626083fe74SMark Rutland memblock_enforce_memory_limit(memory_limit); 1636083fe74SMark Rutland 164bd00cd5fSMark Rutland /* 165bd00cd5fSMark Rutland * Register the kernel text, kernel data, initrd, and initial 166bd00cd5fSMark Rutland * pagetables with memblock. 167bd00cd5fSMark Rutland */ 168c1cc1552SCatalin Marinas memblock_reserve(__pa(_text), _end - _text); 169c1cc1552SCatalin Marinas #ifdef CONFIG_BLK_DEV_INITRD 170ec2eaa73SRob Herring if (initrd_start) 171ec2eaa73SRob Herring memblock_reserve(__virt_to_phys(initrd_start), initrd_end - initrd_start); 172c1cc1552SCatalin Marinas #endif 173c1cc1552SCatalin Marinas 1749bf14b7cSMarek Szyprowski early_init_fdt_scan_reserved_mem(); 1752d5a5612SCatalin Marinas 1762d5a5612SCatalin Marinas /* 4GB maximum for 32-bit only capable devices */ 1772d5a5612SCatalin Marinas if (IS_ENABLED(CONFIG_ZONE_DMA)) 178a1e50a82SCatalin Marinas arm64_dma_phys_limit = max_zone_dma_phys(); 179a1e50a82SCatalin Marinas else 180a1e50a82SCatalin Marinas arm64_dma_phys_limit = PHYS_MASK + 1; 181a1e50a82SCatalin Marinas dma_contiguous_reserve(arm64_dma_phys_limit); 1826ac2104dSLaura Abbott 183c1cc1552SCatalin Marinas memblock_allow_resize(); 184c1cc1552SCatalin Marinas memblock_dump_all(); 185c1cc1552SCatalin Marinas } 186c1cc1552SCatalin Marinas 187c1cc1552SCatalin Marinas void __init bootmem_init(void) 188c1cc1552SCatalin Marinas { 189c1cc1552SCatalin Marinas unsigned long min, max; 190c1cc1552SCatalin Marinas 191c1cc1552SCatalin Marinas min = PFN_UP(memblock_start_of_DRAM()); 192c1cc1552SCatalin Marinas max = PFN_DOWN(memblock_end_of_DRAM()); 193c1cc1552SCatalin Marinas 19436dd9086SVladimir Murzin early_memtest(min << PAGE_SHIFT, max << PAGE_SHIFT); 19536dd9086SVladimir Murzin 196c1cc1552SCatalin Marinas /* 197c1cc1552SCatalin Marinas * Sparsemem tries to allocate bootmem in memory_present(), so must be 198c1cc1552SCatalin Marinas * done after the fixed reservations. 199c1cc1552SCatalin Marinas */ 200c1cc1552SCatalin Marinas arm64_memory_present(); 201c1cc1552SCatalin Marinas 202c1cc1552SCatalin Marinas sparse_init(); 203c1cc1552SCatalin Marinas zone_sizes_init(min, max); 204c1cc1552SCatalin Marinas 205c1cc1552SCatalin Marinas high_memory = __va((max << PAGE_SHIFT) - 1) + 1; 206c1cc1552SCatalin Marinas max_pfn = max_low_pfn = max; 207c1cc1552SCatalin Marinas } 208c1cc1552SCatalin Marinas 209c1cc1552SCatalin Marinas #ifndef CONFIG_SPARSEMEM_VMEMMAP 210c1cc1552SCatalin Marinas static inline void free_memmap(unsigned long start_pfn, unsigned long end_pfn) 211c1cc1552SCatalin Marinas { 212c1cc1552SCatalin Marinas struct page *start_pg, *end_pg; 213c1cc1552SCatalin Marinas unsigned long pg, pgend; 214c1cc1552SCatalin Marinas 215c1cc1552SCatalin Marinas /* 216c1cc1552SCatalin Marinas * Convert start_pfn/end_pfn to a struct page pointer. 217c1cc1552SCatalin Marinas */ 218c1cc1552SCatalin Marinas start_pg = pfn_to_page(start_pfn - 1) + 1; 219c1cc1552SCatalin Marinas end_pg = pfn_to_page(end_pfn - 1) + 1; 220c1cc1552SCatalin Marinas 221c1cc1552SCatalin Marinas /* 222c1cc1552SCatalin Marinas * Convert to physical addresses, and round start upwards and end 223c1cc1552SCatalin Marinas * downwards. 224c1cc1552SCatalin Marinas */ 225c1cc1552SCatalin Marinas pg = (unsigned long)PAGE_ALIGN(__pa(start_pg)); 226c1cc1552SCatalin Marinas pgend = (unsigned long)__pa(end_pg) & PAGE_MASK; 227c1cc1552SCatalin Marinas 228c1cc1552SCatalin Marinas /* 229c1cc1552SCatalin Marinas * If there are free pages between these, free the section of the 230c1cc1552SCatalin Marinas * memmap array. 231c1cc1552SCatalin Marinas */ 232c1cc1552SCatalin Marinas if (pg < pgend) 233c1cc1552SCatalin Marinas free_bootmem(pg, pgend - pg); 234c1cc1552SCatalin Marinas } 235c1cc1552SCatalin Marinas 236c1cc1552SCatalin Marinas /* 237c1cc1552SCatalin Marinas * The mem_map array can get very big. Free the unused area of the memory map. 238c1cc1552SCatalin Marinas */ 239c1cc1552SCatalin Marinas static void __init free_unused_memmap(void) 240c1cc1552SCatalin Marinas { 241c1cc1552SCatalin Marinas unsigned long start, prev_end = 0; 242c1cc1552SCatalin Marinas struct memblock_region *reg; 243c1cc1552SCatalin Marinas 244c1cc1552SCatalin Marinas for_each_memblock(memory, reg) { 245c1cc1552SCatalin Marinas start = __phys_to_pfn(reg->base); 246c1cc1552SCatalin Marinas 247c1cc1552SCatalin Marinas #ifdef CONFIG_SPARSEMEM 248c1cc1552SCatalin Marinas /* 249c1cc1552SCatalin Marinas * Take care not to free memmap entries that don't exist due 250c1cc1552SCatalin Marinas * to SPARSEMEM sections which aren't present. 251c1cc1552SCatalin Marinas */ 252c1cc1552SCatalin Marinas start = min(start, ALIGN(prev_end, PAGES_PER_SECTION)); 253c1cc1552SCatalin Marinas #endif 254c1cc1552SCatalin Marinas /* 255c1cc1552SCatalin Marinas * If we had a previous bank, and there is a space between the 256c1cc1552SCatalin Marinas * current bank and the previous, free it. 257c1cc1552SCatalin Marinas */ 258c1cc1552SCatalin Marinas if (prev_end && prev_end < start) 259c1cc1552SCatalin Marinas free_memmap(prev_end, start); 260c1cc1552SCatalin Marinas 261c1cc1552SCatalin Marinas /* 262c1cc1552SCatalin Marinas * Align up here since the VM subsystem insists that the 263c1cc1552SCatalin Marinas * memmap entries are valid from the bank end aligned to 264c1cc1552SCatalin Marinas * MAX_ORDER_NR_PAGES. 265c1cc1552SCatalin Marinas */ 266b9bcc919SDave P Martin prev_end = ALIGN(__phys_to_pfn(reg->base + reg->size), 267c1cc1552SCatalin Marinas MAX_ORDER_NR_PAGES); 268c1cc1552SCatalin Marinas } 269c1cc1552SCatalin Marinas 270c1cc1552SCatalin Marinas #ifdef CONFIG_SPARSEMEM 271c1cc1552SCatalin Marinas if (!IS_ALIGNED(prev_end, PAGES_PER_SECTION)) 272c1cc1552SCatalin Marinas free_memmap(prev_end, ALIGN(prev_end, PAGES_PER_SECTION)); 273c1cc1552SCatalin Marinas #endif 274c1cc1552SCatalin Marinas } 275c1cc1552SCatalin Marinas #endif /* !CONFIG_SPARSEMEM_VMEMMAP */ 276c1cc1552SCatalin Marinas 277c1cc1552SCatalin Marinas /* 278c1cc1552SCatalin Marinas * mem_init() marks the free areas in the mem_map and tells us how much memory 279c1cc1552SCatalin Marinas * is free. This is done after various parts of the system have claimed their 280c1cc1552SCatalin Marinas * memory after the kernel image. 281c1cc1552SCatalin Marinas */ 282c1cc1552SCatalin Marinas void __init mem_init(void) 283c1cc1552SCatalin Marinas { 284a1e50a82SCatalin Marinas swiotlb_init(1); 285a1e50a82SCatalin Marinas 286a6583c7cSGanapatrao Kulkarni set_max_mapnr(pfn_to_page(max_pfn) - mem_map); 287c1cc1552SCatalin Marinas 288c1cc1552SCatalin Marinas #ifndef CONFIG_SPARSEMEM_VMEMMAP 289c1cc1552SCatalin Marinas free_unused_memmap(); 290c1cc1552SCatalin Marinas #endif 291bee4ebd1SJiang Liu /* this will put all unused low memory onto the freelists */ 2920c988534SJiang Liu free_all_bootmem(); 293c1cc1552SCatalin Marinas 2946879ea83SJiang Liu mem_init_print_info(NULL); 295c1cc1552SCatalin Marinas 296c1cc1552SCatalin Marinas #define MLK(b, t) b, t, ((t) - (b)) >> 10 297c1cc1552SCatalin Marinas #define MLM(b, t) b, t, ((t) - (b)) >> 20 29808375198SCatalin Marinas #define MLG(b, t) b, t, ((t) - (b)) >> 30 299c1cc1552SCatalin Marinas #define MLK_ROUNDUP(b, t) b, t, DIV_ROUND_UP(((t) - (b)), SZ_1K) 300c1cc1552SCatalin Marinas 301c1cc1552SCatalin Marinas pr_notice("Virtual kernel memory layout:\n" 302ee7f881bSLinus Walleij #ifdef CONFIG_KASAN 303ee7f881bSLinus Walleij " kasan : 0x%16lx - 0x%16lx (%6ld GB)\n" 304ee7f881bSLinus Walleij #endif 30508375198SCatalin Marinas " vmalloc : 0x%16lx - 0x%16lx (%6ld GB)\n" 306c1cc1552SCatalin Marinas #ifdef CONFIG_SPARSEMEM_VMEMMAP 30708375198SCatalin Marinas " vmemmap : 0x%16lx - 0x%16lx (%6ld GB maximum)\n" 30808375198SCatalin Marinas " 0x%16lx - 0x%16lx (%6ld MB actual)\n" 309c1cc1552SCatalin Marinas #endif 31008375198SCatalin Marinas " fixed : 0x%16lx - 0x%16lx (%6ld KB)\n" 311aa03c428SMark Rutland " PCI I/O : 0x%16lx - 0x%16lx (%6ld MB)\n" 312c1cc1552SCatalin Marinas " modules : 0x%16lx - 0x%16lx (%6ld MB)\n" 313c1cc1552SCatalin Marinas " memory : 0x%16lx - 0x%16lx (%6ld MB)\n" 31408375198SCatalin Marinas " .init : 0x%p" " - 0x%p" " (%6ld KB)\n" 31508375198SCatalin Marinas " .text : 0x%p" " - 0x%p" " (%6ld KB)\n" 31608375198SCatalin Marinas " .data : 0x%p" " - 0x%p" " (%6ld KB)\n", 317ee7f881bSLinus Walleij #ifdef CONFIG_KASAN 318ee7f881bSLinus Walleij MLG(KASAN_SHADOW_START, KASAN_SHADOW_END), 319ee7f881bSLinus Walleij #endif 32008375198SCatalin Marinas MLG(VMALLOC_START, VMALLOC_END), 321c1cc1552SCatalin Marinas #ifdef CONFIG_SPARSEMEM_VMEMMAP 32208375198SCatalin Marinas MLG((unsigned long)vmemmap, 32308375198SCatalin Marinas (unsigned long)vmemmap + VMEMMAP_SIZE), 324c1cc1552SCatalin Marinas MLM((unsigned long)virt_to_page(PAGE_OFFSET), 325c1cc1552SCatalin Marinas (unsigned long)virt_to_page(high_memory)), 326c1cc1552SCatalin Marinas #endif 32708375198SCatalin Marinas MLK(FIXADDR_START, FIXADDR_TOP), 328aa03c428SMark Rutland MLM(PCI_IO_START, PCI_IO_END), 329c1cc1552SCatalin Marinas MLM(MODULES_VADDR, MODULES_END), 330c1cc1552SCatalin Marinas MLM(PAGE_OFFSET, (unsigned long)high_memory), 331c1cc1552SCatalin Marinas MLK_ROUNDUP(__init_begin, __init_end), 332c1cc1552SCatalin Marinas MLK_ROUNDUP(_text, _etext), 333c1cc1552SCatalin Marinas MLK_ROUNDUP(_sdata, _edata)); 334c1cc1552SCatalin Marinas 335c1cc1552SCatalin Marinas #undef MLK 336c1cc1552SCatalin Marinas #undef MLM 337c1cc1552SCatalin Marinas #undef MLK_ROUNDUP 338c1cc1552SCatalin Marinas 339c1cc1552SCatalin Marinas /* 340c1cc1552SCatalin Marinas * Check boundaries twice: Some fundamental inconsistencies can be 341c1cc1552SCatalin Marinas * detected at build time already. 342c1cc1552SCatalin Marinas */ 343c1cc1552SCatalin Marinas #ifdef CONFIG_COMPAT 344c1cc1552SCatalin Marinas BUILD_BUG_ON(TASK_SIZE_32 > TASK_SIZE_64); 345c1cc1552SCatalin Marinas #endif 346c1cc1552SCatalin Marinas BUILD_BUG_ON(TASK_SIZE_64 > MODULES_VADDR); 347c1cc1552SCatalin Marinas BUG_ON(TASK_SIZE_64 > MODULES_VADDR); 348c1cc1552SCatalin Marinas 349bee4ebd1SJiang Liu if (PAGE_SIZE >= 16384 && get_num_physpages() <= 128) { 350c1cc1552SCatalin Marinas extern int sysctl_overcommit_memory; 351c1cc1552SCatalin Marinas /* 352c1cc1552SCatalin Marinas * On a machine this small we won't get anywhere without 353c1cc1552SCatalin Marinas * overcommit, so turn it on by default. 354c1cc1552SCatalin Marinas */ 355c1cc1552SCatalin Marinas sysctl_overcommit_memory = OVERCOMMIT_ALWAYS; 356c1cc1552SCatalin Marinas } 357c1cc1552SCatalin Marinas } 358c1cc1552SCatalin Marinas 359c1cc1552SCatalin Marinas void free_initmem(void) 360c1cc1552SCatalin Marinas { 361da141706SLaura Abbott fixup_init(); 3629af5b807SJiang Liu free_initmem_default(0); 363e039ee4eSAndre Przywara free_alternatives_memory(); 364c1cc1552SCatalin Marinas } 365c1cc1552SCatalin Marinas 366c1cc1552SCatalin Marinas #ifdef CONFIG_BLK_DEV_INITRD 367c1cc1552SCatalin Marinas 368662ba3dbSWang Long static int keep_initrd __initdata; 369c1cc1552SCatalin Marinas 370662ba3dbSWang Long void __init free_initrd_mem(unsigned long start, unsigned long end) 371c1cc1552SCatalin Marinas { 3720145058cSCatalin Marinas if (!keep_initrd) 3739af5b807SJiang Liu free_reserved_area((void *)start, (void *)end, 0, "initrd"); 374c1cc1552SCatalin Marinas } 375c1cc1552SCatalin Marinas 376c1cc1552SCatalin Marinas static int __init keepinitrd_setup(char *__unused) 377c1cc1552SCatalin Marinas { 378c1cc1552SCatalin Marinas keep_initrd = 1; 379c1cc1552SCatalin Marinas return 1; 380c1cc1552SCatalin Marinas } 381c1cc1552SCatalin Marinas 382c1cc1552SCatalin Marinas __setup("keepinitrd", keepinitrd_setup); 383c1cc1552SCatalin Marinas #endif 384