Skip to content

Commit 67a3ba2

Browse files
Marcin Nowakowskiamalon
authored andcommitted
MIPS: Fix incorrect mem=X@Y handling
Commit 73fbc1e ("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 <[email protected]> Signed-off-by: Marcin Nowakowski <[email protected]> Fixes: 73fbc1e ("MIPS: fix mem=X@Y commandline processing") Cc: Ralf Baechle <[email protected]> Cc: [email protected] Cc: <[email protected]> # v4.11+ Tested-by: Mathieu Malaterre <[email protected]> Patchwork: https://patchwork.linux-mips.org/patch/18562/ Signed-off-by: James Hogan <[email protected]>
1 parent 627f4a2 commit 67a3ba2

File tree

1 file changed

+12
-4
lines changed

1 file changed

+12
-4
lines changed

arch/mips/kernel/setup.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ static void __init bootmem_init(void)
375375
unsigned long reserved_end;
376376
unsigned long mapstart = ~0UL;
377377
unsigned long bootmap_size;
378+
phys_addr_t ramstart = (phys_addr_t)ULLONG_MAX;
378379
bool bootmap_valid = false;
379380
int i;
380381

@@ -395,7 +396,8 @@ static void __init bootmem_init(void)
395396
max_low_pfn = 0;
396397

397398
/*
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
399401
*/
400402
for (i = 0; i < boot_mem_map.nr_map; i++) {
401403
unsigned long start, end;
@@ -407,6 +409,8 @@ static void __init bootmem_init(void)
407409
end = PFN_DOWN(boot_mem_map.map[i].addr
408410
+ boot_mem_map.map[i].size);
409411

412+
ramstart = min(ramstart, boot_mem_map.map[i].addr);
413+
410414
#ifndef CONFIG_HIGHMEM
411415
/*
412416
* Skip highmem here so we get an accurate max_low_pfn if low
@@ -436,6 +440,13 @@ static void __init bootmem_init(void)
436440
mapstart = max(reserved_end, start);
437441
}
438442

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+
439450
if (min_low_pfn >= max_low_pfn)
440451
panic("Incorrect memory mapping !!!");
441452
if (min_low_pfn > ARCH_PFN_OFFSET) {
@@ -664,9 +675,6 @@ static int __init early_parse_mem(char *p)
664675

665676
add_memory_region(start, size, BOOT_MEM_RAM);
666677

667-
if (start && start > PHYS_OFFSET)
668-
add_memory_region(PHYS_OFFSET, start - PHYS_OFFSET,
669-
BOOT_MEM_RESERVED);
670678
return 0;
671679
}
672680
early_param("mem", early_parse_mem);

0 commit comments

Comments
 (0)