diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h index 0152c040f6c3..fb703d120d09 100644 --- a/arch/sh/include/asm/page.h +++ b/arch/sh/include/asm/page.h @@ -49,7 +49,7 @@ extern unsigned long shm_align_mask; extern unsigned long max_low_pfn, min_low_pfn; -extern unsigned long memory_start, memory_end; +extern unsigned long memory_start, memory_end, memory_limit; static inline unsigned long pages_do_alias(unsigned long addr1, unsigned long addr2) diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c index f0f049caa6e2..7f68fc0e89e8 100644 --- a/arch/sh/kernel/machine_kexec.c +++ b/arch/sh/kernel/machine_kexec.c @@ -169,7 +169,8 @@ void __init reserve_crashkernel(void) crash_size = PAGE_ALIGN(crashk_res.end - crashk_res.start + 1); if (!crashk_res.start) { - crashk_res.start = lmb_alloc(crash_size, PAGE_SIZE); + unsigned long max = lmb_end_of_DRAM() - memory_limit; + crashk_res.start = __lmb_alloc_base(crash_size, PAGE_SIZE, max); if (!crashk_res.start) { pr_err("crashkernel allocation failed\n"); goto disable; @@ -183,15 +184,22 @@ void __init reserve_crashkernel(void) } } - pr_info("Reserving %ldMB of memory at %ldMB " + crashk_res.end = crashk_res.start + crash_size - 1; + + /* + * Crash kernel trumps memory limit + */ + if ((lmb_end_of_DRAM() - memory_limit) <= crashk_res.end) { + memory_limit = 0; + pr_info("Disabled memory limit for crashkernel\n"); + } + + pr_info("Reserving %ldMB of memory at 0x%08lx " "for crashkernel (System RAM: %ldMB)\n", (unsigned long)(crash_size >> 20), - (unsigned long)(crashk_res.start >> 20), + (unsigned long)(crashk_res.start), (unsigned long)(lmb_phys_mem_size() >> 20)); - crashk_res.end = crashk_res.start + crash_size - 1; - insert_resource(&iomem_resource, &crashk_res); - return; disable: diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 2c9ab2842765..f6a2db12ad78 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -95,6 +95,7 @@ unsigned long memory_start; EXPORT_SYMBOL(memory_start); unsigned long memory_end = 0; EXPORT_SYMBOL(memory_end); +unsigned long memory_limit = 0; static struct resource mem_resources[MAX_NUMNODES]; @@ -102,21 +103,12 @@ int l1i_cache_shape, l1d_cache_shape, l2_cache_shape; static int __init early_parse_mem(char *p) { - unsigned long size; + if (!p) + return 1; - memory_start = (unsigned long)__va(__MEMORY_START); - size = memparse(p, &p); + memory_limit = PAGE_ALIGN(memparse(p, &p)); - if (size > __MEMORY_SIZE) { - printk(KERN_ERR - "Using mem= to increase the size of kernel memory " - "is not allowed.\n" - " Recompile the kernel with the correct value for " - "CONFIG_MEMORY_SIZE.\n"); - return 0; - } - - memory_end = memory_start + size; + pr_notice("Memory limited to %ldMB\n", memory_limit >> 20); return 0; } @@ -252,7 +244,7 @@ void __init do_init_bootmem(void) { unsigned long bootmap_size; unsigned long bootmap_pages, bootmem_paddr; - u64 total_pages = (lmb_end_of_DRAM() - __MEMORY_START) >> PAGE_SHIFT; + u64 total_pages = lmb_phys_mem_size() >> PAGE_SHIFT; int i; bootmap_pages = bootmem_bootmap_pages(total_pages); @@ -276,12 +268,6 @@ void __init do_init_bootmem(void) __add_active_range(0, start_pfn, end_pfn); } - /* - * Handle additional early reservations - */ - check_for_initrd(); - reserve_crashkernel(); - /* * Add all physical memory to the bootmem map and mark each * area as present. @@ -299,7 +285,7 @@ void __init do_init_bootmem(void) sparse_memory_present_with_active_regions(0); } -static void __init setup_memory(void) +static void __init early_reserve_mem(void) { unsigned long start_pfn; @@ -326,11 +312,11 @@ static void __init setup_memory(void) if (CONFIG_ZERO_PAGE_OFFSET != 0) lmb_reserve(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET); - lmb_analyze(); - lmb_dump_all(); - - do_init_bootmem(); - plat_mem_setup(); + /* + * Handle additional early reservations + */ + check_for_initrd(); + reserve_crashkernel(); } /* @@ -397,10 +383,6 @@ void __init setup_arch(char **cmdline_p) bss_resource.start = virt_to_phys(__bss_start); bss_resource.end = virt_to_phys(_ebss)-1; - memory_start = (unsigned long)__va(__MEMORY_START); - if (!memory_end) - memory_end = memory_start + __MEMORY_SIZE; - #ifdef CONFIG_CMDLINE_OVERWRITE strlcpy(command_line, CONFIG_CMDLINE, sizeof(command_line)); #else @@ -417,8 +399,6 @@ void __init setup_arch(char **cmdline_p) parse_early_param(); - uncached_init(); - plat_early_device_setup(); /* Let earlyprintk output early console messages */ @@ -429,21 +409,28 @@ void __init setup_arch(char **cmdline_p) sh_mv_setup(); sh_mv.mv_mem_init(); - /* - * Find the highest page frame number we have available - */ - max_pfn = PFN_DOWN(__pa(memory_end)); + early_reserve_mem(); + + lmb_enforce_memory_limit(memory_limit); + lmb_analyze(); + + lmb_dump_all(); /* * Determine low and high memory ranges: */ - max_low_pfn = max_pfn; + max_low_pfn = max_pfn = lmb_end_of_DRAM() >> PAGE_SHIFT; min_low_pfn = __MEMORY_START >> PAGE_SHIFT; nodes_clear(node_online_map); + memory_start = (unsigned long)__va(__MEMORY_START); + memory_end = memory_start + (memory_limit ?: lmb_phys_mem_size()); + + uncached_init(); pmb_init(); - setup_memory(); + do_init_bootmem(); + plat_mem_setup(); sparse_init(); #ifdef CONFIG_DUMMY_CONSOLE