aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2021-10-15 12:08:54 -0700
committerRichard Henderson <richard.henderson@linaro.org>2021-10-15 12:08:54 -0700
commit253e399bab7c83b3411f8eac01840283a9304cb3 (patch)
tree9fd0a3fcf71a9e6b0d6ecc81222688539f572ce2 /hw
parent82d88f834c8f7d33ad9529fca80924bc496fcb70 (diff)
parent5dacda5167560b3af8eadbce5814f60ba44b467e (diff)
Merge remote-tracking branch 'remotes/kwolf/tags/for-upstream' into staging
qdev: Add JSON -device - Add a JSON mode to the -device command line option - net/vhost-{user,vdpa}: Fix device compatibility check - Minor iotests fixes # gpg: Signature made Fri 15 Oct 2021 07:41:22 AM PDT # gpg: using RSA key DC3DEB159A9AF95D3D7456FE7F09B272C88F2FD6 # gpg: issuer "kwolf@redhat.com" # gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full] * remotes/kwolf/tags/for-upstream: vl: Enable JSON syntax for -device qdev: Base object creation on QDict rather than QemuOpts virtio-net: Avoid QemuOpts in failover_find_primary_device() virtio-net: Store failover primary opts pointer locally qdev: Add Error parameter to hide_device() callbacks qemu-option: Allow deleting opts during qemu_opts_foreach() softmmu/qdev-monitor: add error handling in qdev_set_id qdev: Make DeviceState.id independent of QemuOpts qdev: Avoid using string visitor for properties iotests/051: Fix typo iotests/245: Fix type for iothread property qom: Reduce use of error_propagate() net/vhost-vdpa: Fix device compatibility check net/vhost-user: Fix device compatibility check net: Introduce NetClientInfo.check_peer_type() Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/arm/virt.c2
-rw-r--r--hw/core/qdev-properties-system.c6
-rw-r--r--hw/core/qdev.c11
-rw-r--r--hw/net/virtio-net.c85
-rw-r--r--hw/pci-bridge/pci_expander_bridge.c2
-rw-r--r--hw/ppc/e500.c2
-rw-r--r--hw/vfio/pci.c4
-rw-r--r--hw/xen/xen-legacy-backend.c3
8 files changed, 63 insertions, 52 deletions
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 7170aaacd5..4160d49688 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1459,7 +1459,7 @@ static void create_platform_bus(VirtMachineState *vms)
MemoryRegion *sysmem = get_system_memory();
dev = qdev_new(TYPE_PLATFORM_BUS_DEVICE);
- dev->id = TYPE_PLATFORM_BUS_DEVICE;
+ dev->id = g_strdup(TYPE_PLATFORM_BUS_DEVICE);
qdev_prop_set_uint32(dev, "num_irqs", PLATFORM_BUS_NUM_IRQS);
qdev_prop_set_uint32(dev, "mmio_size", vms->memmap[VIRT_PLATFORM_BUS].size);
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index e71f5d64d1..a91f60567a 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -431,6 +431,12 @@ static void set_netdev(Object *obj, Visitor *v, const char *name,
goto out;
}
+ if (peers[i]->info->check_peer_type) {
+ if (!peers[i]->info->check_peer_type(peers[i], obj->class, errp)) {
+ goto out;
+ }
+ }
+
ncs[i] = peers[i];
ncs[i]->queue_index = i;
}
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index cefc5eaa0a..7f06403752 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -28,6 +28,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qapi/qapi-events-qdev.h"
+#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qerror.h"
#include "qapi/visitor.h"
#include "qemu/error-report.h"
@@ -211,14 +212,17 @@ void device_listener_unregister(DeviceListener *listener)
QTAILQ_REMOVE(&device_listeners, listener, link);
}
-bool qdev_should_hide_device(QemuOpts *opts)
+bool qdev_should_hide_device(const QDict *opts, bool from_json, Error **errp)
{
+ ERRP_GUARD();
DeviceListener *listener;
QTAILQ_FOREACH(listener, &device_listeners, link) {
if (listener->hide_device) {
- if (listener->hide_device(listener, opts)) {
+ if (listener->hide_device(listener, opts, from_json, errp)) {
return true;
+ } else if (*errp) {
+ return false;
}
}
}
@@ -955,7 +959,8 @@ static void device_finalize(Object *obj)
dev->canonical_path = NULL;
}
- qemu_opts_del(dev->opts);
+ qobject_unref(dev->opts);
+ g_free(dev->id);
}
static void device_class_base_init(ObjectClass *class, void *data)
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index f205331dcf..09e173a558 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -796,23 +796,28 @@ static inline uint64_t virtio_net_supported_guest_offloads(VirtIONet *n)
typedef struct {
VirtIONet *n;
- char *id;
-} FailoverId;
+ DeviceState *dev;
+} FailoverDevice;
/**
- * Set the id of the failover primary device
+ * Set the failover primary device
*
* @opaque: FailoverId to setup
* @opts: opts for device we are handling
* @errp: returns an error if this function fails
*/
-static int failover_set_primary(void *opaque, QemuOpts *opts, Error **errp)
+static int failover_set_primary(DeviceState *dev, void *opaque)
{
- FailoverId *fid = opaque;
- const char *standby_id = qemu_opt_get(opts, "failover_pair_id");
+ FailoverDevice *fdev = opaque;
+ PCIDevice *pci_dev = (PCIDevice *)
+ object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE);
- if (g_strcmp0(standby_id, fid->n->netclient_name) == 0) {
- fid->id = g_strdup(opts->id);
+ if (!pci_dev) {
+ return 0;
+ }
+
+ if (!g_strcmp0(pci_dev->failover_pair_id, fdev->n->netclient_name)) {
+ fdev->dev = dev;
return 1;
}
@@ -820,25 +825,6 @@ static int failover_set_primary(void *opaque, QemuOpts *opts, Error **errp)
}
/**
- * Find the primary device id for this failover virtio-net
- *
- * @n: VirtIONet device
- * @errp: returns an error if this function fails
- */
-static char *failover_find_primary_device_id(VirtIONet *n)
-{
- Error *err = NULL;
- FailoverId fid;
-
- fid.n = n;
- if (!qemu_opts_foreach(qemu_find_opts("device"),
- failover_set_primary, &fid, &err)) {
- return NULL;
- }
- return fid.id;
-}
-
-/**
* Find the primary device for this failover virtio-net
*
* @n: VirtIONet device
@@ -846,39 +832,38 @@ static char *failover_find_primary_device_id(VirtIONet *n)
*/
static DeviceState *failover_find_primary_device(VirtIONet *n)
{
- char *id = failover_find_primary_device_id(n);
-
- if (!id) {
- return NULL;
- }
+ FailoverDevice fdev = {
+ .n = n,
+ };
- return qdev_find_recursive(sysbus_get_default(), id);
+ qbus_walk_children(sysbus_get_default(), failover_set_primary, NULL,
+ NULL, NULL, &fdev);
+ return fdev.dev;
}
static void failover_add_primary(VirtIONet *n, Error **errp)
{
Error *err = NULL;
- QemuOpts *opts;
- char *id;
DeviceState *dev = failover_find_primary_device(n);
if (dev) {
return;
}
- id = failover_find_primary_device_id(n);
- if (!id) {
+ if (!n->primary_opts) {
error_setg(errp, "Primary device not found");
error_append_hint(errp, "Virtio-net failover will not work. Make "
"sure primary device has parameter"
" failover_pair_id=%s\n", n->netclient_name);
return;
}
- opts = qemu_opts_find(qemu_find_opts("device"), id);
- g_assert(opts); /* cannot be NULL because id was found using opts list */
- dev = qdev_device_add(opts, &err);
+
+ dev = qdev_device_add_from_qdict(n->primary_opts,
+ n->primary_opts_from_json,
+ &err);
if (err) {
- qemu_opts_del(opts);
+ qobject_unref(n->primary_opts);
+ n->primary_opts = NULL;
} else {
object_unref(OBJECT(dev));
}
@@ -3304,7 +3289,9 @@ static void virtio_net_migration_state_notifier(Notifier *notifier, void *data)
}
static bool failover_hide_primary_device(DeviceListener *listener,
- QemuOpts *device_opts)
+ const QDict *device_opts,
+ bool from_json,
+ Error **errp)
{
VirtIONet *n = container_of(listener, VirtIONet, primary_listener);
const char *standby_id;
@@ -3312,11 +3299,20 @@ static bool failover_hide_primary_device(DeviceListener *listener,
if (!device_opts) {
return false;
}
- standby_id = qemu_opt_get(device_opts, "failover_pair_id");
+ standby_id = qdict_get_try_str(device_opts, "failover_pair_id");
if (g_strcmp0(standby_id, n->netclient_name) != 0) {
return false;
}
+ if (n->primary_opts) {
+ error_setg(errp, "Cannot attach more than one primary device to '%s'",
+ n->netclient_name);
+ return false;
+ }
+
+ n->primary_opts = qdict_clone_shallow(device_opts);
+ n->primary_opts_from_json = from_json;
+
/* failover_primary_hidden is set during feature negotiation */
return qatomic_read(&n->failover_primary_hidden);
}
@@ -3506,8 +3502,11 @@ static void virtio_net_device_unrealize(DeviceState *dev)
g_free(n->vlans);
if (n->failover) {
+ qobject_unref(n->primary_opts);
device_listener_unregister(&n->primary_listener);
remove_migration_state_change_notifier(&n->migration_state);
+ } else {
+ assert(n->primary_opts == NULL);
}
max_queues = n->multiqueue ? n->max_queues : 1;
diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c
index 7112dc3062..10e6e7c2ab 100644
--- a/hw/pci-bridge/pci_expander_bridge.c
+++ b/hw/pci-bridge/pci_expander_bridge.c
@@ -245,7 +245,7 @@ static void pxb_dev_realize_common(PCIDevice *dev, bool pcie, Error **errp)
} else {
bus = pci_root_bus_new(ds, "pxb-internal", NULL, NULL, 0, TYPE_PXB_BUS);
bds = qdev_new("pci-bridge");
- bds->id = dev_name;
+ bds->id = g_strdup(dev_name);
qdev_prop_set_uint8(bds, PCI_BRIDGE_DEV_PROP_CHASSIS_NR, pxb->bus_nr);
qdev_prop_set_bit(bds, PCI_BRIDGE_DEV_PROP_SHPC, false);
}
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 95451414dd..960e7efcd3 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -1006,7 +1006,7 @@ void ppce500_init(MachineState *machine)
/* Platform Bus Device */
if (pmc->has_platform_bus) {
dev = qdev_new(TYPE_PLATFORM_BUS_DEVICE);
- dev->id = TYPE_PLATFORM_BUS_DEVICE;
+ dev->id = g_strdup(TYPE_PLATFORM_BUS_DEVICE);
qdev_prop_set_uint32(dev, "num_irqs", pmc->platform_bus_num_irqs);
qdev_prop_set_uint32(dev, "mmio_size", pmc->platform_bus_size);
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 4feaa1cb68..5cdf1d4298 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -29,10 +29,10 @@
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
#include "migration/vmstate.h"
+#include "qapi/qmp/qdict.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
-#include "qemu/option.h"
#include "qemu/range.h"
#include "qemu/units.h"
#include "sysemu/kvm.h"
@@ -941,7 +941,7 @@ static void vfio_pci_size_rom(VFIOPCIDevice *vdev)
}
if (vfio_opt_rom_in_denylist(vdev)) {
- if (dev->opts && qemu_opt_get(dev->opts, "rombar")) {
+ if (dev->opts && qdict_haskey(dev->opts, "rombar")) {
warn_report("Device at %s is known to cause system instability"
" issues during option rom execution",
vdev->vbasedev.name);
diff --git a/hw/xen/xen-legacy-backend.c b/hw/xen/xen-legacy-backend.c
index be3cf4a195..085fd31ef7 100644
--- a/hw/xen/xen-legacy-backend.c
+++ b/hw/xen/xen-legacy-backend.c
@@ -276,7 +276,8 @@ static struct XenLegacyDevice *xen_be_get_xendev(const char *type, int dom,
xendev = g_malloc0(ops->size);
object_initialize(&xendev->qdev, ops->size, TYPE_XENBACKEND);
OBJECT(xendev)->free = g_free;
- qdev_set_id(DEVICE(xendev), g_strdup_printf("xen-%s-%d", type, dev));
+ qdev_set_id(DEVICE(xendev), g_strdup_printf("xen-%s-%d", type, dev),
+ &error_fatal);
qdev_realize(DEVICE(xendev), xen_sysbus, &error_fatal);
object_unref(OBJECT(xendev));