Commit 6ede1fd3 authored by Yinghai Lu's avatar Yinghai Lu Committed by H. Peter Anvin

x86, mm: Trim memory in memblock to be page aligned

We will not map partial pages, so need to make sure memblock
allocation will not allocate those bytes out.

Also we will use for_each_mem_pfn_range() to loop to map memory
range to keep them consistent.
Signed-off-by: default avatarYinghai Lu <yinghai@kernel.org>
Link: http://lkml.kernel.org/r/CAE9FiQVZirvaBMFYRfXMmWEcHbKSicQEHz4VAwUv0xFCk51ZNw@mail.gmail.comAcked-by: default avatarJacob Shin <jacob.shin@amd.com>
Signed-off-by: default avatarH. Peter Anvin <hpa@linux.intel.com>
Cc: <stable@vger.kernel.org>
parent 94777fc5
...@@ -1077,6 +1077,9 @@ void __init memblock_x86_fill(void) ...@@ -1077,6 +1077,9 @@ void __init memblock_x86_fill(void)
memblock_add(ei->addr, ei->size); memblock_add(ei->addr, ei->size);
} }
/* throw away partial pages */
memblock_trim_memory(PAGE_SIZE);
memblock_dump_all(); memblock_dump_all();
} }
......
...@@ -57,6 +57,7 @@ int memblock_add(phys_addr_t base, phys_addr_t size); ...@@ -57,6 +57,7 @@ int memblock_add(phys_addr_t base, phys_addr_t size);
int memblock_remove(phys_addr_t base, phys_addr_t size); int memblock_remove(phys_addr_t base, phys_addr_t size);
int memblock_free(phys_addr_t base, phys_addr_t size); int memblock_free(phys_addr_t base, phys_addr_t size);
int memblock_reserve(phys_addr_t base, phys_addr_t size); int memblock_reserve(phys_addr_t base, phys_addr_t size);
void memblock_trim_memory(phys_addr_t align);
#ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
void __next_mem_pfn_range(int *idx, int nid, unsigned long *out_start_pfn, void __next_mem_pfn_range(int *idx, int nid, unsigned long *out_start_pfn,
......
...@@ -930,6 +930,30 @@ int __init_memblock memblock_is_region_reserved(phys_addr_t base, phys_addr_t si ...@@ -930,6 +930,30 @@ int __init_memblock memblock_is_region_reserved(phys_addr_t base, phys_addr_t si
return memblock_overlaps_region(&memblock.reserved, base, size) >= 0; return memblock_overlaps_region(&memblock.reserved, base, size) >= 0;
} }
void __init_memblock memblock_trim_memory(phys_addr_t align)
{
int i;
phys_addr_t start, end, orig_start, orig_end;
struct memblock_type *mem = &memblock.memory;
for (i = 0; i < mem->cnt; i++) {
orig_start = mem->regions[i].base;
orig_end = mem->regions[i].base + mem->regions[i].size;
start = round_up(orig_start, align);
end = round_down(orig_end, align);
if (start == orig_start && end == orig_end)
continue;
if (start < end) {
mem->regions[i].base = start;
mem->regions[i].size = end - start;
} else {
memblock_remove_region(mem, i);
i--;
}
}
}
void __init_memblock memblock_set_current_limit(phys_addr_t limit) void __init_memblock memblock_set_current_limit(phys_addr_t limit)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment