diff mbox

[FYI,06/13] hw/acpi: introduce ACPI_BUILD_QEMUPARAM_FILE

Message ID 1442148227-17343-7-git-send-email-lersek@redhat.com
State New
Headers show

Commit Message

Laszlo Ersek Sept. 13, 2015, 12:43 p.m. UTC
We'll build the UEFI ACPI Data Table for the VMGENID device in a separate
fw_cfg blob (see "docs/vmgenid.txt").

When introducing a new fw_cfg blob for ACPI linker/loader purposes, we
have to decide first if the new blob will be subject to patching on first
guest access.

(1) If so, then the blob must be backed by a RAMBlock, so that the patched
    contents can be migrated, for the case when migration occurs while the
    guest is reading the patched blob.

(2) If the blob is not subject to patching on first guest access, then it
    doesn't have to be migrated in a RAMBlock; the target host can rebuild
    the blob identically from scratch (assuming the same machine type of
    course), and the migrated guest can continue reading that.

In the first case, the new blob has to follow the pattern seen with
"main_blob", "rsdp" and "linker":

- In acpi_build_tables_cleanup(), the direct output of the AML generator
  should be freed unconditionally, because that output has been copied
  into a RAMBlock both at startup (with acpi_add_rom_blob()) and on
  patching too (with acpi_ram_update()).

- Therefore the "mfre" parameter is not considered for such blobs in
  acpi_build_tables_cleanup().

In the second case, the new blob has to follow the pattern seen with
"tcpalog":

- In acpi_build_tables_cleanup(), the direct output of the AML generator
  must not be freed on startup (because that output is linked by fw_cfg).

- However on patching (which affects only *other* blobs), the fresh blob
  contents out of the AML generator are identical to the original contents
  (which are still linked by fw_cfg), thus the fresh output should be
  simply thrown away.

- Hence the "mfre" parameter must be considered for such blobs in
  acpi_build_tables_cleanup().

Now that we're introducing the ACPI_BUILD_QEMUPARAM_FILE blob (without any
contents as yet), only for the purposes of the VMGENID device, we can see
(from "docs/vmgenid.txt") that this blob won't need any patching, in
response to guest actions that occur before the guest first downloads the
blob. For that reason we follow pattern (2).

Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Gal Hammer <ghammer@redhat.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Shannon Zhao <shannon.zhao@linaro.org>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
---
 include/hw/acpi/aml-build.h | 2 ++
 hw/acpi/aml-build.c         | 2 ++
 hw/arm/virt-acpi-build.c    | 3 +++
 hw/i386/acpi-build.c        | 3 +++
 4 files changed, 10 insertions(+)
diff mbox

Patch

diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 47d28c9..ee54242 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -16,6 +16,7 @@ 
 #define ACPI_BUILD_TABLE_FILE "etc/acpi/tables"
 #define ACPI_BUILD_RSDP_FILE "etc/acpi/rsdp"
 #define ACPI_BUILD_TPMLOG_FILE "etc/tpm/log"
+#define ACPI_BUILD_QEMUPARAM_FILE "etc/acpi/qemuparam"
 
 typedef enum {
     AML_NO_OPCODE = 0,/* has only data */
@@ -154,6 +155,7 @@  struct AcpiBuildTables {
     GArray *main_blob;
     GArray *rsdp;
     GArray *tcpalog;
+    GArray *qemuparam_blob;
     GArray *linker;
 } AcpiBuildTables;
 
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 03111a3..7d58483 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -1228,6 +1228,7 @@  void acpi_build_tables_init(AcpiBuildTables *tables)
     tables->rsdp = g_array_new(false, true /* clear */, 1);
     tables->main_blob = g_array_new(false, true /* clear */, 1);
     tables->tcpalog = g_array_new(false, true /* clear */, 1);
+    tables->qemuparam_blob = g_array_new(false, true /* clear */, 1);
     tables->linker = bios_linker_loader_init();
 }
 
@@ -1238,6 +1239,7 @@  void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
     g_array_free(tables->rsdp, true);
     g_array_free(tables->main_blob, true);
     g_array_free(tables->tcpalog, mfre);
+    g_array_free(tables->qemuparam_blob, mfre);
 }
 
 /* Build rsdt table */
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 5725994..8b6856e 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -695,6 +695,9 @@  void virt_acpi_setup(VirtGuestInfo *guest_info)
 
     fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE,
                     tables.tcpalog->data, acpi_data_len(tables.tcpalog));
+    fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_QEMUPARAM_FILE,
+                    tables.qemuparam_blob->data,
+                    acpi_data_len(tables.qemuparam_blob));
 
     build_state->rsdp_mr = acpi_add_rom_blob(build_state, tables.rsdp,
                                               ACPI_BUILD_RSDP_FILE, 0);
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index baebfcc..045015e 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1909,6 +1909,9 @@  void acpi_setup(PcGuestInfo *guest_info)
 
     fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE,
                     tables.tcpalog->data, acpi_data_len(tables.tcpalog));
+    fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_QEMUPARAM_FILE,
+                    tables.qemuparam_blob->data,
+                    acpi_data_len(tables.qemuparam_blob));
 
     if (!guest_info->rsdp_in_ram) {
         /*