From f18e29fc90cf271bae0c671151d0f55bd7649d52 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Thu, 2 Mar 2023 17:15:43 +0100 Subject: [PATCH] pcihp: add ACPI PCI hotplug specific is_hotpluggable_bus() callback Provide pcihp specific callback to check if bus is hotpluggable and consolidate its scattered hotplug criteria there. While at it clean up no longer needed qbus_set_hotplug_handler(BUS(bus), NULL) workarounds since callback makes qbus_is_hotpluggable() return correct answer even if hotplug_handler is set on bus. PS: see ("pci: fix 'hotplugglable' property behavior") for details why callback was introduced. Signed-off-by: Igor Mammedov Message-Id: <20230302161543.286002-35-imammedo@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/acpi-pci-hotplug-stub.c | 4 ++++ hw/acpi/ich9.c | 6 +++++ hw/acpi/pcihp.c | 42 ++++++++++++++------------------- hw/acpi/piix4.c | 8 +++++++ hw/isa/lpc_ich9.c | 1 + include/hw/acpi/ich9.h | 1 + include/hw/acpi/pcihp.h | 1 + 7 files changed, 39 insertions(+), 24 deletions(-) diff --git a/hw/acpi/acpi-pci-hotplug-stub.c b/hw/acpi/acpi-pci-hotplug-stub.c index d1794399f7..dcee3ad7a1 100644 --- a/hw/acpi/acpi-pci-hotplug-stub.c +++ b/hw/acpi/acpi-pci-hotplug-stub.c @@ -40,3 +40,7 @@ void acpi_pcihp_reset(AcpiPciHpState *s) return; } +bool acpi_pcihp_is_hotpluggbale_bus(AcpiPciHpState *s, BusState *bus) +{ + return true; +} diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index f778ade7ea..25e2c7243e 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -578,6 +578,12 @@ void ich9_pm_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, } } +bool ich9_pm_is_hotpluggable_bus(HotplugHandler *hotplug_dev, BusState *bus) +{ + ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev); + return acpi_pcihp_is_hotpluggbale_bus(&lpc->pm.acpi_pci_hotplug, bus); +} + void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list) { ICH9LPCState *s = ICH9_LPC_DEVICE(adev); diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c index 34cad061a8..dcfb779a7a 100644 --- a/hw/acpi/pcihp.c +++ b/hw/acpi/pcihp.c @@ -121,20 +121,6 @@ static void acpi_set_pci_info(bool has_bridge_hotplug) } } -static void acpi_pcihp_disable_root_bus(void) -{ - Object *host = acpi_get_i386_pci_host(); - PCIBus *bus; - - bus = PCI_HOST_BRIDGE(host)->bus; - if (bus && qbus_is_hotpluggable(BUS(bus))) { - /* setting the hotplug handler to NULL makes the bus non-hotpluggable */ - qbus_set_hotplug_handler(BUS(bus), NULL); - } - - return; -} - static void acpi_pcihp_test_hotplug_bus(PCIBus *bus, void *opaque) { AcpiPciHpFind *find = opaque; @@ -278,9 +264,6 @@ static void acpi_pcihp_update(AcpiPciHpState *s) void acpi_pcihp_reset(AcpiPciHpState *s) { - if (!s->use_acpi_root_pci_hotplug) { - acpi_pcihp_disable_root_bus(); - } acpi_set_pci_info(s->use_acpi_hotplug_bridge); acpi_pcihp_update(s); } @@ -320,13 +303,6 @@ void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s, object_dynamic_cast(OBJECT(dev), TYPE_PCI_BRIDGE)) { PCIBus *sec = pci_bridge_get_sec_bus(PCI_BRIDGE(pdev)); - /* Remove all hot-plug handlers if hot-plug is disabled on slot */ - if (object_dynamic_cast(OBJECT(dev), TYPE_PCIE_SLOT) && - !PCIE_SLOT(pdev)->hotplug) { - qbus_set_hotplug_handler(BUS(sec), NULL); - return; - } - qbus_set_hotplug_handler(BUS(sec), OBJECT(hotplug_dev)); /* We don't have to overwrite any other hotplug handler yet */ assert(QLIST_EMPTY(&sec->child)); @@ -385,6 +361,24 @@ void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev, acpi_send_event(DEVICE(hotplug_dev), ACPI_PCI_HOTPLUG_STATUS); } +bool acpi_pcihp_is_hotpluggbale_bus(AcpiPciHpState *s, BusState *bus) +{ + Object *o = OBJECT(bus->parent); + + if (s->use_acpi_hotplug_bridge && + object_dynamic_cast(o, TYPE_PCI_BRIDGE)) { + if (object_dynamic_cast(o, TYPE_PCIE_SLOT) && !PCIE_SLOT(o)->hotplug) { + return false; + } + return true; + } + + if (s->use_acpi_root_pci_hotplug) { + return true; + } + return false; +} + static uint64_t pci_read(void *opaque, hwaddr addr, unsigned int size) { AcpiPciHpState *s = opaque; diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 0a233fa95d..63d2113b86 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -404,6 +404,13 @@ static void piix4_device_unplug_cb(HotplugHandler *hotplug_dev, } } +static bool piix4_is_hotpluggable_bus(HotplugHandler *hotplug_dev, + BusState *bus) +{ + PIIX4PMState *s = PIIX4_PM(hotplug_dev); + return acpi_pcihp_is_hotpluggbale_bus(&s->acpi_pci_hotplug, bus); +} + static void piix4_pm_machine_ready(Notifier *n, void *opaque) { PIIX4PMState *s = container_of(n, PIIX4PMState, machine_ready); @@ -644,6 +651,7 @@ static void piix4_pm_class_init(ObjectClass *klass, void *data) hc->plug = piix4_device_plug_cb; hc->unplug_request = piix4_device_unplug_request_cb; hc->unplug = piix4_device_unplug_cb; + hc->is_hotpluggable_bus = piix4_is_hotpluggable_bus; adevc->ospm_status = piix4_ospm_status; adevc->send_event = piix4_send_gpe; adevc->madt_cpu = pc_madt_cpu_entry; diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index d8303d0322..9714b0001e 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -865,6 +865,7 @@ static void ich9_lpc_class_init(ObjectClass *klass, void *data) hc->plug = ich9_pm_device_plug_cb; hc->unplug_request = ich9_pm_device_unplug_request_cb; hc->unplug = ich9_pm_device_unplug_cb; + hc->is_hotpluggable_bus = ich9_pm_is_hotpluggable_bus; adevc->ospm_status = ich9_pm_ospm_status; adevc->send_event = ich9_send_gpe; adevc->madt_cpu = pc_madt_cpu_entry; diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h index 57a542c4b8..2faf7f0cae 100644 --- a/include/hw/acpi/ich9.h +++ b/include/hw/acpi/ich9.h @@ -87,6 +87,7 @@ void ich9_pm_device_unplug_request_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp); void ich9_pm_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp); +bool ich9_pm_is_hotpluggable_bus(HotplugHandler *hotplug_dev, BusState *bus); void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list); #endif /* HW_ACPI_ICH9_H */ diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h index 04c98511a4..ef59810c17 100644 --- a/include/hw/acpi/pcihp.h +++ b/include/hw/acpi/pcihp.h @@ -58,6 +58,7 @@ typedef struct AcpiPciHpState { void acpi_pcihp_init(Object *owner, AcpiPciHpState *, PCIBus *root, MemoryRegion *address_space_io, uint16_t io_base); +bool acpi_pcihp_is_hotpluggbale_bus(AcpiPciHpState *s, BusState *bus); void acpi_pcihp_device_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp); void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,