From: Sameeh Jubran <sameeh@daynix.com>
To: qemu-devel@nongnu.org, Jason Wang <jasowang@redhat.com>
Cc: "Michael S . Tsirkin" <mst@redhat.com>,
Yan Vugenfirer <yan@daynix.com>,
Eduardo Habkost <ehabkost@redhat.com>
Subject: [Qemu-devel] [RFC 1/2] qdev/qbus: Add hidden device support
Date: Thu, 25 Oct 2018 17:06:30 +0300 [thread overview]
Message-ID: <20181025140631.634922-2-sameeh@daynix.com> (raw)
In-Reply-To: <20181025140631.634922-1-sameeh@daynix.com>
From: Sameeh Jubran <sjubran@redhat.com>
Signed-off-by: Sameeh Jubran <sjubran@redhat.com>
---
hw/core/qdev.c | 48 +++++++++++++++++++++++++++++++---
hw/pci/pci.c | 1 +
include/hw/pci/pci.h | 2 ++
include/hw/qdev-core.h | 11 +++++++-
qdev-monitor.c | 58 +++++++++++++++++++++++++++++++++++++++---
5 files changed, 112 insertions(+), 8 deletions(-)
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 529b82de18..a7c063f6ae 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -77,16 +77,23 @@ static void bus_add_child(BusState *bus, DeviceState *child)
kid->child = child;
object_ref(OBJECT(kid->child));
- QTAILQ_INSERT_HEAD(&bus->children, kid, sibling);
+ if(child->hidden)
+ {
+ QTAILQ_INSERT_HEAD(&bus->hidden_children, kid, sibling);
+ }
+ else
+ {
+ QTAILQ_INSERT_HEAD(&bus->children, kid, sibling);
- /* This transfers ownership of kid->child to the property. */
- snprintf(name, sizeof(name), "child[%d]", kid->index);
- object_property_add_link(OBJECT(bus), name,
+ /* This transfers ownership of kid->child to the property. */
+ snprintf(name, sizeof(name), "child[%d]", kid->index);
+ object_property_add_link(OBJECT(bus), name,
object_get_typename(OBJECT(child)),
(Object **)&kid->child,
NULL, /* read-only property */
0, /* return ownership on prop deletion */
NULL);
+ }
}
void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
@@ -104,12 +111,38 @@ void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
}
dev->parent_bus = bus;
object_ref(OBJECT(bus));
+
bus_add_child(bus, dev);
+
if (replugging) {
object_unref(OBJECT(dev));
}
}
+void qdev_unhide(const char *dev_id, BusState *bus, Error **errp)
+{
+ BusChild *kid;
+ DeviceState *dev = NULL;
+
+ QTAILQ_FOREACH(kid, &bus->hidden_children, sibling) {
+ if (!strcmp(kid->child->id,dev_id)) {
+ dev = kid->child;
+ break;
+ }
+ }
+
+ if (dev && dev->hidden)
+ {
+ dev->hidden = false;
+ QTAILQ_REMOVE(&bus->hidden_children, kid, sibling);
+ qdev_set_parent_bus(dev, dev->parent_bus);
+ object_property_set_bool(OBJECT(dev), true, "realized", errp);
+ if (!errp)
+ hotplug_handler_plug(bus->hotplug_handler, dev,
+ errp);
+ }
+}
+
/* Create a new device. This only initializes the device state
structure and allows properties to be set. The device still needs
to be realized. See qdev-core.h. */
@@ -208,6 +241,13 @@ void device_listener_unregister(DeviceListener *listener)
QTAILQ_REMOVE(&device_listeners, listener, link);
}
+bool qdev_should_hide_device(const char *dev_id, BusState *bus)
+{
+ bool res;
+ DEVICE_LISTENER_CALL(should_be_hidden, Forward, dev_id, bus, &res);
+ return res;
+}
+
void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
int required_for_version)
{
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 80bc45930d..054c22be1e 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -70,6 +70,7 @@ static Property pci_props[] = {
QEMU_PCIE_LNKSTA_DLLLA_BITNR, true),
DEFINE_PROP_BIT("x-pcie-extcap-init", PCIDevice, cap_present,
QEMU_PCIE_EXTCAP_INIT_BITNR, true),
+ DEFINE_PROP_STRING("standby", PCIDevice, standby_id_str),
DEFINE_PROP_END_OF_LIST()
};
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 990d6fcbde..8c0c3e9ef7 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -351,6 +351,8 @@ struct PCIDevice {
MSIVectorUseNotifier msix_vector_use_notifier;
MSIVectorReleaseNotifier msix_vector_release_notifier;
MSIVectorPollNotifier msix_vector_poll_notifier;
+
+ char *standby_id_str;
};
void pci_register_bar(PCIDevice *pci_dev, int region_num,
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index f1fd0f8736..dedb84e539 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -143,6 +143,7 @@ struct DeviceState {
char *canonical_path;
bool realized;
bool pending_deleted_event;
+ bool hidden;
QemuOpts *opts;
int hotplugged;
BusState *parent_bus;
@@ -156,6 +157,11 @@ struct DeviceState {
struct DeviceListener {
void (*realize)(DeviceListener *listener, DeviceState *dev);
void (*unrealize)(DeviceListener *listener, DeviceState *dev);
+ /* This callback is called just upon init of the DeviceState
+ * and can be used by a standby device for informing qdev if this
+ * device should be hidden by cross checking the ids
+ */
+ void (*should_be_hidden)(DeviceListener *listener, const char *dev_id, BusState *bus, bool *res);
QTAILQ_ENTRY(DeviceListener) link;
};
@@ -206,6 +212,7 @@ struct BusState {
int max_index;
bool realized;
QTAILQ_HEAD(ChildrenHead, BusChild) children;
+ QTAILQ_HEAD(HiddenChildrenHead, BusChild) hidden_children;
QLIST_ENTRY(BusState) sibling;
};
@@ -360,7 +367,7 @@ int qdev_walk_children(DeviceState *dev,
void qdev_reset_all(DeviceState *dev);
void qdev_reset_all_fn(void *opaque);
-
+void qdev_unhide(const char *dev_id, BusState *bus, Error **errp);
/**
* @qbus_reset_all:
* @bus: Bus to be reset.
@@ -434,4 +441,6 @@ static inline bool qbus_is_hotpluggable(BusState *bus)
void device_listener_register(DeviceListener *listener);
void device_listener_unregister(DeviceListener *listener);
+bool qdev_should_hide_device(const char *dev_id, BusState *bus);
+
#endif
diff --git a/qdev-monitor.c b/qdev-monitor.c
index 61e0300991..e211b7b223 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -554,6 +554,49 @@ void qdev_set_id(DeviceState *dev, const char *id)
}
}
+struct DeviceBusTuple
+{
+ DeviceState *dev;
+ BusState *bus;
+} DeviceBusTuple;
+
+static int has_standby_device(void *opaque, const char *name, const char *value,
+ Error **errp)
+{
+ if (strcmp(name, "standby") == 0)
+ {
+ struct DeviceBusTuple *tuple = (struct DeviceBusTuple *)opaque;
+ const char *dev_id = (tuple->dev)->id;
+ BusState *bus = tuple->bus;
+
+ if (qdev_should_hide_device(dev_id, bus))
+ {
+ return 1;
+ }
+ else
+ {
+ error_setg(errp, "An error occurred: Please note that the primary device should be"
+ " must be placed after the standby device in the command line");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static bool should_hide_device(DeviceState *dev, QemuOpts *opts,BusState *bus, Error **err)
+{
+ struct DeviceBusTuple tuple;
+ tuple.dev = dev;
+ tuple.bus = bus;
+
+ if (//!qemu_opt_get(opts, "vfio-pci") ||
+ qemu_opt_foreach(opts, has_standby_device, &tuple, err) == 0)
+ {
+ return false;
+ }
+ return true;
+}
+
DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
{
DeviceClass *dc;
@@ -607,6 +650,13 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
/* create device */
dev = DEVICE(object_new(driver));
+ qdev_set_id(dev, qemu_opts_id(opts));
+
+ dev->hidden = should_hide_device(dev, opts, bus, &err);
+ if (err)
+ {
+ goto err_del_dev;
+ }
if (bus) {
qdev_set_parent_bus(dev, bus);
} else if (qdev_hotplug && !qdev_get_machine_hotplug_handler(dev)) {
@@ -616,15 +666,17 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
goto err_del_dev;
}
- qdev_set_id(dev, qemu_opts_id(opts));
-
/* set properties */
if (qemu_opt_foreach(opts, set_property, dev, &err)) {
goto err_del_dev;
}
dev->opts = opts;
- object_property_set_bool(OBJECT(dev), true, "realized", &err);
+ if (!dev->hidden)
+ {
+ object_property_set_bool(OBJECT(dev), true, "realized", &err);
+ }
+
if (err != NULL) {
dev->opts = NULL;
goto err_del_dev;
--
2.17.0
next prev parent reply other threads:[~2018-10-25 14:06 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-10-25 14:06 [Qemu-devel] [RFC 0/2] Attempt to implement the standby feature for assigned network devices Sameeh Jubran
2018-10-25 14:06 ` Sameeh Jubran [this message]
2018-10-25 14:06 ` [Qemu-devel] [RFC 2/2] virtio-net: Implement VIRTIO_NET_F_STANDBY feature Sameeh Jubran
2018-10-25 18:01 ` [Qemu-devel] [RFC 0/2] Attempt to implement the standby feature for assigned network devices Sameeh Jubran
2018-12-05 16:18 ` Michael Roth
2018-12-05 17:09 ` [Qemu-devel] [libvirt] " Peter Krempa
2018-12-05 17:22 ` Michael S. Tsirkin
2018-12-05 17:26 ` Daniel P. Berrangé
2018-12-05 17:43 ` Daniel P. Berrangé
2018-10-25 22:17 ` [Qemu-devel] " Michael S. Tsirkin
2018-12-05 17:18 ` Daniel P. Berrangé
2018-12-05 17:26 ` Michael S. Tsirkin
2018-12-05 20:24 ` Michael Roth
2018-12-05 20:44 ` Michael Roth
2018-12-05 20:58 ` Michael S. Tsirkin
2018-12-05 20:57 ` Michael S. Tsirkin
2018-12-06 10:01 ` Daniel P. Berrangé
2018-12-06 10:06 ` Daniel P. Berrangé
2018-12-07 16:36 ` Eduardo Habkost
2018-12-07 16:46 ` Daniel P. Berrangé
2018-12-07 18:26 ` Michael S. Tsirkin
2018-12-07 17:50 ` Roman Kagan
2018-12-07 18:20 ` Michael S. Tsirkin
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=20181025140631.634922-2-sameeh@daynix.com \
--to=sameeh@daynix.com \
--cc=ehabkost@redhat.com \
--cc=jasowang@redhat.com \
--cc=mst@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=yan@daynix.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.