On Thu, Feb 1, 2018 at 12:37 PM, Marcin Nowakowski <marcin.nowakowski@xxxxxxxx> wrote: > 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@xxxxxxxxx> > Signed-off-by: Marcin Nowakowski <marcin.nowakowski@xxxxxxxx> > Fixes: 73fbc1eba7ff ("MIPS: fix mem=X@Y commandline processing") > Cc: <stable@xxxxxxxxxxxxxxx> # v4.11+ > --- > v3: Update stable version, code cleanup as suggested by James Hogan > v2: Use updated email adress, add tag for stable. > --- > arch/mips/kernel/setup.c | 16 ++++++++++++---- > 1 file changed, 12 insertions(+), 4 deletions(-) > > diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c > index 702c678de116..e4a1581ce822 100644 > --- a/arch/mips/kernel/setup.c > +++ b/arch/mips/kernel/setup.c > @@ -375,6 +375,7 @@ static void __init bootmem_init(void) > unsigned long reserved_end; > unsigned long mapstart = ~0UL; > unsigned long bootmap_size; > + phys_addr_t ramstart = (phys_addr_t)ULLONG_MAX; > bool bootmap_valid = false; > int i; > > @@ -395,7 +396,8 @@ static void __init bootmem_init(void) > max_low_pfn = 0; > > /* > - * Find the highest page frame number we have available. > + * Find the highest page frame number we have available > + * and the lowest used RAM address > */ > for (i = 0; i < boot_mem_map.nr_map; i++) { > unsigned long start, end; > @@ -407,6 +409,8 @@ static void __init bootmem_init(void) > end = PFN_DOWN(boot_mem_map.map[i].addr > + boot_mem_map.map[i].size); > > + ramstart = min(ramstart, boot_mem_map.map[i].addr); > + > #ifndef CONFIG_HIGHMEM > /* > * Skip highmem here so we get an accurate max_low_pfn if low > @@ -436,6 +440,13 @@ static void __init bootmem_init(void) > mapstart = max(reserved_end, start); > } > > + /* > + * Reserve any memory between the start of RAM and PHYS_OFFSET > + */ > + if (ramstart > PHYS_OFFSET) > + add_memory_region(PHYS_OFFSET, ramstart - PHYS_OFFSET, > + BOOT_MEM_RESERVED); > + > if (min_low_pfn >= max_low_pfn) > panic("Incorrect memory mapping !!!"); > if (min_low_pfn > ARCH_PFN_OFFSET) { > @@ -664,9 +675,6 @@ static int __init early_parse_mem(char *p) > > add_memory_region(start, size, BOOT_MEM_RAM); > > - if (start && start > PHYS_OFFSET) > - add_memory_region(PHYS_OFFSET, start - PHYS_OFFSET, > - BOOT_MEM_RESERVED); > return 0; > } > early_param("mem", early_parse_mem); > -- > 2.14.1 > Looks good to me: $ cat /proc/cpuinfo system type : JZ4780 machine : Creator CI20 processor : 0 cpu model : Ingenic JZRISC V4.15 FPU V0.0 BogoMIPS : 956.00 wait instruction : yes microsecond timers : no tlb_entries : 32 extra interrupt vector : yes hardware watchpoint : yes, count: 1, address/irw mask: [0x0fff] isa : mips1 mips2 mips32r1 mips32r2 ASEs implemented : shadow register sets : 1 kscratch registers : 0 package : 0 core : 0 VCED exceptions : not available VCEI exceptions : not available $ uname -a Linux ci20 4.15.0+ #323 PREEMPT Thu Feb 1 13:08:11 CET 2018 mips GNU/Linux Tested-by: Mathieu Malaterre <malat@xxxxxxxxxx> Thanks