From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37949) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XBlVj-0001VS-Cf for qemu-devel@nongnu.org; Mon, 28 Jul 2014 10:02:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XBlVb-0004hb-OM for qemu-devel@nongnu.org; Mon, 28 Jul 2014 10:02:43 -0400 Received: from mx1.redhat.com ([209.132.183.28]:35817) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XBlVb-0004hM-Gd for qemu-devel@nongnu.org; Mon, 28 Jul 2014 10:02:35 -0400 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s6SE2XRR018800 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Mon, 28 Jul 2014 10:02:34 -0400 From: Paolo Bonzini Date: Mon, 28 Jul 2014 16:02:15 +0200 Message-Id: <1406556135-31717-6-git-send-email-pbonzini@redhat.com> In-Reply-To: <1406556135-31717-1-git-send-email-pbonzini@redhat.com> References: <1406556135-31717-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PATCH 5/5] pc: acpi: generate AML only for PCI0 devices if PCI bridge hotplug is disabled List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: imammedo@redhat.com, lersek@redhat.com, mst@redhat.com From: Igor Mammedov 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 [Affect bus_count too. - Paolo] Signed-off-by: Paolo Bonzini --- 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