qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: imammedo@redhat.com, lersek@redhat.com, mst@redhat.com
Subject: [Qemu-devel] [PATCH 5/5] pc: acpi: generate AML only for PCI0 devices if PCI bridge hotplug is disabled
Date: Mon, 28 Jul 2014 16:02:15 +0200	[thread overview]
Message-ID: <1406556135-31717-6-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1406556135-31717-1-git-send-email-pbonzini@redhat.com>

From: Igor Mammedov <imammedo@redhat.com>

Fixes migration regression from QEMU-1.7 to a newer QEMUs.
SSDT table size in QEMU-1.7 doesn't change regardless of
a number of PCI bridge devices present at startup.

However in QEMU-2.0 since addition of hotplug on PCI bridges,
each PCI bridge adds ~1875 bytes to SSDT table, including
pc-i440fx-1.7 machine type where PCI bridge hotplug disabled
via compat property.
It breaks migration from "QEMU-1.7" to "QEMU-2.[01] -M pc-i440fx-1.7"
since RAMBlock size of ACPI tables on target becomes larger
then on source and migration fails with:

"Length mismatch: /rom@etc/acpi/tables: 2000 in != 3000"

error.

Fix this by generating AML only for PCI0 bus if
hotplug on PCI bridges is disabled and preserves PCI brigde
description in AML as it was done in QEMU-1.7 for pc-i440fx-1.7.

It will help to maintain size of SSDT static regardless of
number of PCI bridges on startup for pc-i440fx-1.7 machine type.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
[Affect bus_count too. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/i386/acpi-build.c | 29 +++++++++++++++++++++++------
 1 file changed, 23 insertions(+), 6 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 8d42eaf..90f1b90 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -77,6 +77,7 @@ typedef struct AcpiMcfgInfo {
 typedef struct AcpiPmInfo {
     bool s3_disabled;
     bool s4_disabled;
+    bool pcihp_bridge_en;
     uint8_t s4_val;
     uint16_t sci_int;
     uint8_t acpi_enable_cmd;
@@ -98,6 +99,7 @@ typedef struct AcpiBuildPciBusHotplugState {
     GArray *device_table;
     GArray *notify_table;
     struct AcpiBuildPciBusHotplugState *parent;
+    bool pcihp_bridge_en;
 } AcpiBuildPciBusHotplugState;
 
 static void acpi_get_dsdt(AcpiMiscInfo *info)
@@ -201,6 +203,9 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
                                            NULL);
     pm->gpe0_blk_len = object_property_get_int(obj, ACPI_PM_PROP_GPE0_BLK_LEN,
                                                NULL);
+    pm->pcihp_bridge_en =
+        object_property_get_bool(obj, "acpi-pci-hotplug-with-bridge-support",
+                                 NULL);
 }
 
 static void acpi_get_misc_info(AcpiMiscInfo *info)
@@ -802,11 +807,13 @@ static void acpi_set_pci_info(void)
 }
 
 static void build_pci_bus_state_init(AcpiBuildPciBusHotplugState *state,
-                                     AcpiBuildPciBusHotplugState *parent)
+                                     AcpiBuildPciBusHotplugState *parent,
+                                     bool pcihp_bridge_en)
 {
     state->parent = parent;
     state->device_table = build_alloc_array();
     state->notify_table = build_alloc_array();
+    state->pcihp_bridge_en = pcihp_bridge_en;
 }
 
 static void build_pci_bus_state_cleanup(AcpiBuildPciBusHotplugState *state)
@@ -820,7 +827,7 @@ static void *build_pci_bus_begin(PCIBus *bus, void *parent_state)
     AcpiBuildPciBusHotplugState *parent = parent_state;
     AcpiBuildPciBusHotplugState *child = g_malloc(sizeof *child);
 
-    build_pci_bus_state_init(child, parent);
+    build_pci_bus_state_init(child, parent, parent->pcihp_bridge_en);
 
     return child;
 }
