aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony Liguori <aliguori@us.ibm.com>2012-02-12 11:36:24 -0600
committerAnthony Liguori <aliguori@us.ibm.com>2012-02-15 09:39:21 -0600
commitb2d4b3f7b8c8ad0519c4705a3b850446068e6946 (patch)
treeb82818d644b8c0813e033de422b4d4568b588dc3
parent83f7d43a9ef70b1b91e465173e18c845420e931e (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.c18
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;
}