aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcin Nowakowski <marcin.nowakowski@mips.com>2018-02-01 06:37:21 -0500
committerJames Hogan <jhogan@kernel.org>2018-02-13 08:14:41 -0500
commit67a3ba25aa955198196f40b76b329b3ab9ad415a (patch)
tree1f233a0d6c6376606e16c807127b31e680dbe708
parent627f4a2bdf113ab88abc65cb505c89cbf615eae0 (diff)
MIPS: Fix incorrect mem=X@Y handling
Commit 73fbc1eba7ff ("MIPS: fix mem=X@Y commandline processing") added a fix to ensure that the memory range between PHYS_OFFSET and low memory address specified by mem= cmdline argument is not later processed by free_all_bootmem. This change was incorrect for systems where the commandline specifies more than 1 mem argument, as it will cause all memory between PHYS_OFFSET and each of the memory offsets to be marked as reserved, which results in parts of the RAM marked as reserved (Creator CI20's u-boot has a default commandline argument 'mem=256M@0x0 mem=768M@0x30000000'). Change the behaviour to ensure that only the range between PHYS_OFFSET and the lowest start address of the memories is marked as protected. This change also ensures that the range is marked protected even if it's only defined through the devicetree and not only via commandline arguments. Reported-by: Mathieu Malaterre <mathieu.malaterre@gmail.com> Signed-off-by: Marcin Nowakowski <marcin.nowakowski@mips.com> Fixes: 73fbc1eba7ff ("MIPS: fix mem=X@Y commandline processing") Cc: Ralf Baechle <ralf@linux-mips.org> Cc: linux-mips@linux-mips.org Cc: <stable@vger.kernel.org> # v4.11+ Tested-by: Mathieu Malaterre <malat@debian.org> Patchwork: https://patchwork.linux-mips.org/patch/18562/ Signed-off-by: James Hogan <jhogan@kernel.org>
-rw-r--r--arch/mips/kernel/setup.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 85bc601e9a0d..5f8b0a9e30b3 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -375,6 +375,7 @@ static void __init bootmem_init(void)
375 unsigned long reserved_end; 375 unsigned long reserved_end;
376 unsigned long mapstart = ~0UL; 376 unsigned long mapstart = ~0UL;
377 unsigned long bootmap_size; 377 unsigned long bootmap_size;
378 phys_addr_t ramstart = (phys_addr_t)ULLONG_MAX;
378 bool bootmap_valid = false; 379 bool bootmap_valid = false;
379 int i; 380 int i;
380 381
@@ -395,7 +396,8 @@ static void __init bootmem_init(void)
395 max_low_pfn = 0; 396 max_low_pfn = 0;
396 397
397 /* 398 /*
398 * Find the highest page frame number we have available. 399 * Find the highest page frame number we have available
400 * and the lowest used RAM address
399 */ 401 */
400 for (i = 0; i < boot_mem_map.nr_map; i++) { 402 for (i = 0; i < boot_mem_map.nr_map; i++) {
401 unsigned long start, end; 403 unsigned long start, end;
@@ -407,6 +409,8 @@ static void __init bootmem_init(void)
407 end = PFN_DOWN(boot_mem_map.map[i].addr 409 end = PFN_DOWN(boot_mem_map.map[i].addr
408 + boot_mem_map.map[i].size); 410 + boot_mem_map.map[i].size);
409 411
412 ramstart = min(ramstart, boot_mem_map.map[i].addr);
413
410#ifndef CONFIG_HIGHMEM 414#ifndef CONFIG_HIGHMEM
411 /* 415 /*
412 * Skip highmem here so we get an accurate max_low_pfn if low 416 * Skip highmem here so we get an accurate max_low_pfn if low
@@ -436,6 +440,13 @@ static void __init bootmem_init(void)
436 mapstart = max(reserved_end, start); 440 mapstart = max(reserved_end, start);
437 } 441 }
438 442
443 /*
444 * Reserve any memory between the start of RAM and PHYS_OFFSET
445 */
446 if (ramstart > PHYS_OFFSET)
447 add_memory_region(PHYS_OFFSET, ramstart - PHYS_OFFSET,
448 BOOT_MEM_RESERVED);
449
439 if (min_low_pfn >= max_low_pfn) 450 if (min_low_pfn >= max_low_pfn)
440 panic("Incorrect memory mapping !!!"); 451 panic("Incorrect memory mapping !!!");
441 if (min_low_pfn > ARCH_PFN_OFFSET) { 452 if (min_low_pfn > ARCH_PFN_OFFSET) {
@@ -664,9 +675,6 @@ static int __init early_parse_mem(char *p)
664 675
665 add_memory_region(start, size, BOOT_MEM_RAM); 676 add_memory_region(start, size, BOOT_MEM_RAM);
666 677
667 if (start && start > PHYS_OFFSET)
668 add_memory_region(PHYS_OFFSET, start - PHYS_OFFSET,
669 BOOT_MEM_RESERVED);
670 return 0; 678 return 0;
671} 679}
672early_param("mem", early_parse_mem); 680early_param("mem", early_parse_mem);