@@ -822,6 +822,8 @@ void __init start_xen(unsigned long boot_phys_offset,
setup_mm();
+ vm_init();
+
/* Parse the ACPI tables for possible boot-time configuration */
acpi_boot_table_init();
@@ -833,8 +835,6 @@ void __init start_xen(unsigned long boot_phys_offset,
*/
system_state = SYS_STATE_boot;
- vm_init();
-
if ( acpi_disabled )
{
printk("Booting using Device Tree\n");
@@ -695,6 +695,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
int i, j, e820_warn = 0, bytes = 0;
bool acpi_boot_table_init_done = false, relocated = false;
int ret;
+ bool vm_init_done = false;
struct ns16550_defaults ns16550 = {
.data_bits = 8,
.parity = 'n',
@@ -1301,12 +1302,23 @@ void __init noreturn __start_xen(unsigned long mbi_p)
continue;
if ( !acpi_boot_table_init_done &&
- s >= (1ULL << 32) &&
- !acpi_boot_table_init() )
+ s >= (1ULL << 32) )
{
- acpi_boot_table_init_done = true;
- srat_parse_regions(s);
- setup_max_pdx(raw_max_page);
+ /*
+ * We only initialise vmap and acpi after going through the bottom
+ * 4GiB, so that we have enough pages in the boot allocator.
+ */
+ if ( !vm_init_done )
+ {
+ vm_init();
+ vm_init_done = true;
+ }
+ if ( !acpi_boot_table_init() )
+ {
+ acpi_boot_table_init_done = true;
+ srat_parse_regions(s);
+ setup_max_pdx(raw_max_page);
+ }
}
if ( pfn_to_pdx((e - 1) >> PAGE_SHIFT) >= max_pdx )
@@ -1483,6 +1495,9 @@ void __init noreturn __start_xen(unsigned long mbi_p)
init_frametable();
+ if ( !vm_init_done )
+ vm_init();
+
if ( !acpi_boot_table_init_done )
acpi_boot_table_init();
@@ -1520,12 +1535,6 @@ void __init noreturn __start_xen(unsigned long mbi_p)
end_boot_allocator();
system_state = SYS_STATE_boot;
- /*
- * No calls involving ACPI code should go between the setting of
- * SYS_STATE_boot and vm_init() (or else acpi_os_{,un}map_memory()
- * will break).
- */
- vm_init();
console_init_ring();
vesa_init();
@@ -35,9 +35,20 @@ void __init vm_init_type(enum vmap_region type, void *start, void *end)
for ( i = 0, va = (unsigned long)vm_bitmap(type); i < nr; ++i, va += PAGE_SIZE )
{
- struct page_info *pg = alloc_domheap_page(NULL, 0);
+ mfn_t mfn;
+ int rc;
- map_pages_to_xen(va, page_to_mfn(pg), 1, PAGE_HYPERVISOR);
+ if ( system_state == SYS_STATE_early_boot )
+ mfn = alloc_boot_pages(1, 1);
+ else
+ {
+ struct page_info *pg = alloc_domheap_page(NULL, 0);
+
+ BUG_ON(!pg);
+ mfn = page_to_mfn(pg);
+ }
+ rc = map_pages_to_xen(va, mfn, 1, PAGE_HYPERVISOR);
+ BUG_ON(rc);
clear_page((void *)va);
}
bitmap_fill(vm_bitmap(type), vm_low[type]);
@@ -63,7 +74,7 @@ static void *vm_alloc(unsigned int nr, unsigned int align,
spin_lock(&vm_lock);
for ( ; ; )
{
- struct page_info *pg;
+ mfn_t mfn;
ASSERT(vm_low[t] == vm_top[t] || !test_bit(vm_low[t], vm_bitmap(t)));
for ( start = vm_low[t]; start < vm_top[t]; )
@@ -98,9 +109,16 @@ static void *vm_alloc(unsigned int nr, unsigned int align,
if ( vm_top[t] >= vm_end[t] )
return NULL;
- pg = alloc_domheap_page(NULL, 0);
- if ( !pg )
- return NULL;
+ if ( system_state == SYS_STATE_early_boot )
+ mfn = alloc_boot_pages(1, 1);
+ else
+ {
+ struct page_info *pg = alloc_domheap_page(NULL, 0);
+
+ if ( !pg )
+ return NULL;
+ mfn = page_to_mfn(pg);
+ }
spin_lock(&vm_lock);
@@ -108,7 +126,7 @@ static void *vm_alloc(unsigned int nr, unsigned int align,
{
unsigned long va = (unsigned long)vm_bitmap(t) + vm_top[t] / 8;
- if ( !map_pages_to_xen(va, page_to_mfn(pg), 1, PAGE_HYPERVISOR) )
+ if ( !map_pages_to_xen(va, mfn, 1, PAGE_HYPERVISOR) )
{
clear_page((void *)va);
vm_top[t] += PAGE_SIZE * 8;
@@ -118,7 +136,10 @@ static void *vm_alloc(unsigned int nr, unsigned int align,
}
}
- free_domheap_page(pg);
+ if ( system_state == SYS_STATE_early_boot )
+ init_boot_pages(mfn_to_maddr(mfn), mfn_to_maddr(mfn) + PAGE_SIZE);
+ else
+ free_domheap_page(mfn_to_page(mfn));
if ( start >= vm_top[t] )
{