Skip to content

Commit fa5a198

Browse files
atishp04palmer-dabbelt
authored andcommitted
riscv: Parse all memory blocks to remove unusable memory
Currently, maximum physical memory allowed is equal to -PAGE_OFFSET. That's why we remove any memory blocks spanning beyond that size. However, it is done only for memblock containing linux kernel which will not work if there are multiple memblocks. Process all memory blocks to figure out how much memory needs to be removed and remove at the end instead of updating the memblock list in place. Signed-off-by: Atish Patra <[email protected]> Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent 4400231 commit fa5a198

File tree

1 file changed

+17
-14
lines changed

1 file changed

+17
-14
lines changed

arch/riscv/mm/init.c

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -147,26 +147,29 @@ void __init setup_bootmem(void)
147147
{
148148
struct memblock_region *reg;
149149
phys_addr_t mem_size = 0;
150+
phys_addr_t total_mem = 0;
151+
phys_addr_t mem_start, end = 0;
150152
phys_addr_t vmlinux_end = __pa_symbol(&_end);
151153
phys_addr_t vmlinux_start = __pa_symbol(&_start);
152154

153155
/* Find the memory region containing the kernel */
154156
for_each_memblock(memory, reg) {
155-
phys_addr_t end = reg->base + reg->size;
156-
157-
if (reg->base <= vmlinux_start && vmlinux_end <= end) {
158-
mem_size = min(reg->size, (phys_addr_t)-PAGE_OFFSET);
159-
160-
/*
161-
* Remove memblock from the end of usable area to the
162-
* end of region
163-
*/
164-
if (reg->base + mem_size < end)
165-
memblock_remove(reg->base + mem_size,
166-
end - reg->base - mem_size);
167-
}
157+
end = reg->base + reg->size;
158+
if (!total_mem)
159+
mem_start = reg->base;
160+
if (reg->base <= vmlinux_start && vmlinux_end <= end)
161+
BUG_ON(reg->size == 0);
162+
total_mem = total_mem + reg->size;
168163
}
169-
BUG_ON(mem_size == 0);
164+
165+
/*
166+
* Remove memblock from the end of usable area to the
167+
* end of region
168+
*/
169+
mem_size = min(total_mem, (phys_addr_t)-PAGE_OFFSET);
170+
if (mem_start + mem_size < end)
171+
memblock_remove(mem_start + mem_size,
172+
end - mem_start - mem_size);
170173

171174
/* Reserve from the start of the kernel to the end of the kernel */
172175
memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start);

0 commit comments

Comments
 (0)