qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

pci/pcihp: perform unplug via the hotplug handler

Introduce and use the "unplug" callback.

This is a preparation for multi-stage hotplug handlers, whereby the bus
hotplug handler is overwritten by the machine hotplug handler. This handler
will then pass control to the bus hotplug handler. So to get this running
cleanly, we also have to make sure to go via the hotplug handler chain when
actually unplugging a device after an unplug request. Lookup the hotplug
handler and call "unplug".

Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

authored by

David Hildenbrand and committed by
Michael S. Tsirkin
c97adf3c 3e520926

+18 -3
+10 -1
hw/acpi/pcihp.c
··· 154 154 155 155 static void acpi_pcihp_eject_slot(AcpiPciHpState *s, unsigned bsel, unsigned slots) 156 156 { 157 + HotplugHandler *hotplug_ctrl; 157 158 BusChild *kid, *next; 158 159 int slot = ctz32(slots); 159 160 PCIBus *bus = acpi_pcihp_find_hotplug_bus(s, bsel); ··· 171 172 PCIDevice *dev = PCI_DEVICE(qdev); 172 173 if (PCI_SLOT(dev->devfn) == slot) { 173 174 if (!acpi_pcihp_pc_no_hotplug(s, dev)) { 174 - object_unparent(OBJECT(qdev)); 175 + hotplug_ctrl = qdev_get_hotplug_handler(qdev); 176 + hotplug_handler_unplug(hotplug_ctrl, qdev, &error_abort); 175 177 } 176 178 } 177 179 } ··· 266 268 267 269 void acpi_pcihp_device_unplug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s, 268 270 DeviceState *dev, Error **errp) 271 + { 272 + object_unparent(OBJECT(dev)); 273 + } 274 + 275 + void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev, 276 + AcpiPciHpState *s, DeviceState *dev, 277 + Error **errp) 269 278 { 270 279 PCIDevice *pdev = PCI_DEVICE(dev); 271 280 int slot = PCI_SLOT(pdev->devfn);
+5 -2
hw/acpi/piix4.c
··· 419 419 acpi_memory_unplug_request_cb(hotplug_dev, &s->acpi_memory_hotplug, 420 420 dev, errp); 421 421 } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { 422 - acpi_pcihp_device_unplug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev, 423 - errp); 422 + acpi_pcihp_device_unplug_request_cb(hotplug_dev, &s->acpi_pci_hotplug, 423 + dev, errp); 424 424 } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU) && 425 425 !s->cpu_hotplug_legacy) { 426 426 acpi_cpu_unplug_request_cb(hotplug_dev, &s->cpuhp_state, dev, errp); ··· 438 438 if (s->acpi_memory_hotplug.is_enabled && 439 439 object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { 440 440 acpi_memory_unplug_cb(&s->acpi_memory_hotplug, dev, errp); 441 + } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { 442 + acpi_pcihp_device_unplug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev, 443 + errp); 441 444 } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU) && 442 445 !s->cpu_hotplug_legacy) { 443 446 acpi_cpu_unplug_cb(&s->cpuhp_state, dev, errp);
+3
include/hw/acpi/pcihp.h
··· 62 62 DeviceState *dev, Error **errp); 63 63 void acpi_pcihp_device_unplug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s, 64 64 DeviceState *dev, Error **errp); 65 + void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev, 66 + AcpiPciHpState *s, DeviceState *dev, 67 + Error **errp); 65 68 66 69 /* Called on reset */ 67 70 void acpi_pcihp_reset(AcpiPciHpState *s);