mips: Make sure dt memory regions are valid

There are situations when memory regions coming from dts may be
too big for the platform physical address space. This especially
concerns XPA-capable systems. Bootloader may determine more than 4GB
memory available and pass it to the kernel over dts memory node, while
kernel is built without XPA/64BIT support. In this case the region
may either simply be truncated by add_memory_region() method
or by u64->phys_addr_t type casting. But in worst case the method
can even drop the memory region if it exceeds PHYS_ADDR_MAX size.
So lets make sure the retrieved from dts memory regions are valid,
and if some of them aren't, just manually truncate them with a warning
printed out.

Signed-off-by: Serge Semin <[email protected]>
Signed-off-by: Paul Burton <[email protected]>
Cc: Ralf Baechle <[email protected]>
Cc: James Hogan <[email protected]>
Cc: Mike Rapoport <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Michal Hocko <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: Thomas Bogendoerfer <[email protected]>
Cc: Huacai Chen <[email protected]>
Cc: Stefan Agner <[email protected]>
Cc: Stephen Rothwell <[email protected]>
Cc: Alexandre Belloni <[email protected]>
Cc: Juergen Gross <[email protected]>
Cc: Serge Semin <[email protected]>
Cc: [email protected]
Cc: [email protected]
This commit is contained in:
Serge Semin 2019-05-03 20:50:40 +03:00 • committed by Paul Burton
commit 93fa5b2807
No known key found for this signature in database
GPG key ID: 3EA79FACB57500DD

View file

@ -41,7 +41,19 @@ char *mips_get_machine_name(void)
#ifdef CONFIG_USE_OF
void __init early_init_dt_add_memory_arch(u64 base, u64 size)
{
return add_memory_region(base, size, BOOT_MEM_RAM);
if (base >= PHYS_ADDR_MAX) {
pr_warn("Trying to add an invalid memory region, skipped\n");
return;
}
/* Truncate the passed memory region instead of type casting */
if (base + size - 1 >= PHYS_ADDR_MAX || base + size < base) {
pr_warn("Truncate memory region %llx @ %llx to size %llx\n",
size, base, PHYS_ADDR_MAX - base);
size = PHYS_ADDR_MAX - base;
}
add_memory_region(base, size, BOOT_MEM_RAM);
}
int __init early_init_dt_reserve_memory_arch(phys_addr_t base,