From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com, qemu-block@nongnu.org, mreitz@redhat.com
Subject: [PATCH v8 08/17] qdev: add "check if address free" callback for buses
Date: Wed, 7 Oct 2020 07:56:51 -0400 [thread overview]
Message-ID: <20201007115700.707938-9-pbonzini@redhat.com> (raw)
In-Reply-To: <20201007115700.707938-1-pbonzini@redhat.com>
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 7bf27b9db7..268cecc498 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -3142,7 +3142,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
next prev parent reply other threads:[~2020-10-07 12:02 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-10-07 11:56 [PATCH v8 00/17] Fix scsi devices plug/unplug races w.r.t virtio-scsi iothread Paolo Bonzini
2020-10-07 11:56 ` [PATCH v8 01/17] qtest: rename qtest_qmp_receive to qtest_qmp_receive_dict Paolo Bonzini
2020-10-07 11:56 ` [PATCH v8 02/17] qtest: Reintroduce qtest_qmp_receive Paolo Bonzini
2020-10-07 11:56 ` [PATCH v8 03/17] qtest: remove qtest_qmp_receive_success Paolo Bonzini
2020-10-07 11:56 ` [PATCH v8 04/17] device-plug-test: use qtest_qmp to send the device_del command Paolo Bonzini
2020-10-07 11:56 ` [PATCH v8 05/17] qtest: switch users back to qtest_qmp_receive Paolo Bonzini
2020-10-07 11:56 ` [PATCH v8 06/17] qtest: check that drives are really appearing and disappearing Paolo Bonzini
2020-10-09 9:09 ` Kevin Wolf
2020-10-07 11:56 ` [PATCH v8 07/17] qemu-iotests, qtest: rewrite test 067 as a qtest Paolo Bonzini
2020-10-09 9:48 ` Kevin Wolf
2020-10-09 12:15 ` Paolo Bonzini
2020-10-07 11:56 ` Paolo Bonzini [this message]
2020-10-07 11:56 ` [PATCH v8 09/17] scsi/scsi_bus: switch search direction in scsi_device_find Paolo Bonzini
2020-10-07 11:56 ` [PATCH v8 10/17] device_core: use drain_call_rcu in in qmp_device_add Paolo Bonzini
2020-10-07 11:56 ` [PATCH v8 11/17] device-core: use RCU for list of children of a bus Paolo Bonzini
2020-10-07 11:56 ` [PATCH v8 12/17] scsi: switch to bus->check_address Paolo Bonzini
2020-10-07 11:56 ` [PATCH v8 13/17] device-core: use atomic_set on .realized property Paolo Bonzini
2020-10-07 11:56 ` [PATCH v8 14/17] scsi/scsi-bus: scsi_device_find: don't return unrealized devices Paolo Bonzini
2020-10-07 11:56 ` [PATCH v8 15/17] scsi/scsi_bus: Add scsi_device_get Paolo Bonzini
2020-10-07 11:56 ` [PATCH v8 16/17] virtio-scsi: use scsi_device_get Paolo Bonzini
2020-10-07 11:57 ` [PATCH v8 17/17] scsi/scsi_bus: fix races in REPORT LUNS Paolo Bonzini
2020-10-07 12:18 ` [PATCH v8 00/17] Fix scsi devices plug/unplug races w.r.t virtio-scsi iothread no-reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201007115700.707938-9-pbonzini@redhat.com \
--to=pbonzini@redhat.com \
--cc=kwolf@redhat.com \
--cc=mreitz@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).