diff options
author | Anthony Liguori <aliguori@us.ibm.com> | 2012-02-12 11:36:24 -0600 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2012-02-15 09:39:21 -0600 |
commit | b2d4b3f7b8c8ad0519c4705a3b850446068e6946 (patch) | |
tree | b82818d644b8c0813e033de422b4d4568b588dc3 | |
parent | 83f7d43a9ef70b1b91e465173e18c845420e931e (diff) |
device_add: don't add a /peripheral link until init is complete
Otherwise we end up with a dangling reference which causes qdev_free() to fail.
Reported-by: Michael Tsirkin <mst@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
-rw-r--r-- | hw/qdev-monitor.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c index 49f13ca087..a310cc7b16 100644 --- a/hw/qdev-monitor.c +++ b/hw/qdev-monitor.c @@ -457,6 +457,16 @@ DeviceState *qdev_device_add(QemuOpts *opts) id = qemu_opts_id(opts); if (id) { qdev->id = id; + } + if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) { + qdev_free(qdev); + return NULL; + } + if (qdev_init(qdev) < 0) { + qerror_report(QERR_DEVICE_INIT_FAILED, driver); + return NULL; + } + if (qdev->id) { object_property_add_child(qdev_get_peripheral(), qdev->id, OBJECT(qdev), NULL); } else { @@ -466,14 +476,6 @@ DeviceState *qdev_device_add(QemuOpts *opts) OBJECT(qdev), NULL); g_free(name); } - if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) { - qdev_free(qdev); - return NULL; - } - if (qdev_init(qdev) < 0) { - qerror_report(QERR_DEVICE_INIT_FAILED, driver); - return NULL; - } qdev->opts = opts; return qdev; } |