qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PULL 24/96] acpi: update RSDP on guest access


From: Michael S. Tsirkin
Subject: [Qemu-devel] [PULL 24/96] acpi: update RSDP on guest access
Date: Wed, 18 Feb 2015 22:46:26 +0100

RSDT offset can change across reboots and that makes
immutable RSDP, which is build at startup, point to
incorrect place in ACPI table blob. That results in
BIOS corrupting tables and guest OS failing to find
ACPI tables.
We really should have put it in a ROM region, but
we can't change that for old machine types,
let's just set the callback and update it explicitly.

Signed-off-by: Michael S. Tsirkin <address@hidden>
Signed-off-by: Igor Mammedov <address@hidden>
Reviewed-by: Michael S. Tsirkin <address@hidden>
Signed-off-by: Michael S. Tsirkin <address@hidden>
Reviewed-by: Marcel Apfelbaum <address@hidden>
---
 hw/i386/acpi-build.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 5737ed0..d9b99bc 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1367,6 +1367,7 @@ struct AcpiBuildState {
     /* Is table patched? */
     uint8_t patched;
     PcGuestInfo *guest_info;
+    void *rsdp;
 } AcpiBuildState;
 
 static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
@@ -1501,8 +1502,6 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables 
*tables)
 
     /* We'll expose it all to Guest so we want to reduce
      * chance of size changes.
-     * RSDP is small so it's easy to keep it immutable, no need to
-     * bother with alignment.
      *
      * We used to align the tables to 4k, but of course this would
      * too simple to be enough.  4k turned out to be too small an
@@ -1574,6 +1573,7 @@ static void acpi_build_update(void *build_opaque, 
uint32_t offset)
 
     memcpy(qemu_get_ram_ptr(build_state->table_ram), tables.table_data->data,
            build_state->table_size);
+    memcpy(build_state->rsdp, tables.rsdp->data, acpi_data_len(tables.rsdp));
 
     cpu_physical_memory_set_dirty_range_nocode(build_state->table_ram,
                                                build_state->table_size);
@@ -1646,11 +1646,14 @@ void acpi_setup(PcGuestInfo *guest_info)
                     tables.tcpalog->data, acpi_data_len(tables.tcpalog));
 
     /*
-     * RSDP is small so it's easy to keep it immutable, no need to
-     * bother with ROM blobs.
+     * Though RSDP is small, its contents isn't immutable, so
+     * update it along with the rest of tables on guest access.
      */
-    fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_RSDP_FILE,
-                    tables.rsdp->data, acpi_data_len(tables.rsdp));
+    fw_cfg_add_file_callback(guest_info->fw_cfg, ACPI_BUILD_RSDP_FILE,
+                             acpi_build_update, build_state,
+                             tables.rsdp->data, acpi_data_len(tables.rsdp));
+
+    build_state->rsdp = tables.rsdp->data;
 
     qemu_register_reset(acpi_build_reset, build_state);
     acpi_build_reset(build_state);
-- 
MST




reply via email to

[Prev in Thread] Current Thread [Next in Thread]