Commit e6f59784 authored by Alex Williamson's avatar Alex Williamson Committed by Tony Luck

[IA64] efi.c: fix mem= & max_addr=

With this change, there's some extra fuzz introduced that a max_addr
specification will get rounded down to a granule boundary and memory
quantity, when using mem=, will be within a granule size of the
requested amount.  Let me know if anyone finds more problems with it.
Signed-off-by: default avatarAlex Williamson <alex.williamson@hp.com>
Signed-off-by: default avatarTony Luck <tony.luck@intel.com>
parent 8407e566
......@@ -324,12 +324,12 @@ efi_memmap_walk (efi_freemem_callback_t callback, void *arg)
* [granule_addr - first_non_wb_addr) is guaranteed to
* be contiguous WB memory.
*/
granule_addr = md->phys_addr & ~(IA64_GRANULE_SIZE - 1);
granule_addr = GRANULEROUNDDOWN(md->phys_addr);
first_non_wb_addr = max(first_non_wb_addr, granule_addr);
if (first_non_wb_addr < md->phys_addr) {
trim_bottom(md, granule_addr + IA64_GRANULE_SIZE);
granule_addr = md->phys_addr & ~(IA64_GRANULE_SIZE - 1);
granule_addr = GRANULEROUNDDOWN(md->phys_addr);
first_non_wb_addr = max(first_non_wb_addr, granule_addr);
}
......@@ -343,24 +343,36 @@ efi_memmap_walk (efi_freemem_callback_t callback, void *arg)
break; /* non-WB or hole */
}
last_granule_addr = first_non_wb_addr & ~(IA64_GRANULE_SIZE - 1);
last_granule_addr = GRANULEROUNDDOWN(first_non_wb_addr);
if (last_granule_addr < md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT))
trim_top(md, last_granule_addr);
if (is_available_memory(md)) {
if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) > max_addr) {
if (md->phys_addr > max_addr)
if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) >= max_addr) {
if (md->phys_addr >= max_addr)
continue;
md->num_pages = (max_addr - md->phys_addr) >> EFI_PAGE_SHIFT;
first_non_wb_addr = max_addr;
}
if (total_mem >= mem_limit)
continue;
total_mem += (md->num_pages << EFI_PAGE_SHIFT);
if (total_mem > mem_limit) {
md->num_pages -= ((total_mem - mem_limit) >> EFI_PAGE_SHIFT);
max_addr = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
if (total_mem + (md->num_pages << EFI_PAGE_SHIFT) > mem_limit) {
unsigned long limit_addr = md->phys_addr;
limit_addr += mem_limit - total_mem;
limit_addr = GRANULEROUNDDOWN(limit_addr);
if (md->phys_addr > limit_addr)
continue;
md->num_pages = (limit_addr - md->phys_addr) >>
EFI_PAGE_SHIFT;
first_non_wb_addr = max_addr = md->phys_addr +
(md->num_pages << EFI_PAGE_SHIFT);
}
total_mem += (md->num_pages << EFI_PAGE_SHIFT);
if (md->num_pages == 0)
continue;
......@@ -495,13 +507,13 @@ efi_init (void)
for (cp = saved_command_line; *cp; ) {
if (memcmp(cp, "mem=", 4) == 0) {
cp += 4;
mem_limit = memparse(cp, &end) - 2;
mem_limit = memparse(cp, &end);
if (end != cp)
break;
cp = end;
} else if (memcmp(cp, "max_addr=", 9) == 0) {
cp += 9;
max_addr = memparse(cp, &end) - 1;
max_addr = GRANULEROUNDDOWN(memparse(cp, &end));
if (end != cp)
break;
cp = end;
......
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