On 13/07/2018 17:59, Thomas Huth wrote: > Your patch looks good at a first quick glance, but it seems not to work as > expected: When I now run QEMU like this: > > echo "{'execute':'qmp_capabilities'}" \ > "{'execute':'device-list-properties'," \ > "'arguments':{'typename':'xlnx,zynqmp'}}" \ > "{'execute': 'human-monitor-command', " \ > "'arguments': {'command-line': 'info qtree'}}" | \ > aarch64-softmmu/qemu-system-aarch64 -M none,accel=qtest -qmp stdio > > then QEMU ends up in an endless loop and I've got to kill it.
There are two more bugs that my patch makes un-latent, where the objects are created but not added as children. Therefore when you call object_unparent on them, nothing happens. In particular dpcd and edid give you an infinite loop in bus_unparent, because device_unparent is not called and does not remove them from the list of devices on the bus. The following incremental changes fix everything for me. Note that aux_create_slave/qdev_create already do the unref for you. Thanks, Paolo diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c index 589ef59dfd..6439bd05ef 100644 --- a/hw/display/xlnx_dp.c +++ b/hw/display/xlnx_dp.c @@ -1235,8 +1235,11 @@ static void xlnx_dp_init(Object *obj) * Initialize DPCD and EDID.. */ s->dpcd = DPCD(aux_create_slave(s->aux_bus, "dpcd")); + object_property_add_child(OBJECT(s), "dpcd", OBJECT(s->dpcd), NULL); + s->edid = I2CDDC(qdev_create(BUS(aux_get_i2c_bus(s->aux_bus)), "i2c-ddc")); i2c_set_slave_address(I2C_SLAVE(s->edid), 0x50); + object_property_add_child(OBJECT(s), "edid", OBJECT(s->edid), NULL); fifo8_create(&s->rx_fifo, 16); fifo8_create(&s->tx_fifo, 16); diff --git a/hw/misc/auxbus.c b/hw/misc/auxbus.c index 2fe807d42f..0e56d9a8a4 100644 --- a/hw/misc/auxbus.c +++ b/hw/misc/auxbus.c @@ -32,6 +32,7 @@ #include "hw/misc/auxbus.h" #include "hw/i2c/i2c.h" #include "monitor/monitor.h" +#include "qapi/error.h" #ifndef DEBUG_AUX #define DEBUG_AUX 0 @@ -63,9 +64,14 @@ static void aux_bus_class_init(ObjectClass *klass, void *data) AUXBus *aux_init_bus(DeviceState *parent, const char *name) { AUXBus *bus; + Object *auxtoi2c; bus = AUX_BUS(qbus_create(TYPE_AUX_BUS, parent, name)); - bus->bridge = AUXTOI2C(qdev_create(BUS(bus), TYPE_AUXTOI2C)); + auxtoi2c = object_new_with_props(TYPE_AUXTOI2C, OBJECT(bus), "i2c", + &error_abort, NULL); + qdev_set_parent_bus(DEVICE(auxtoi2c), BUS(bus)); + + bus->bridge = AUXTOI2C(auxtoi2c); /* Memory related. */ bus->aux_io = g_malloc(sizeof(*bus->aux_io));