Skip to content

Commit fb319e7

Browse files
Chen Zhouctmarinas
authored andcommitted
of: fdt: Add memory for devices by DT property "linux,usable-memory-range"
When reserving crashkernel in high memory, some low memory is reserved for crash dump kernel devices and never mapped by the first kernel. This memory range is advertised to crash dump kernel via DT property under /chosen, linux,usable-memory-range = <BASE1 SIZE1 [BASE2 SIZE2]> We reused the DT property linux,usable-memory-range and made the low memory region as the second range "BASE2 SIZE2", which keeps compatibility with existing user-space and older kdump kernels. Crash dump kernel reads this property at boot time and call memblock_add() to add the low memory region after memblock_cap_memory_range() has been called. Signed-off-by: Chen Zhou <[email protected]> Co-developed-by: Zhen Lei <[email protected]> Signed-off-by: Zhen Lei <[email protected]> Reviewed-by: Rob Herring <[email protected]> Tested-by: Dave Kleikamp <[email protected]> Acked-by: Baoquan He <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Catalin Marinas <[email protected]>
1 parent 944a45a commit fb319e7

File tree

1 file changed

+23
-10
lines changed

1 file changed

+23
-10
lines changed

drivers/of/fdt.c

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -973,16 +973,24 @@ static void __init early_init_dt_check_for_elfcorehdr(unsigned long node)
973973

974974
static unsigned long chosen_node_offset = -FDT_ERR_NOTFOUND;
975975

976+
/*
977+
* The main usage of linux,usable-memory-range is for crash dump kernel.
978+
* Originally, the number of usable-memory regions is one. Now there may
979+
* be two regions, low region and high region.
980+
* To make compatibility with existing user-space and older kdump, the low
981+
* region is always the last range of linux,usable-memory-range if exist.
982+
*/
983+
#define MAX_USABLE_RANGES 2
984+
976985
/**
977986
* early_init_dt_check_for_usable_mem_range - Decode usable memory range
978987
* location from flat tree
979988
*/
980989
void __init early_init_dt_check_for_usable_mem_range(void)
981990
{
982-
const __be32 *prop;
983-
int len;
984-
phys_addr_t cap_mem_addr;
985-
phys_addr_t cap_mem_size;
991+
struct memblock_region rgn[MAX_USABLE_RANGES] = {0};
992+
const __be32 *prop, *endp;
993+
int len, i;
986994
unsigned long node = chosen_node_offset;
987995

988996
if ((long)node < 0)
@@ -991,16 +999,21 @@ void __init early_init_dt_check_for_usable_mem_range(void)
991999
pr_debug("Looking for usable-memory-range property... ");
9921000

9931001
prop = of_get_flat_dt_prop(node, "linux,usable-memory-range", &len);
994-
if (!prop || (len < (dt_root_addr_cells + dt_root_size_cells)))
1002+
if (!prop || (len % (dt_root_addr_cells + dt_root_size_cells)))
9951003
return;
9961004

997-
cap_mem_addr = dt_mem_next_cell(dt_root_addr_cells, &prop);
998-
cap_mem_size = dt_mem_next_cell(dt_root_size_cells, &prop);
1005+
endp = prop + (len / sizeof(__be32));
1006+
for (i = 0; i < MAX_USABLE_RANGES && prop < endp; i++) {
1007+
rgn[i].base = dt_mem_next_cell(dt_root_addr_cells, &prop);
1008+
rgn[i].size = dt_mem_next_cell(dt_root_size_cells, &prop);
9991009

1000-
pr_debug("cap_mem_start=%pa cap_mem_size=%pa\n", &cap_mem_addr,
1001-
&cap_mem_size);
1010+
pr_debug("cap_mem_regions[%d]: base=%pa, size=%pa\n",
1011+
i, &rgn[i].base, &rgn[i].size);
1012+
}
10021013

1003-
memblock_cap_memory_range(cap_mem_addr, cap_mem_size);
1014+
memblock_cap_memory_range(rgn[0].base, rgn[0].size);
1015+
for (i = 1; i < MAX_USABLE_RANGES && rgn[i].size; i++)
1016+
memblock_add(rgn[i].base, rgn[i].size);
10041017
}
10051018

10061019
#ifdef CONFIG_SERIAL_EARLYCON

0 commit comments

Comments
 (0)