x86: allow non-BIGMEM configs to boot on >= 16Tb systems

While frame table setup, directmap init, and boot allocator population
respect all intended bounds, the logic passing memory to the heap
allocator which wasn't passed to the boot allocator fails to respect
max_{pdx,pfn}. This then typically triggers the BUG() in
free_heap_pages() after checking page state, because of hitting a struct
page_info instance which was set to all ~0.

Of course all the memory above the 16Tb boundary is still going to
remain unused; using it requires BIGMEM=y. And of course this fix
similarly ought to help BIGMEM=y configurations on >= 123Tb systems
(where all the memory beyond that boundary continues to be unused).

Fixes: bac2000063 ("x86-64: reduce range spanned by 1:1 mapping and frame table indexes")
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Roger Pau Monné <roger.pau@citrix.com>
This commit is contained in:
Jan Beulich committed 2023-12-19 13:47:38 +01:00
1 parent 0cc74376d6
commit 64d32b75e6
1 file changed
+8 -6
+8 -6
View File
@@ -1731,15 +1731,15 @@ void asmlinkage __init noreturn __start_xen(unsigned long mbi_p)
if ( max_page - 1 > virt_to_mfn(HYPERVISOR_VIRT_END - 1) )
{
unsigned long limit = virt_to_mfn(HYPERVISOR_VIRT_END - 1);
unsigned long lo = virt_to_mfn(HYPERVISOR_VIRT_END - 1);
uint64_t mask = PAGE_SIZE - 1;
if ( !highmem_start )
xenheap_max_mfn(limit);
xenheap_max_mfn(lo);
end_boot_allocator();
/* Pass the remaining memory to the allocator. */
/* Pass the remaining memory in (lo, max_page) to the allocator. */
for ( i = 0; i < boot_e820.nr_map; i++ )
{
uint64_t s, e;
@@ -1748,10 +1748,12 @@ void asmlinkage __init noreturn __start_xen(unsigned long mbi_p)
continue;
s = (boot_e820.map[i].addr + mask) & ~mask;
e = (boot_e820.map[i].addr + boot_e820.map[i].size) & ~mask;
if ( PFN_DOWN(e) <= limit )
if ( PFN_DOWN(e) <= lo || PFN_DOWN(s) >= max_page )
continue;
if ( PFN_DOWN(s) <= limit )
s = pfn_to_paddr(limit + 1);
if ( PFN_DOWN(s) <= lo )
s = pfn_to_paddr(lo + 1);
if ( PFN_DOWN(e) > max_page )
e = pfn_to_paddr(max_page);
init_domheap_pages(s, e);
}
}
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.