{
struct memblock_region *reg;
phys_addr_t mem_size = 0;
+ phys_addr_t total_mem = 0;
+ phys_addr_t mem_start, end = 0;
phys_addr_t vmlinux_end = __pa_symbol(&_end);
phys_addr_t vmlinux_start = __pa_symbol(&_start);
/* Find the memory region containing the kernel */
for_each_memblock(memory, reg) {
- phys_addr_t end = reg->base + reg->size;
-
- if (reg->base <= vmlinux_start && vmlinux_end <= end) {
- mem_size = min(reg->size, (phys_addr_t)-PAGE_OFFSET);
-
- /*
- * Remove memblock from the end of usable area to the
- * end of region
- */
- if (reg->base + mem_size < end)
- memblock_remove(reg->base + mem_size,
- end - reg->base - mem_size);
- }
+ end = reg->base + reg->size;
+ if (!total_mem)
+ mem_start = reg->base;
+ if (reg->base <= vmlinux_start && vmlinux_end <= end)
+ BUG_ON(reg->size == 0);
+ total_mem = total_mem + reg->size;
}
- BUG_ON(mem_size == 0);
+
+ /*
+ * Remove memblock from the end of usable area to the
+ * end of region
+ */
+ mem_size = min(total_mem, (phys_addr_t)-PAGE_OFFSET);
+ if (mem_start + mem_size < end)
+ memblock_remove(mem_start + mem_size,
+ end - mem_start - mem_size);
/* Reserve from the start of the kernel to the end of the kernel */
memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start);