Machine queue, 2019-03-06
* qdev: Hotplug handler chaining (David Hildenbrand) * qdev: fix qbus_is_full() (Tony Krowiak) * hostmem: fix crash when querying empty host-nodes property via QMP (Igor Mammedov) -----BEGIN PGP SIGNATURE----- iQIcBAABCAAGBQJcgBPhAAoJECgHk2+YTcWmWF0P/jyKA7fmdgTTqmgIvJ4nR2On d57GZobD+w3XqPUKFXJaayiwRiGrvZqBE1wUF9lURIVqG1vQVD5AT2hLQfC3PMv5 DbmDkWlVSdZ3fQLlvXI7kNXFdYt7ae2Xr/HDKJiPe8LXL8D0EW8puUT0ywu/ihz9 dKGo7erjASKZb3481mUyNcsRjUHYXxzyb8PHWciAmzm/xIedwsCcyZOA/ulIYl3t sqC/KewaxcZkExuvEUUpI+sPMHxGbu4Xq6QbhDMbxxT0b1MFa6zuoivNLnEvRE1q ixsSkKP1n9WqpdWqz+dmG7W6YTmlEw2F7E2MIPsLKij8V7pOnryECmd9FF1l95Cc 1Ul/c0WE1LY/dN0G/fKND1TjFuvXN27kFl+X3bi5Kno3FPPu6ajMWjaiAbW+QSbV ODyMGWvDjVj0lRCmIwxIWQIqKp2f9NOB8xbdY1qdPXgQJm2zryMyGAcUJTBWFcXB 7udErPIszhm2qwsjPnSPFYdn8MZbvzUauoGVJqxH0sbQmN237h3/DyV/+vZ/ZiRx 1a2G3oKckIS1AccEusFuVRIvx2wBTfsD/9beEw/io2eKxknbxyCyj6i/qcivqSUY POUc9+Iwk8dC0tw6VKnENXdzHSmo7ZuWnO0jcuu+k37AHHDGLu2PgcP3Hm+SyGIY QjeumpJafu5Ek1GJ6sKz =rUEC -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/ehabkost/tags/machine-next-pull-request' into staging Machine queue, 2019-03-06 * qdev: Hotplug handler chaining (David Hildenbrand) * qdev: fix qbus_is_full() (Tony Krowiak) * hostmem: fix crash when querying empty host-nodes property via QMP (Igor Mammedov) # gpg: Signature made Wed 06 Mar 2019 18:39:29 GMT # gpg: using RSA key 2807936F984DC5A6 # gpg: Good signature from "Eduardo Habkost <ehabkost@redhat.com>" [full] # Primary key fingerprint: 5A32 2FD5 ABC4 D3DB ACCF D1AA 2807 936F 984D C5A6 * remotes/ehabkost/tags/machine-next-pull-request: qdev: Provide qdev_get_bus_hotplug_handler() qdev: Let machine hotplug handler to override bus hotplug handler qdev: Let the hotplug_handler_unplug() caller delete the device hostmem: fix crash when querying empty host-nodes property via QMP qdev/core: fix qbus_is_full() Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
32694e98b8
@ -88,7 +88,7 @@ host_memory_backend_get_host_nodes(Object *obj, Visitor *v, const char *name,
|
||||
|
||||
value = find_first_bit(backend->host_nodes, MAX_NODES);
|
||||
if (value == MAX_NODES) {
|
||||
return;
|
||||
goto ret;
|
||||
}
|
||||
|
||||
*node = g_malloc0(sizeof(**node));
|
||||
@ -106,6 +106,7 @@ host_memory_backend_get_host_nodes(Object *obj, Visitor *v, const char *name,
|
||||
node = &(*node)->next;
|
||||
} while (true);
|
||||
|
||||
ret:
|
||||
visit_type_uint16List(v, name, &host_nodes, errp);
|
||||
}
|
||||
|
||||
|
@ -126,6 +126,7 @@ static void cpu_hotplug_wr(void *opaque, hwaddr addr, uint64_t data,
|
||||
dev = DEVICE(cdev->cpu);
|
||||
hotplug_ctrl = qdev_get_hotplug_handler(dev);
|
||||
hotplug_handler_unplug(hotplug_ctrl, dev, NULL);
|
||||
object_unparent(OBJECT(dev));
|
||||
}
|
||||
break;
|
||||
case ACPI_CPU_CMD_OFFSET_WR:
|
||||
|
@ -189,6 +189,7 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data,
|
||||
error_free(local_err);
|
||||
break;
|
||||
}
|
||||
object_unparent(OBJECT(dev));
|
||||
trace_mhp_acpi_pc_dimm_deleted(mem_st->selector);
|
||||
}
|
||||
break;
|
||||
|
@ -174,6 +174,7 @@ static void acpi_pcihp_eject_slot(AcpiPciHpState *s, unsigned bsel, unsigned slo
|
||||
if (!acpi_pcihp_pc_no_hotplug(s, dev)) {
|
||||
hotplug_ctrl = qdev_get_hotplug_handler(qdev);
|
||||
hotplug_handler_unplug(hotplug_ctrl, qdev, &error_abort);
|
||||
object_unparent(OBJECT(qdev));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -269,7 +270,7 @@ void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
|
||||
void acpi_pcihp_device_unplug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
|
||||
DeviceState *dev, Error **errp)
|
||||
{
|
||||
object_unparent(OBJECT(dev));
|
||||
object_property_set_bool(OBJECT(dev), false, "realized", NULL);
|
||||
}
|
||||
|
||||
void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev,
|
||||
|
@ -59,6 +59,8 @@ static void bus_remove_child(BusState *bus, DeviceState *child)
|
||||
snprintf(name, sizeof(name), "child[%d]", kid->index);
|
||||
QTAILQ_REMOVE(&bus->children, kid, sibling);
|
||||
|
||||
bus->num_children--;
|
||||
|
||||
/* This gives back ownership of kid->child back to us. */
|
||||
object_property_del(OBJECT(bus), name, NULL);
|
||||
object_unref(OBJECT(kid->child));
|
||||
@ -73,6 +75,7 @@ static void bus_add_child(BusState *bus, DeviceState *child)
|
||||
char name[32];
|
||||
BusChild *kid = g_malloc0(sizeof(*kid));
|
||||
|
||||
bus->num_children++;
|
||||
kid->index = bus->max_index++;
|
||||
kid->child = child;
|
||||
object_ref(OBJECT(kid->child));
|
||||
@ -233,14 +236,20 @@ HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HotplugHandler *qdev_get_bus_hotplug_handler(DeviceState *dev)
|
||||
{
|
||||
if (dev->parent_bus) {
|
||||
return dev->parent_bus->hotplug_handler;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev)
|
||||
{
|
||||
HotplugHandler *hotplug_ctrl;
|
||||
HotplugHandler *hotplug_ctrl = qdev_get_machine_hotplug_handler(dev);
|
||||
|
||||
if (dev->parent_bus && dev->parent_bus->hotplug_handler) {
|
||||
hotplug_ctrl = dev->parent_bus->hotplug_handler;
|
||||
} else {
|
||||
hotplug_ctrl = qdev_get_machine_hotplug_handler(dev);
|
||||
if (hotplug_ctrl == NULL && dev->parent_bus) {
|
||||
hotplug_ctrl = qdev_get_bus_hotplug_handler(dev);
|
||||
}
|
||||
return hotplug_ctrl;
|
||||
}
|
||||
@ -286,8 +295,7 @@ void qbus_reset_all_fn(void *opaque)
|
||||
void qdev_simple_device_unplug_cb(HotplugHandler *hotplug_dev,
|
||||
DeviceState *dev, Error **errp)
|
||||
{
|
||||
/* just zap it */
|
||||
object_unparent(OBJECT(dev));
|
||||
object_property_set_bool(OBJECT(dev), false, "realized", NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2154,8 +2154,7 @@ static void pc_memory_unplug(HotplugHandler *hotplug_dev,
|
||||
}
|
||||
|
||||
pc_dimm_unplug(PC_DIMM(dev), MACHINE(pcms));
|
||||
object_unparent(OBJECT(dev));
|
||||
|
||||
object_property_set_bool(OBJECT(dev), false, "realized", NULL);
|
||||
out:
|
||||
error_propagate(errp, local_err);
|
||||
}
|
||||
@ -2261,7 +2260,7 @@ static void pc_cpu_unplug_cb(HotplugHandler *hotplug_dev,
|
||||
|
||||
found_cpu = pc_find_cpu_slot(MACHINE(pcms), cpu->apic_id, NULL);
|
||||
found_cpu->cpu = NULL;
|
||||
object_unparent(OBJECT(dev));
|
||||
object_property_set_bool(OBJECT(dev), false, "realized", NULL);
|
||||
|
||||
/* decrement the number of CPUs */
|
||||
pcms->boot_cpus--;
|
||||
|
@ -428,7 +428,8 @@ PCIBus *pci_root_bus_new(DeviceState *parent, const char *name,
|
||||
void pci_root_bus_cleanup(PCIBus *bus)
|
||||
{
|
||||
pci_bus_uninit(bus);
|
||||
object_unparent(OBJECT(bus));
|
||||
/* the caller of the unplug hotplug handler will delete this device */
|
||||
object_property_set_bool(OBJECT(bus), false, "realized", NULL);
|
||||
}
|
||||
|
||||
void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
|
||||
|
@ -450,7 +450,7 @@ void pcie_cap_slot_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||
void pcie_cap_slot_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||
Error **errp)
|
||||
{
|
||||
object_unparent(OBJECT(dev));
|
||||
object_property_set_bool(OBJECT(dev), false, "realized", NULL);
|
||||
}
|
||||
|
||||
static void pcie_unplug_device(PCIBus *bus, PCIDevice *dev, void *opaque)
|
||||
@ -458,6 +458,7 @@ static void pcie_unplug_device(PCIBus *bus, PCIDevice *dev, void *opaque)
|
||||
HotplugHandler *hotplug_ctrl = qdev_get_hotplug_handler(DEVICE(dev));
|
||||
|
||||
hotplug_handler_unplug(hotplug_ctrl, DEVICE(dev), &error_abort);
|
||||
object_unparent(OBJECT(dev));
|
||||
}
|
||||
|
||||
void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
|
||||
|
@ -249,6 +249,7 @@ static void shpc_free_devices_in_slot(SHPCDevice *shpc, int slot)
|
||||
hotplug_ctrl = qdev_get_hotplug_handler(DEVICE(affected_dev));
|
||||
hotplug_handler_unplug(hotplug_ctrl, DEVICE(affected_dev),
|
||||
&error_abort);
|
||||
object_unparent(OBJECT(affected_dev));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -546,7 +547,7 @@ void shpc_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||
void shpc_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||
Error **errp)
|
||||
{
|
||||
object_unparent(OBJECT(dev));
|
||||
object_property_set_bool(OBJECT(dev), false, "realized", NULL);
|
||||
}
|
||||
|
||||
void shpc_device_unplug_request_cb(HotplugHandler *hotplug_dev,
|
||||
|
@ -3595,6 +3595,7 @@ void spapr_lmb_release(DeviceState *dev)
|
||||
* unplug handler chain. This can never fail.
|
||||
*/
|
||||
hotplug_handler_unplug(hotplug_ctrl, dev, &error_abort);
|
||||
object_unparent(OBJECT(dev));
|
||||
}
|
||||
|
||||
static void spapr_memory_unplug(HotplugHandler *hotplug_dev, DeviceState *dev)
|
||||
@ -3603,7 +3604,7 @@ static void spapr_memory_unplug(HotplugHandler *hotplug_dev, DeviceState *dev)
|
||||
sPAPRDIMMState *ds = spapr_pending_dimm_unplugs_find(spapr, PC_DIMM(dev));
|
||||
|
||||
pc_dimm_unplug(PC_DIMM(dev), MACHINE(hotplug_dev));
|
||||
object_unparent(OBJECT(dev));
|
||||
object_property_set_bool(OBJECT(dev), false, "realized", NULL);
|
||||
spapr_pending_dimm_unplugs_remove(spapr, ds);
|
||||
}
|
||||
|
||||
@ -3667,6 +3668,7 @@ void spapr_core_release(DeviceState *dev)
|
||||
|
||||
/* Call the unplug handler chain. This can never fail. */
|
||||
hotplug_handler_unplug(hotplug_ctrl, dev, &error_abort);
|
||||
object_unparent(OBJECT(dev));
|
||||
}
|
||||
|
||||
static void spapr_core_unplug(HotplugHandler *hotplug_dev, DeviceState *dev)
|
||||
@ -3689,7 +3691,7 @@ static void spapr_core_unplug(HotplugHandler *hotplug_dev, DeviceState *dev)
|
||||
|
||||
assert(core_slot);
|
||||
core_slot->cpu = NULL;
|
||||
object_unparent(OBJECT(dev));
|
||||
object_property_set_bool(OBJECT(dev), false, "realized", NULL);
|
||||
}
|
||||
|
||||
static
|
||||
@ -3940,11 +3942,12 @@ void spapr_phb_release(DeviceState *dev)
|
||||
HotplugHandler *hotplug_ctrl = qdev_get_hotplug_handler(dev);
|
||||
|
||||
hotplug_handler_unplug(hotplug_ctrl, dev, &error_abort);
|
||||
object_unparent(OBJECT(dev));
|
||||
}
|
||||
|
||||
static void spapr_phb_unplug(HotplugHandler *hotplug_dev, DeviceState *dev)
|
||||
{
|
||||
object_unparent(OBJECT(dev));
|
||||
object_property_set_bool(OBJECT(dev), false, "realized", NULL);
|
||||
}
|
||||
|
||||
static void spapr_phb_unplug_request(HotplugHandler *hotplug_dev,
|
||||
|
@ -1379,6 +1379,7 @@ void spapr_phb_remove_pci_device_cb(DeviceState *dev)
|
||||
HotplugHandler *hotplug_ctrl = qdev_get_hotplug_handler(dev);
|
||||
|
||||
hotplug_handler_unplug(hotplug_ctrl, dev, &error_abort);
|
||||
object_unparent(OBJECT(dev));
|
||||
}
|
||||
|
||||
static sPAPRDRConnector *spapr_phb_get_pci_func_drc(sPAPRPHBState *phb,
|
||||
@ -1506,7 +1507,7 @@ static void spapr_pci_unplug(HotplugHandler *plug_handler,
|
||||
* an 'idle' state, as the device cleanup code expects.
|
||||
*/
|
||||
pci_device_reset(PCI_DEVICE(plugged_dev));
|
||||
object_unparent(OBJECT(plugged_dev));
|
||||
object_property_set_bool(OBJECT(plugged_dev), false, "realized", NULL);
|
||||
}
|
||||
|
||||
static void spapr_pci_unplug_request(HotplugHandler *plug_handler,
|
||||
|
@ -51,7 +51,7 @@ static void ccw_device_unplug(HotplugHandler *hotplug_dev,
|
||||
|
||||
css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid, 1, 0);
|
||||
|
||||
object_unparent(OBJECT(dev));
|
||||
object_property_set_bool(OBJECT(dev), false, "realized", NULL);
|
||||
}
|
||||
|
||||
static void virtual_css_bus_reset(BusState *qbus)
|
||||
|
@ -154,14 +154,17 @@ static void s390_pci_perform_unplug(S390PCIBusDevice *pbdev)
|
||||
|
||||
/* Unplug the PCI device */
|
||||
if (pbdev->pdev) {
|
||||
hotplug_ctrl = qdev_get_hotplug_handler(DEVICE(pbdev->pdev));
|
||||
hotplug_handler_unplug(hotplug_ctrl, DEVICE(pbdev->pdev),
|
||||
&error_abort);
|
||||
DeviceState *pdev = DEVICE(pbdev->pdev);
|
||||
|
||||
hotplug_ctrl = qdev_get_hotplug_handler(pdev);
|
||||
hotplug_handler_unplug(hotplug_ctrl, pdev, &error_abort);
|
||||
object_unparent(OBJECT(pdev));
|
||||
}
|
||||
|
||||
/* Unplug the zPCI device */
|
||||
hotplug_ctrl = qdev_get_hotplug_handler(DEVICE(pbdev));
|
||||
hotplug_handler_unplug(hotplug_ctrl, DEVICE(pbdev), &error_abort);
|
||||
object_unparent(OBJECT(pbdev));
|
||||
}
|
||||
|
||||
void s390_pci_sclp_deconfigure(SCCB *sccb)
|
||||
@ -994,7 +997,7 @@ static void s390_pcihost_unplug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||
pbdev->fh, pbdev->fid);
|
||||
bus = pci_get_bus(pci_dev);
|
||||
devfn = pci_dev->devfn;
|
||||
object_unparent(OBJECT(pci_dev));
|
||||
object_property_set_bool(OBJECT(dev), false, "realized", NULL);
|
||||
|
||||
s390_pci_msix_free(pbdev);
|
||||
s390_pci_iommu_free(s, bus, devfn);
|
||||
@ -1005,7 +1008,7 @@ static void s390_pcihost_unplug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||
pbdev->fid = 0;
|
||||
QTAILQ_REMOVE(&s->zpci_devs, pbdev, link);
|
||||
g_hash_table_remove(s->zpci_table, &pbdev->idx);
|
||||
object_unparent(OBJECT(pbdev));
|
||||
object_property_set_bool(OBJECT(dev), false, "realized", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -206,6 +206,7 @@ struct BusState {
|
||||
HotplugHandler *hotplug_handler;
|
||||
int max_index;
|
||||
bool realized;
|
||||
int num_children;
|
||||
QTAILQ_HEAD(, BusChild) children;
|
||||
QLIST_ENTRY(BusState) sibling;
|
||||
};
|
||||
@ -280,7 +281,19 @@ DeviceState *qdev_try_create(BusState *bus, const char *name);
|
||||
void qdev_init_nofail(DeviceState *dev);
|
||||
void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
|
||||
int required_for_version);
|
||||
HotplugHandler *qdev_get_bus_hotplug_handler(DeviceState *dev);
|
||||
HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev);
|
||||
/**
|
||||
* qdev_get_hotplug_handler: Get handler responsible for device wiring
|
||||
*
|
||||
* Find HOTPLUG_HANDLER for @dev that provides [pre|un]plug callbacks for it.
|
||||
*
|
||||
* Note: in case @dev has a parent bus, it will be returned as handler unless
|
||||
* machine handler overrides it.
|
||||
*
|
||||
* Returns: pointer to object that implements TYPE_HOTPLUG_HANDLER interface
|
||||
* or NULL if there aren't any.
|
||||
*/
|
||||
HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev);
|
||||
void qdev_unplug(DeviceState *dev, Error **errp);
|
||||
void qdev_simple_device_unplug_cb(HotplugHandler *hotplug_dev,
|
||||
|
@ -414,7 +414,7 @@ static DeviceState *qbus_find_dev(BusState *bus, char *elem)
|
||||
static inline bool qbus_is_full(BusState *bus)
|
||||
{
|
||||
BusClass *bus_class = BUS_GET_CLASS(bus);
|
||||
return bus_class->max_dev && bus->max_index >= bus_class->max_dev;
|
||||
return bus_class->max_dev && bus->num_children >= bus_class->max_dev;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -862,6 +862,7 @@ void qdev_unplug(DeviceState *dev, Error **errp)
|
||||
DeviceClass *dc = DEVICE_GET_CLASS(dev);
|
||||
HotplugHandler *hotplug_ctrl;
|
||||
HotplugHandlerClass *hdc;
|
||||
Error *local_err = NULL;
|
||||
|
||||
if (dev->parent_bus && !qbus_is_hotpluggable(dev->parent_bus)) {
|
||||
error_setg(errp, QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
|
||||
@ -890,10 +891,14 @@ void qdev_unplug(DeviceState *dev, Error **errp)
|
||||
* otherwise just remove it synchronously */
|
||||
hdc = HOTPLUG_HANDLER_GET_CLASS(hotplug_ctrl);
|
||||
if (hdc->unplug_request) {
|
||||
hotplug_handler_unplug_request(hotplug_ctrl, dev, errp);
|
||||
hotplug_handler_unplug_request(hotplug_ctrl, dev, &local_err);
|
||||
} else {
|
||||
hotplug_handler_unplug(hotplug_ctrl, dev, errp);
|
||||
hotplug_handler_unplug(hotplug_ctrl, dev, &local_err);
|
||||
if (!local_err) {
|
||||
object_unparent(OBJECT(dev));
|
||||
}
|
||||
}
|
||||
error_propagate(errp, local_err);
|
||||
}
|
||||
|
||||
void qmp_device_del(const char *id, Error **errp)
|
||||
|
Loading…
x
Reference in New Issue
Block a user