[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 28/38] qdev: add "check if address free" callback for buses
From: |
Paolo Bonzini |
Subject: |
[PULL 28/38] qdev: add "check if address free" callback for buses |
Date: |
Mon, 12 Oct 2020 16:33:33 -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 29/38] scsi/scsi_bus: switch search direction in scsi_device_find, (continued)
- [PULL 29/38] scsi/scsi_bus: switch search direction in scsi_device_find, Paolo Bonzini, 2020/10/12
- [PULL 26/38] qtest: check that drives are really appearing and disappearing, Paolo Bonzini, 2020/10/12
- [PULL 22/38] qtest: Reintroduce qtest_qmp_receive with QMP event buffering, Paolo Bonzini, 2020/10/12
- [PULL 23/38] qtest: remove qtest_qmp_receive_success, Paolo Bonzini, 2020/10/12
- [PULL 19/38] build-sys: fix git version from -version, Paolo Bonzini, 2020/10/12
- [PULL 24/38] device-plug-test: use qtest_qmp to send the device_del command, Paolo Bonzini, 2020/10/12
- [PULL 25/38] qtest: switch users back to qtest_qmp_receive, Paolo Bonzini, 2020/10/12
- [PULL 20/38] meson.build: Re-enable KVM support for MIPS, Paolo Bonzini, 2020/10/12
- [PULL 21/38] qtest: rename qtest_qmp_receive to qtest_qmp_receive_dict, Paolo Bonzini, 2020/10/12
- [PULL 14/38] docs: Move QTest documentation to its own document, Paolo Bonzini, 2020/10/12
- [PULL 28/38] qdev: add "check if address free" callback for buses,
Paolo Bonzini <=
- [PULL 16/38] docs/devel/qtest: Include libqtest API reference, Paolo Bonzini, 2020/10/12
- [PULL 33/38] device-core: use atomic_set on .realized property, Paolo Bonzini, 2020/10/12
- [PULL 32/38] scsi: switch to bus->check_address, Paolo Bonzini, 2020/10/12
- [PULL 13/38] qom: fix objects with improper parent type, Paolo Bonzini, 2020/10/12
- [PULL 38/38] meson: identify more sections of meson.build, Paolo Bonzini, 2020/10/12
- [PULL 30/38] device_core: use drain_call_rcu in in qmp_device_add, Paolo Bonzini, 2020/10/12
- [PULL 37/38] scsi/scsi_bus: fix races in REPORT LUNS, Paolo Bonzini, 2020/10/12
- [PULL 34/38] scsi/scsi-bus: scsi_device_find: don't return unrealized devices, Paolo Bonzini, 2020/10/12
- [PULL 31/38] device-core: use RCU for list of children of a bus, Paolo Bonzini, 2020/10/12