aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2016-05-10 11:30:42 +0100
committerPeter Maydell <peter.maydell@linaro.org>2016-06-14 15:07:43 +0100
commit7474f1be701f136b224af5e1abe55e97dc3f29a5 (patch)
tree3b35f2e3610b34a380a8b3e3a12f73eab9bf82b8
parentd32490ca74c700edc74f0b2f6b7536b52a644739 (diff)
qdev_try_create(): Assert that devices we put onto the system bus are SysBusDevices
If qdev_try_create() is passed NULL for the bus, it will automatically put the newly created device onto the default system bus. However if the device is not actually a SysBusDevice then this will result in later crashes (for instance when running the monitor "info qtree" command) because code reasonably assumes that all devices on the system bus are system bus devices. Generally the mistake is that the calling code should create the object with object_new(TYPE_FOO) rather than qdev_create(NULL, TYPE_FOO); see commit 6749695eaaf346c1 for an example of fixing this bug. Assert in qdev_try_create() if the device isn't suitable to put on the system bus, so that this mistake results in failure earlier and more reliably. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Markus Armbruster <armbru@redhat.com>
-rw-r--r--hw/core/qdev.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 0a05a5295c..dcc00f8c70 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -35,6 +35,7 @@
#include "qemu/error-report.h"
#include "hw/hotplug.h"
#include "hw/boards.h"
+#include "hw/sysbus.h"
#include "qapi-event.h"
int qdev_hotplug = 0;
@@ -140,6 +141,12 @@ DeviceState *qdev_try_create(BusState *bus, const char *type)
}
if (!bus) {
+ /* Assert that the device really is a SysBusDevice before
+ * we put it onto the sysbus. Non-sysbus devices which aren't
+ * being put onto a bus should be created with object_new(TYPE_FOO),
+ * not qdev_create(NULL, TYPE_FOO).
+ */
+ g_assert(object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE));
bus = sysbus_get_default();
}