@@ -1691,6 +1691,7 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
acpi_align_size(tables->table_data, ACPI_BUILD_TABLE_SIZE);
}
+ pc_set_acpi_data_size(tables->table_data->len);
acpi_align_size(tables->linker, ACPI_BUILD_ALIGN_SIZE);
/* Cleanup memory that's no longer used. */
@@ -73,10 +73,10 @@
#endif
/* Leave a chunk of memory at the top of RAM for the BIOS ACPI tables. */
-unsigned acpi_data_size = 0x28000;
-void pc_set_legacy_acpi_data_size(void)
+unsigned acpi_data_size = 0x10000;
+void pc_set_acpi_data_size(unsigned size)
{
- acpi_data_size = 0x10000;
+ acpi_data_size = MAX(size + 0x8000, 0x10000);
}
#define BIOS_CFG_IOPORT 0x510
@@ -316,7 +316,6 @@ static void pc_compat_2_0(MachineState *machine)
legacy_acpi_table_size = 6652;
smbios_legacy_mode = true;
has_reserved_memory = false;
- pc_set_legacy_acpi_data_size();
}
static void pc_compat_1_7(MachineState *machine)
@@ -280,7 +280,6 @@ static void pc_compat_2_0(MachineState *machine)
{
smbios_legacy_mode = true;
has_reserved_memory = false;
- pc_set_legacy_acpi_data_size();
}
static void pc_compat_1_7(MachineState *machine)
@@ -176,7 +176,7 @@ void pc_acpi_init(const char *default_dsdt);
PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size,
ram_addr_t above_4g_mem_size);
-void pc_set_legacy_acpi_data_size(void);
+void pc_set_acpi_data_size(unsigned);
#define PCI_HOST_PROP_PCI_HOLE_START "pci-hole-start"
#define PCI_HOST_PROP_PCI_HOLE_END "pci-hole-end"
The initrd is loaded close to the top of memory, with some extra padding on top to account for memory that the BIOS could reserve in the memory map (for ACPI tables and the like). This reserved high memory area can get quite big. We currently force a 128k size for 2.1+ machine types, but even that might not be enough: if the BIOS allocates more memory from the high area than just the ACPI tables, loading the initrd can stumble on that memory and break. So, we want to do two things. First, increase the size of the padding to account for BIOS data structures. 32k will do, since in practice the problems were fixed with just 4k. Second, to avoid wasting memory, size the padding based on the actual size of the ACPI tables. The table builder can pass the right size, padded as above and with a minimum of 64k. For older machine types, the padding has basically no consequence; simply, the acpi_data_size will be set at machine_ready time instead of machine init, which is made possible by calling load_linux after the ACPI tables are built. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- hw/i386/acpi-build.c | 1 + hw/i386/pc.c | 6 +++--- hw/i386/pc_piix.c | 1 - hw/i386/pc_q35.c | 1 - include/hw/i386/pc.h | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-)