[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 29/39] qdev: add "check if address free" callback for buses
From: |
Paolo Bonzini |
Subject: |
[PULL 29/39] qdev: add "check if address free" callback for buses |
Date: |
Sat, 10 Oct 2020 03:57:29 -0400 |
Check if an address is free on the bus before plugging in the
device. This makes it possible to do the check without any
side effects, and to detect the problem early without having
to do it in the realize callback.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20201006123904.610658-5-mlevitsk@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/core/qdev.c | 17 +++++++++++++++--
hw/net/virtio-net.c | 2 +-
hw/sd/core.c | 3 ++-
include/hw/qdev-core.h | 13 ++++++++++++-
4 files changed, 30 insertions(+), 5 deletions(-)
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 96772a15bd..74db78df36 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -94,13 +94,23 @@ static void bus_add_child(BusState *bus, DeviceState *child)
0);
}
-void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
+static bool bus_check_address(BusState *bus, DeviceState *child, Error **errp)
+{
+ BusClass *bc = BUS_GET_CLASS(bus);
+ return !bc->check_address || bc->check_address(bus, child, errp);
+}
+
+bool qdev_set_parent_bus(DeviceState *dev, BusState *bus, Error **errp)
{
BusState *old_parent_bus = dev->parent_bus;
DeviceClass *dc = DEVICE_GET_CLASS(dev);
assert(dc->bus_type && object_dynamic_cast(OBJECT(bus), dc->bus_type));
+ if (!bus_check_address(bus, dev, errp)) {
+ return false;
+ }
+
if (old_parent_bus) {
trace_qdev_update_parent_bus(dev, object_get_typename(OBJECT(dev)),
old_parent_bus, object_get_typename(OBJECT(old_parent_bus)),
@@ -126,6 +136,7 @@ void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
object_unref(OBJECT(old_parent_bus));
object_unref(OBJECT(dev));
}
+ return true;
}
DeviceState *qdev_new(const char *name)
@@ -371,7 +382,9 @@ bool qdev_realize(DeviceState *dev, BusState *bus, Error
**errp)
assert(!dev->realized && !dev->parent_bus);
if (bus) {
- qdev_set_parent_bus(dev, bus);
+ if (!qdev_set_parent_bus(dev, bus, errp)) {
+ return false;
+ }
} else {
assert(!DEVICE_GET_CLASS(dev)->bus_type);
}
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index a160a9da9c..277289d56e 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -3138,7 +3138,7 @@ static bool failover_replug_primary(VirtIONet *n, Error
**errp)
error_setg(errp, "virtio_net: couldn't find primary bus");
return false;
}
- qdev_set_parent_bus(n->primary_dev, n->primary_bus);
+ qdev_set_parent_bus(n->primary_dev, n->primary_bus, &error_abort);
n->primary_should_be_hidden = false;
if (!qemu_opt_set_bool(n->primary_device_opts,
"partially_hotplugged", true, errp)) {
diff --git a/hw/sd/core.c b/hw/sd/core.c
index 957d116f1a..08c93b5903 100644
--- a/hw/sd/core.c
+++ b/hw/sd/core.c
@@ -23,6 +23,7 @@
#include "hw/qdev-core.h"
#include "hw/sd/sd.h"
#include "qemu/module.h"
+#include "qapi/error.h"
#include "trace.h"
static inline const char *sdbus_name(SDBus *sdbus)
@@ -240,7 +241,7 @@ void sdbus_reparent_card(SDBus *from, SDBus *to)
readonly = sc->get_readonly(card);
sdbus_set_inserted(from, false);
- qdev_set_parent_bus(DEVICE(card), &to->qbus);
+ qdev_set_parent_bus(DEVICE(card), &to->qbus, &error_abort);
sdbus_set_inserted(to, true);
sdbus_set_readonly(to, readonly);
}
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 72064f4dd4..14d476c587 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -210,13 +210,24 @@ struct BusClass {
/* FIXME first arg should be BusState */
void (*print_dev)(Monitor *mon, DeviceState *dev, int indent);
char *(*get_dev_path)(DeviceState *dev);
+
/*
* This callback is used to create Open Firmware device path in accordance
* with OF spec http://forthworks.com/standards/of1275.pdf. Individual bus
* bindings can be found at http://playground.sun.com/1275/bindings/.
*/
char *(*get_fw_dev_path)(DeviceState *dev);
+
void (*reset)(BusState *bus);
+
+ /*
+ * Return whether the device can be added to @bus,
+ * based on the address that was set (via device properties)
+ * before realize. If not, on return @errp contains the
+ * human-readable error message.
+ */
+ bool (*check_address)(BusState *bus, DeviceState *dev, Error **errp);
+
BusRealize realize;
BusUnrealize unrealize;
@@ -788,7 +799,7 @@ const char *qdev_fw_name(DeviceState *dev);
Object *qdev_get_machine(void);
/* FIXME: make this a link<> */
-void qdev_set_parent_bus(DeviceState *dev, BusState *bus);
+bool qdev_set_parent_bus(DeviceState *dev, BusState *bus, Error **errp);
extern bool qdev_hotplug;
extern bool qdev_hot_removed;
--
2.26.2
- [PULL 19/39] docs/devel: update instruction on how to add new unit tests, (continued)
- [PULL 19/39] docs/devel: update instruction on how to add new unit tests, Paolo Bonzini, 2020/10/10
- [PULL 14/39] configure: fix performance regression due to PIC objects, Paolo Bonzini, 2020/10/10
- [PULL 17/39] docs/devel/qtest: Include libqtest API reference, Paolo Bonzini, 2020/10/10
- [PULL 12/39] exec: split out non-softmmu-specific parts, Paolo Bonzini, 2020/10/10
- [PULL 25/39] device-plug-test: use qtest_qmp to send the device_del command, Paolo Bonzini, 2020/10/10
- [PULL 22/39] qtest: rename qtest_qmp_receive to qtest_qmp_receive_dict, Paolo Bonzini, 2020/10/10
- [PULL 20/39] build-sys: fix git version from -version, Paolo Bonzini, 2020/10/10
- [PULL 18/39] qtest: unify extra_qtest_srcs and extra_qtest_deps, Paolo Bonzini, 2020/10/10
- [PULL 26/39] qtest: switch users back to qtest_qmp_receive, Paolo Bonzini, 2020/10/10
- [PULL 24/39] qtest: remove qtest_qmp_receive_success, Paolo Bonzini, 2020/10/10
- [PULL 29/39] qdev: add "check if address free" callback for buses,
Paolo Bonzini <=
- [PULL 23/39] qtest: Reintroduce qtest_qmp_receive, Paolo Bonzini, 2020/10/10
- [PULL 21/39] meson.build: Re-enable KVM support for MIPS, Paolo Bonzini, 2020/10/10
- [PULL 30/39] scsi/scsi_bus: switch search direction in scsi_device_find, Paolo Bonzini, 2020/10/10
- [PULL 27/39] qtest: check that drives are really appearing and disappearing, Paolo Bonzini, 2020/10/10
- [PULL 28/39] qemu-iotests, qtest: rewrite test 067 as a qtest, Paolo Bonzini, 2020/10/10
- [PULL 36/39] scsi/scsi_bus: Add scsi_device_get, Paolo Bonzini, 2020/10/10
- [PULL 35/39] scsi/scsi-bus: scsi_device_find: don't return unrealized devices, Paolo Bonzini, 2020/10/10
- [PULL 37/39] virtio-scsi: use scsi_device_get, Paolo Bonzini, 2020/10/10
- [PULL 32/39] device-core: use RCU for list of children of a bus, Paolo Bonzini, 2020/10/10
- [PULL 33/39] scsi: switch to bus->check_address, Paolo Bonzini, 2020/10/10