@@ -841,6 +848,14 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state)
     GArray *method;
     bool bus_hotplug_support = false;
 
+    /*
+        skip bridge subtree creation if bridge hotplug is disabled
+        to make it compatible with 1.7 machine type
+    */
+    if (!child->pcihp_bridge_en && bus->parent_dev) {
+        return;
+    }
+
     if (bus->parent_dev) {
         op = 0x82; /* DeviceOp */
         build_append_nameseg(bus_table, "S%.02X_",
@@ -887,7 +902,8 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state)
         pc = PCI_DEVICE_GET_CLASS(pdev);
         dc = DEVICE_GET_CLASS(pdev);
 
-        if (pc->class_id == PCI_CLASS_BRIDGE_ISA || pc->is_bridge) {
+        if (pc->class_id == PCI_CLASS_BRIDGE_ISA ||
+            (pc->is_bridge && child->pcihp_bridge_en)) {
             set_bit(slot, slot_device_system);
         }
 
@@ -899,7 +915,7 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state)
             }
         }
 
-        if (!dc->hotpluggable || pc->is_bridge) {
+        if (!dc->hotpluggable || (pc->is_bridge && child->pcihp_bridge_en)) {
             clear_bit(slot, slot_hotplug_enable);
         }
     }
@@ -1164,7 +1180,7 @@ build_ssdt(GArray *table_data, GArray *linker,
                 bus = PCI_HOST_BRIDGE(pci_host)->bus;
             }
 
-            build_pci_bus_state_init(&hotplug_state, NULL);
+            build_pci_bus_state_init(&hotplug_state, NULL, pm->pcihp_bridge_en);
 
             if (bus) {
                 /* Scan all PCI buses. Generate tables to support hotplug. */
@@ -1578,7 +1594,8 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
         /* Subtracting aml_len gives the size of fixed tables.  Then add the
          * size of the PIIX4 DSDT/SSDT in QEMU 2.0.
          */
-        int bus_count = acpi_count_hotpluggable_pci_buses();
+        int bus_count =
+            pm.pcihp_bridge_en ? acpi_count_hotpluggable_pci_buses() : 1;
         int legacy_aml_len =
             guest_info->legacy_acpi_table_size +
             ACPI_BUILD_LEGACY_CPU_AML_SIZE * max_cpus +
-- 
1.8.3.1

  parent reply	other threads:[~2014-07-28 14:02 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-28 14:02 [Qemu-devel] [PATCH v3 0/5] ACPI fixes for QEMU 2.1 Paolo Bonzini
2014-07-28 14:02 ` [Qemu-devel] [PATCH 1/5] acpi-dsdt: procedurally generate _PRT Paolo Bonzini
2014-07-28 14:02 ` [Qemu-devel] [PATCH 2/5] pc: hack for migration compatibility from QEMU 2.0 Paolo Bonzini
2014-07-28 15:05   ` Michael S. Tsirkin
2014-07-28 15:06     ` Paolo Bonzini
2014-07-28 14:02 ` [Qemu-devel] [PATCH 3/5] pc: future-proof migration-compatibility of ACPI tables Paolo Bonzini
2014-07-28 14:02 ` [Qemu-devel] [PATCH 4/5] bios-tables-test: fix ASL normalization false positive Paolo Bonzini
2014-07-28 14:02 ` Paolo Bonzini [this message]
  -- strict thread matches above, loose matches on Subject: below --
2014-07-28 15:34 [Qemu-devel] [PATCH v4 0/5] ACPI fixes for QEMU 2.1 Paolo Bonzini
2014-07-28 15:34 ` [Qemu-devel] [PATCH 5/5] pc: acpi: generate AML only for PCI0 devices if PCI bridge hotplug is disabled Paolo Bonzini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1406556135-31717-6-git-send-email-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=imammedo@redhat.com \
    --cc=lersek@redhat.com \
    --cc=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).