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) ...@@ -324,12 +324,12 @@ efi_memmap_walk (efi_freemem_callback_t callback, void *arg)
* [granule_addr - first_non_wb_addr) is guaranteed to * [granule_addr - first_non_wb_addr) is guaranteed to
* be contiguous WB memory. * 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); first_non_wb_addr = max(first_non_wb_addr, granule_addr);
if (first_non_wb_addr < md->phys_addr) { if (first_non_wb_addr < md->phys_addr) {
trim_bottom(md, granule_addr + IA64_GRANULE_SIZE); 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); 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) ...@@ -343,24 +343,36 @@ efi_memmap_walk (efi_freemem_callback_t callback, void *arg)
break; /* non-WB or hole */ 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)) if (last_granule_addr < md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT))
trim_top(md, last_granule_addr); trim_top(md, last_granule_addr);
if (is_available_memory(md)) { if (is_available_memory(md)) {
if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) > max_addr) { if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) >= max_addr) {
if (md->phys_addr > max_addr) if (md->phys_addr >= max_addr)
continue; continue;
md->num_pages = (max_addr - md->phys_addr) >> EFI_PAGE_SHIFT; md->num_pages = (max_addr - md->phys_addr) >> EFI_PAGE_SHIFT;
first_non_wb_addr = max_addr;
} }
if (total_mem >= mem_limit) if (total_mem >= mem_limit)
continue; continue;
total_mem += (md->num_pages << EFI_PAGE_SHIFT);
if (total_mem > mem_limit) { if (total_mem + (md->num_pages << EFI_PAGE_SHIFT) > mem_limit) {
md->num_pages -= ((total_mem - mem_limit) >> EFI_PAGE_SHIFT); unsigned long limit_addr = md->phys_addr;
max_addr = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
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) if (md->num_pages == 0)
continue; continue;
...@@ -495,13 +507,13 @@ efi_init (void) ...@@ -495,13 +507,13 @@ efi_init (void)
for (cp = saved_command_line; *cp; ) { for (cp = saved_command_line; *cp; ) {
if (memcmp(cp, "mem=", 4) == 0) { if (memcmp(cp, "mem=", 4) == 0) {
cp += 4; cp += 4;
mem_limit = memparse(cp, &end) - 2; mem_limit = memparse(cp, &end);
if (end != cp) if (end != cp)
break; break;
cp = end; cp = end;
} else if (memcmp(cp, "max_addr=", 9) == 0) { } else if (memcmp(cp, "max_addr=", 9) == 0) {
cp += 9; cp += 9;
max_addr = memparse(cp, &end) - 1; max_addr = GRANULEROUNDDOWN(memparse(cp, &end));
if (end != cp) if (end != cp)
break; break;
cp = end; 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