pci, pc, virtio, misc bugfixes
A bunch of bugfixes - some of these will make sense for 2.1.2 I put Cc: qemu-stable included where appropriate. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJUGyniAAoJECgfDbjSjVRpxg0H/j4jSEWHm/4uKSly6W4MXxhN LghE5iAaO3awU88RiRPW/m/g6sagD9RuQAHteHkvyZ6py/li0IFvLtl66OczeSgc rnM2n9MeYfi5Q05T+ygjqYY2ynosYhrI4iPmsnKqbqLi+WWwQHFKuYKNcNmQjmJu Sg4KDz+W4p5j/pMUZdgf4lse3PaLXoMy4IA1HC8U1WmwvyNLZrPRTXhFn1hFbxU6 Rf604wz6gkAFvwizt2SoRMOIF4w0meCKemY1wqcwOeDWqP6Bj76RnRCrVR06AgnX ngVsrP5SrWymqwFUP9ZpeNdBOQSxXE3zT1cE6JU3/KUvTBs6Eur4Dnz7g2mPb8I= =nHHz -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging pci, pc, virtio, misc bugfixes A bunch of bugfixes - some of these will make sense for 2.1.2 I put Cc: qemu-stable included where appropriate. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # gpg: Signature made Thu 18 Sep 2014 19:52:18 BST using RSA key ID D28D5469 # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" # gpg: aka "Michael S. Tsirkin <mst@redhat.com>" * remotes/mst/tags/for_upstream: pc: leave more space for BIOS allocations virtio-pci: fix migration for pci bus master vhost-user: fix VIRTIO_NET_F_MRG_RXBUF negotiation virtio-pci: enable bus master for old guests Revert "virtio: don't call device on !vm_running" virtio-net: drop assert on vm stop Revert "rng-egd: remove redundant free" qdev: Move global validation to a single function qdev: Rename qdev_prop_check_global() to qdev_prop_check_globals() test-qdev-global-props: Test handling of hotpluggable and non-device types test-qdev-global-props: Initialize not_used=true for all props test-qdev-global-props: Run tests on subprocess tests: disable global props test for old glib test-qdev-global-props: Trivial comment fix hw/machine: Free old values of string properties Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
		
						commit
						10e11f4d2b
					
				@ -169,6 +169,7 @@ static void rng_egd_set_chardev(Object *obj, const char *value, Error **errp)
 | 
				
			|||||||
    if (b->opened) {
 | 
					    if (b->opened) {
 | 
				
			||||||
        error_set(errp, QERR_PERMISSION_DENIED);
 | 
					        error_set(errp, QERR_PERMISSION_DENIED);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
 | 
					        g_free(s->chr_name);
 | 
				
			||||||
        s->chr_name = g_strdup(value);
 | 
					        s->chr_name = g_strdup(value);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										9
									
								
								configure
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								configure
									
									
									
									
										vendored
									
									
								
							@ -2716,6 +2716,12 @@ for i in $glib_modules; do
 | 
				
			|||||||
    fi
 | 
					    fi
 | 
				
			||||||
done
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# g_test_trap_subprocess added in 2.38. Used by some tests.
 | 
				
			||||||
 | 
					glib_subprocess=yes
 | 
				
			||||||
 | 
					if ! $pkg_config --atleast-version=2.38 glib-2.0; then
 | 
				
			||||||
 | 
					    glib_subprocess=no
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
##########################################
 | 
					##########################################
 | 
				
			||||||
# SHA command probe for modules
 | 
					# SHA command probe for modules
 | 
				
			||||||
if test "$modules" = yes; then
 | 
					if test "$modules" = yes; then
 | 
				
			||||||
@ -4586,6 +4592,9 @@ if test "$bluez" = "yes" ; then
 | 
				
			|||||||
  echo "CONFIG_BLUEZ=y" >> $config_host_mak
 | 
					  echo "CONFIG_BLUEZ=y" >> $config_host_mak
 | 
				
			||||||
  echo "BLUEZ_CFLAGS=$bluez_cflags" >> $config_host_mak
 | 
					  echo "BLUEZ_CFLAGS=$bluez_cflags" >> $config_host_mak
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					if test "glib_subprocess" = "yes" ; then
 | 
				
			||||||
 | 
					  echo "CONFIG_HAS_GLIB_SUBPROCESS_TESTS=y" >> $config_host_mak
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
echo "GLIB_CFLAGS=$glib_cflags" >> $config_host_mak
 | 
					echo "GLIB_CFLAGS=$glib_cflags" >> $config_host_mak
 | 
				
			||||||
if test "$gtk" = "yes" ; then
 | 
					if test "$gtk" = "yes" ; then
 | 
				
			||||||
  echo "CONFIG_GTK=y" >> $config_host_mak
 | 
					  echo "CONFIG_GTK=y" >> $config_host_mak
 | 
				
			||||||
 | 
				
			|||||||
@ -24,6 +24,7 @@ static void machine_set_accel(Object *obj, const char *value, Error **errp)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    MachineState *ms = MACHINE(obj);
 | 
					    MachineState *ms = MACHINE(obj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_free(ms->accel);
 | 
				
			||||||
    ms->accel = g_strdup(value);
 | 
					    ms->accel = g_strdup(value);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -79,6 +80,7 @@ static void machine_set_kernel(Object *obj, const char *value, Error **errp)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    MachineState *ms = MACHINE(obj);
 | 
					    MachineState *ms = MACHINE(obj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_free(ms->kernel_filename);
 | 
				
			||||||
    ms->kernel_filename = g_strdup(value);
 | 
					    ms->kernel_filename = g_strdup(value);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -93,6 +95,7 @@ static void machine_set_initrd(Object *obj, const char *value, Error **errp)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    MachineState *ms = MACHINE(obj);
 | 
					    MachineState *ms = MACHINE(obj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_free(ms->initrd_filename);
 | 
				
			||||||
    ms->initrd_filename = g_strdup(value);
 | 
					    ms->initrd_filename = g_strdup(value);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -107,6 +110,7 @@ static void machine_set_append(Object *obj, const char *value, Error **errp)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    MachineState *ms = MACHINE(obj);
 | 
					    MachineState *ms = MACHINE(obj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_free(ms->kernel_cmdline);
 | 
				
			||||||
    ms->kernel_cmdline = g_strdup(value);
 | 
					    ms->kernel_cmdline = g_strdup(value);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -121,6 +125,7 @@ static void machine_set_dtb(Object *obj, const char *value, Error **errp)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    MachineState *ms = MACHINE(obj);
 | 
					    MachineState *ms = MACHINE(obj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_free(ms->dtb);
 | 
				
			||||||
    ms->dtb = g_strdup(value);
 | 
					    ms->dtb = g_strdup(value);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -135,6 +140,7 @@ static void machine_set_dumpdtb(Object *obj, const char *value, Error **errp)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    MachineState *ms = MACHINE(obj);
 | 
					    MachineState *ms = MACHINE(obj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_free(ms->dumpdtb);
 | 
				
			||||||
    ms->dumpdtb = g_strdup(value);
 | 
					    ms->dumpdtb = g_strdup(value);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -176,6 +182,7 @@ static void machine_set_dt_compatible(Object *obj, const char *value, Error **er
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    MachineState *ms = MACHINE(obj);
 | 
					    MachineState *ms = MACHINE(obj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_free(ms->dt_compatible);
 | 
				
			||||||
    ms->dt_compatible = g_strdup(value);
 | 
					    ms->dt_compatible = g_strdup(value);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -232,6 +239,7 @@ static void machine_set_firmware(Object *obj, const char *value, Error **errp)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    MachineState *ms = MACHINE(obj);
 | 
					    MachineState *ms = MACHINE(obj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_free(ms->firmware);
 | 
				
			||||||
    ms->firmware = g_strdup(value);
 | 
					    ms->firmware = g_strdup(value);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -388,28 +388,12 @@ void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
 | 
				
			|||||||
static int qdev_add_one_global(QemuOpts *opts, void *opaque)
 | 
					static int qdev_add_one_global(QemuOpts *opts, void *opaque)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    GlobalProperty *g;
 | 
					    GlobalProperty *g;
 | 
				
			||||||
    ObjectClass *oc;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    g = g_malloc0(sizeof(*g));
 | 
					    g = g_malloc0(sizeof(*g));
 | 
				
			||||||
    g->driver   = qemu_opt_get(opts, "driver");
 | 
					    g->driver   = qemu_opt_get(opts, "driver");
 | 
				
			||||||
    g->property = qemu_opt_get(opts, "property");
 | 
					    g->property = qemu_opt_get(opts, "property");
 | 
				
			||||||
    g->value    = qemu_opt_get(opts, "value");
 | 
					    g->value    = qemu_opt_get(opts, "value");
 | 
				
			||||||
    oc = object_class_dynamic_cast(object_class_by_name(g->driver),
 | 
					    g->user_provided = true;
 | 
				
			||||||
                                   TYPE_DEVICE);
 | 
					 | 
				
			||||||
    if (oc) {
 | 
					 | 
				
			||||||
        DeviceClass *dc = DEVICE_CLASS(oc);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (dc->hotpluggable) {
 | 
					 | 
				
			||||||
            /* If hotpluggable then skip not_used checking. */
 | 
					 | 
				
			||||||
            g->not_used = false;
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            /* Maybe a typo. */
 | 
					 | 
				
			||||||
            g->not_used = true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        /* Maybe a typo. */
 | 
					 | 
				
			||||||
        g->not_used = true;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    qdev_prop_register_global(g);
 | 
					    qdev_prop_register_global(g);
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -955,19 +955,35 @@ void qdev_prop_register_global_list(GlobalProperty *props)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int qdev_prop_check_global(void)
 | 
					int qdev_prop_check_globals(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    GlobalProperty *prop;
 | 
					    GlobalProperty *prop;
 | 
				
			||||||
    int ret = 0;
 | 
					    int ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QTAILQ_FOREACH(prop, &global_props, next) {
 | 
					    QTAILQ_FOREACH(prop, &global_props, next) {
 | 
				
			||||||
        if (!prop->not_used) {
 | 
					        ObjectClass *oc;
 | 
				
			||||||
 | 
					        DeviceClass *dc;
 | 
				
			||||||
 | 
					        if (prop->used) {
 | 
				
			||||||
            continue;
 | 
					            continue;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        if (!prop->user_provided) {
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        oc = object_class_by_name(prop->driver);
 | 
				
			||||||
 | 
					        oc = object_class_dynamic_cast(oc, TYPE_DEVICE);
 | 
				
			||||||
 | 
					        if (!oc) {
 | 
				
			||||||
 | 
					            error_report("Warning: global %s.%s has invalid class name",
 | 
				
			||||||
 | 
					                       prop->driver, prop->property);
 | 
				
			||||||
            ret = 1;
 | 
					            ret = 1;
 | 
				
			||||||
        error_report("Warning: \"-global %s.%s=%s\" not used",
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        dc = DEVICE_CLASS(oc);
 | 
				
			||||||
 | 
					        if (!dc->hotpluggable && !prop->used) {
 | 
				
			||||||
 | 
					            error_report("Warning: global %s.%s=%s not used",
 | 
				
			||||||
                       prop->driver, prop->property, prop->value);
 | 
					                       prop->driver, prop->property, prop->value);
 | 
				
			||||||
 | 
					            ret = 1;
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -983,7 +999,7 @@ void qdev_prop_set_globals_for_type(DeviceState *dev, const char *typename,
 | 
				
			|||||||
        if (strcmp(typename, prop->driver) != 0) {
 | 
					        if (strcmp(typename, prop->driver) != 0) {
 | 
				
			||||||
            continue;
 | 
					            continue;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        prop->not_used = false;
 | 
					        prop->used = true;
 | 
				
			||||||
        object_property_parse(OBJECT(dev), prop->value, prop->property, &err);
 | 
					        object_property_parse(OBJECT(dev), prop->value, prop->property, &err);
 | 
				
			||||||
        if (err != NULL) {
 | 
					        if (err != NULL) {
 | 
				
			||||||
            error_propagate(errp, err);
 | 
					            error_propagate(errp, err);
 | 
				
			||||||
 | 
				
			|||||||
@ -72,8 +72,10 @@
 | 
				
			|||||||
#define DPRINTF(fmt, ...)
 | 
					#define DPRINTF(fmt, ...)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Leave a chunk of memory at the top of RAM for the BIOS ACPI tables.  */
 | 
					/* Leave a chunk of memory at the top of RAM for the BIOS ACPI tables
 | 
				
			||||||
unsigned acpi_data_size = 0x20000;
 | 
					 * (128K) and other BIOS datastructures (less than 4K reported to be used at
 | 
				
			||||||
 | 
					 * the moment, 32K should be enough for a while).  */
 | 
				
			||||||
 | 
					unsigned acpi_data_size = 0x20000 + 0x8000;
 | 
				
			||||||
void pc_set_legacy_acpi_data_size(void)
 | 
					void pc_set_legacy_acpi_data_size(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    acpi_data_size = 0x10000;
 | 
					    acpi_data_size = 0x10000;
 | 
				
			||||||
 | 
				
			|||||||
@ -163,11 +163,11 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options)
 | 
				
			|||||||
    if (r < 0) {
 | 
					    if (r < 0) {
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if (backend_kernel) {
 | 
				
			||||||
        if (!qemu_has_vnet_hdr_len(options->net_backend,
 | 
					        if (!qemu_has_vnet_hdr_len(options->net_backend,
 | 
				
			||||||
                               sizeof(struct virtio_net_hdr_mrg_rxbuf))) {
 | 
					                               sizeof(struct virtio_net_hdr_mrg_rxbuf))) {
 | 
				
			||||||
            net->dev.features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF);
 | 
					            net->dev.features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    if (backend_kernel) {
 | 
					 | 
				
			||||||
        if (~net->dev.features & net->dev.backend_features) {
 | 
					        if (~net->dev.features & net->dev.backend_features) {
 | 
				
			||||||
            fprintf(stderr, "vhost lacks feature mask %" PRIu64
 | 
					            fprintf(stderr, "vhost lacks feature mask %" PRIu64
 | 
				
			||||||
                   " for backend\n",
 | 
					                   " for backend\n",
 | 
				
			||||||
 | 
				
			|||||||
@ -1125,8 +1125,6 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
 | 
				
			|||||||
        return num_packets;
 | 
					        return num_packets;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert(vdev->vm_running);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (q->async_tx.elem.out_num) {
 | 
					    if (q->async_tx.elem.out_num) {
 | 
				
			||||||
        virtio_queue_set_notification(q->tx_vq, 0);
 | 
					        virtio_queue_set_notification(q->tx_vq, 0);
 | 
				
			||||||
        return num_packets;
 | 
					        return num_packets;
 | 
				
			||||||
 | 
				
			|||||||
@ -86,9 +86,6 @@
 | 
				
			|||||||
 * 12 is historical, and due to x86 page size. */
 | 
					 * 12 is historical, and due to x86 page size. */
 | 
				
			||||||
#define VIRTIO_PCI_QUEUE_ADDR_SHIFT    12
 | 
					#define VIRTIO_PCI_QUEUE_ADDR_SHIFT    12
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Flags track per-device state like workarounds for quirks in older guests. */
 | 
					 | 
				
			||||||
#define VIRTIO_PCI_FLAG_BUS_MASTER_BUG  (1 << 0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size,
 | 
					static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size,
 | 
				
			||||||
                               VirtIOPCIProxy *dev);
 | 
					                               VirtIOPCIProxy *dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -314,12 +311,14 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 | 
				
			|||||||
            msix_unuse_all_vectors(&proxy->pci_dev);
 | 
					            msix_unuse_all_vectors(&proxy->pci_dev);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Linux before 2.6.34 sets the device as OK without enabling
 | 
					        /* Linux before 2.6.34 drives the device without enabling
 | 
				
			||||||
           the PCI device bus master bit. In this case we need to disable
 | 
					           the PCI device bus master bit. Enable it automatically
 | 
				
			||||||
           some safety checks. */
 | 
					           for the guest. This is a PCI spec violation but so is
 | 
				
			||||||
        if ((val & VIRTIO_CONFIG_S_DRIVER_OK) &&
 | 
					           initiating DMA with bus master bit clear. */
 | 
				
			||||||
            !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
 | 
					        if (val == (VIRTIO_CONFIG_S_ACKNOWLEDGE | VIRTIO_CONFIG_S_DRIVER)) {
 | 
				
			||||||
            proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
 | 
					            pci_default_write_config(&proxy->pci_dev, PCI_COMMAND,
 | 
				
			||||||
 | 
					                                     proxy->pci_dev.config[PCI_COMMAND] |
 | 
				
			||||||
 | 
					                                     PCI_COMMAND_MASTER, 1);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case VIRTIO_MSI_CONFIG_VECTOR:
 | 
					    case VIRTIO_MSI_CONFIG_VECTOR:
 | 
				
			||||||
@ -470,13 +469,18 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
 | 
				
			|||||||
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
 | 
					    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
 | 
				
			||||||
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
 | 
					    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint8_t cmd = proxy->pci_dev.config[PCI_COMMAND];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pci_default_write_config(pci_dev, address, val, len);
 | 
					    pci_default_write_config(pci_dev, address, val, len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (range_covers_byte(address, len, PCI_COMMAND) &&
 | 
					    if (range_covers_byte(address, len, PCI_COMMAND) &&
 | 
				
			||||||
        !(pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER) &&
 | 
					        !(pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER) &&
 | 
				
			||||||
        !(proxy->flags & VIRTIO_PCI_FLAG_BUS_MASTER_BUG)) {
 | 
					        (cmd & PCI_COMMAND_MASTER)) {
 | 
				
			||||||
 | 
					        /* Bus driver disables bus mastering - make it act
 | 
				
			||||||
 | 
					         * as a kind of reset to render the device quiescent. */
 | 
				
			||||||
        virtio_pci_stop_ioeventfd(proxy);
 | 
					        virtio_pci_stop_ioeventfd(proxy);
 | 
				
			||||||
        virtio_set_status(vdev, vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK);
 | 
					        virtio_reset(vdev);
 | 
				
			||||||
 | 
					        msix_unuse_all_vectors(&proxy->pci_dev);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -885,11 +889,19 @@ static void virtio_pci_vmstate_change(DeviceState *d, bool running)
 | 
				
			|||||||
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
 | 
					    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (running) {
 | 
					    if (running) {
 | 
				
			||||||
        /* Try to find out if the guest has bus master disabled, but is
 | 
					        /* Linux before 2.6.34 drives the device without enabling
 | 
				
			||||||
           in ready state. Then we have a buggy guest OS. */
 | 
					           the PCI device bus master bit. Enable it automatically
 | 
				
			||||||
        if ((vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) &&
 | 
					           for the guest. This is a PCI spec violation but so is
 | 
				
			||||||
            !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
 | 
					           initiating DMA with bus master bit clear.
 | 
				
			||||||
            proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
 | 
					           Note: this only makes a difference when migrating
 | 
				
			||||||
 | 
					           across QEMU versions from an old QEMU, as for new QEMU
 | 
				
			||||||
 | 
					           bus master and driver bits are always in sync.
 | 
				
			||||||
 | 
					           TODO: consider enabling conditionally for compat machine types. */
 | 
				
			||||||
 | 
					        if (vdev->status & (VIRTIO_CONFIG_S_ACKNOWLEDGE |
 | 
				
			||||||
 | 
					                            VIRTIO_CONFIG_S_DRIVER)) {
 | 
				
			||||||
 | 
					            pci_default_write_config(&proxy->pci_dev, PCI_COMMAND,
 | 
				
			||||||
 | 
					                                     proxy->pci_dev.config[PCI_COMMAND] |
 | 
				
			||||||
 | 
					                                     PCI_COMMAND_MASTER, 1);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        virtio_pci_start_ioeventfd(proxy);
 | 
					        virtio_pci_start_ioeventfd(proxy);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
@ -1030,7 +1042,6 @@ static void virtio_pci_reset(DeviceState *qdev)
 | 
				
			|||||||
    virtio_pci_stop_ioeventfd(proxy);
 | 
					    virtio_pci_stop_ioeventfd(proxy);
 | 
				
			||||||
    virtio_bus_reset(bus);
 | 
					    virtio_bus_reset(bus);
 | 
				
			||||||
    msix_unuse_all_vectors(&proxy->pci_dev);
 | 
					    msix_unuse_all_vectors(&proxy->pci_dev);
 | 
				
			||||||
    proxy->flags &= ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static Property virtio_pci_properties[] = {
 | 
					static Property virtio_pci_properties[] = {
 | 
				
			||||||
 | 
				
			|||||||
@ -1108,10 +1108,7 @@ static void virtio_vmstate_change(void *opaque, int running, RunState state)
 | 
				
			|||||||
    BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
 | 
					    BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
 | 
				
			||||||
    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
 | 
					    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
 | 
				
			||||||
    bool backend_run = running && (vdev->status & VIRTIO_CONFIG_S_DRIVER_OK);
 | 
					    bool backend_run = running && (vdev->status & VIRTIO_CONFIG_S_DRIVER_OK);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (running) {
 | 
					 | 
				
			||||||
    vdev->vm_running = running;
 | 
					    vdev->vm_running = running;
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (backend_run) {
 | 
					    if (backend_run) {
 | 
				
			||||||
        virtio_set_status(vdev, vdev->status);
 | 
					        virtio_set_status(vdev, vdev->status);
 | 
				
			||||||
@ -1124,10 +1121,6 @@ static void virtio_vmstate_change(void *opaque, int running, RunState state)
 | 
				
			|||||||
    if (!backend_run) {
 | 
					    if (!backend_run) {
 | 
				
			||||||
        virtio_set_status(vdev, vdev->status);
 | 
					        virtio_set_status(vdev, vdev->status);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!running) {
 | 
					 | 
				
			||||||
        vdev->vm_running = running;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void virtio_init(VirtIODevice *vdev, const char *name,
 | 
					void virtio_init(VirtIODevice *vdev, const char *name,
 | 
				
			||||||
 | 
				
			|||||||
@ -242,16 +242,16 @@ struct PropertyInfo {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * GlobalProperty:
 | 
					 * GlobalProperty:
 | 
				
			||||||
 * @not_used: Track use of a global property.  Defaults to false in all C99
 | 
					 * @user_provided: Set to true if property comes from user-provided config
 | 
				
			||||||
 * struct initializations.
 | 
					 * (command-line or config file).
 | 
				
			||||||
 *
 | 
					 * @used: Set to true if property was used when initializing a device.
 | 
				
			||||||
 * This prevents reports of .compat_props when they are not used.
 | 
					 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
typedef struct GlobalProperty {
 | 
					typedef struct GlobalProperty {
 | 
				
			||||||
    const char *driver;
 | 
					    const char *driver;
 | 
				
			||||||
    const char *property;
 | 
					    const char *property;
 | 
				
			||||||
    const char *value;
 | 
					    const char *value;
 | 
				
			||||||
    bool not_used;
 | 
					    bool user_provided;
 | 
				
			||||||
 | 
					    bool used;
 | 
				
			||||||
    QTAILQ_ENTRY(GlobalProperty) next;
 | 
					    QTAILQ_ENTRY(GlobalProperty) next;
 | 
				
			||||||
} GlobalProperty;
 | 
					} GlobalProperty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -177,7 +177,7 @@ void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void qdev_prop_register_global(GlobalProperty *prop);
 | 
					void qdev_prop_register_global(GlobalProperty *prop);
 | 
				
			||||||
void qdev_prop_register_global_list(GlobalProperty *props);
 | 
					void qdev_prop_register_global_list(GlobalProperty *props);
 | 
				
			||||||
int qdev_prop_check_global(void);
 | 
					int qdev_prop_check_globals(void);
 | 
				
			||||||
void qdev_prop_set_globals(DeviceState *dev, Error **errp);
 | 
					void qdev_prop_set_globals(DeviceState *dev, Error **errp);
 | 
				
			||||||
void qdev_prop_set_globals_for_type(DeviceState *dev, const char *typename,
 | 
					void qdev_prop_set_globals_for_type(DeviceState *dev, const char *typename,
 | 
				
			||||||
                                    Error **errp);
 | 
					                                    Error **errp);
 | 
				
			||||||
 | 
				
			|||||||
@ -58,7 +58,7 @@ check-unit-y += tests/test-int128$(EXESUF)
 | 
				
			|||||||
# all code tested by test-int128 is inside int128.h
 | 
					# all code tested by test-int128 is inside int128.h
 | 
				
			||||||
gcov-files-test-int128-y =
 | 
					gcov-files-test-int128-y =
 | 
				
			||||||
check-unit-y += tests/test-bitops$(EXESUF)
 | 
					check-unit-y += tests/test-bitops$(EXESUF)
 | 
				
			||||||
check-unit-y += tests/test-qdev-global-props$(EXESUF)
 | 
					check-unit-$(CONFIG_HAS_GLIB_SUBPROCESS_TESTS) += tests/test-qdev-global-props$(EXESUF)
 | 
				
			||||||
check-unit-y += tests/check-qom-interface$(EXESUF)
 | 
					check-unit-y += tests/check-qom-interface$(EXESUF)
 | 
				
			||||||
gcov-files-check-qom-interface-y = qom/object.c
 | 
					gcov-files-check-qom-interface-y = qom/object.c
 | 
				
			||||||
check-unit-$(CONFIG_POSIX) += tests/test-vmstate$(EXESUF)
 | 
					check-unit-$(CONFIG_POSIX) += tests/test-vmstate$(EXESUF)
 | 
				
			||||||
 | 
				
			|||||||
@ -65,7 +65,7 @@ static const TypeInfo static_prop_type = {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Test simple static property setting to default value */
 | 
					/* Test simple static property setting to default value */
 | 
				
			||||||
static void test_static_prop(void)
 | 
					static void test_static_prop_subprocess(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    MyType *mt;
 | 
					    MyType *mt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -75,8 +75,16 @@ static void test_static_prop(void)
 | 
				
			|||||||
    g_assert_cmpuint(mt->prop1, ==, PROP_DEFAULT);
 | 
					    g_assert_cmpuint(mt->prop1, ==, PROP_DEFAULT);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void test_static_prop(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_test_trap_subprocess("/qdev/properties/static/default/subprocess", 0, 0);
 | 
				
			||||||
 | 
					    g_test_trap_assert_passed();
 | 
				
			||||||
 | 
					    g_test_trap_assert_stderr("");
 | 
				
			||||||
 | 
					    g_test_trap_assert_stdout("");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Test setting of static property using global properties */
 | 
					/* Test setting of static property using global properties */
 | 
				
			||||||
static void test_static_globalprop(void)
 | 
					static void test_static_globalprop_subprocess(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    MyType *mt;
 | 
					    MyType *mt;
 | 
				
			||||||
    static GlobalProperty props[] = {
 | 
					    static GlobalProperty props[] = {
 | 
				
			||||||
@ -93,10 +101,21 @@ static void test_static_globalprop(void)
 | 
				
			|||||||
    g_assert_cmpuint(mt->prop2, ==, PROP_DEFAULT);
 | 
					    g_assert_cmpuint(mt->prop2, ==, PROP_DEFAULT);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void test_static_globalprop(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_test_trap_subprocess("/qdev/properties/static/global/subprocess", 0, 0);
 | 
				
			||||||
 | 
					    g_test_trap_assert_passed();
 | 
				
			||||||
 | 
					    g_test_trap_assert_stderr("");
 | 
				
			||||||
 | 
					    g_test_trap_assert_stdout("");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define TYPE_DYNAMIC_PROPS "dynamic-prop-type"
 | 
					#define TYPE_DYNAMIC_PROPS "dynamic-prop-type"
 | 
				
			||||||
#define DYNAMIC_TYPE(obj) \
 | 
					#define DYNAMIC_TYPE(obj) \
 | 
				
			||||||
    OBJECT_CHECK(MyType, (obj), TYPE_DYNAMIC_PROPS)
 | 
					    OBJECT_CHECK(MyType, (obj), TYPE_DYNAMIC_PROPS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TYPE_UNUSED_HOTPLUG   "hotplug-type"
 | 
				
			||||||
 | 
					#define TYPE_UNUSED_NOHOTPLUG "nohotplug-type"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void prop1_accessor(Object *obj,
 | 
					static void prop1_accessor(Object *obj,
 | 
				
			||||||
                           Visitor *v,
 | 
					                           Visitor *v,
 | 
				
			||||||
                           void *opaque,
 | 
					                           void *opaque,
 | 
				
			||||||
@ -143,14 +162,56 @@ static const TypeInfo dynamic_prop_type = {
 | 
				
			|||||||
    .class_init = dynamic_class_init,
 | 
					    .class_init = dynamic_class_init,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Test setting of static property using global properties */
 | 
					static void hotplug_class_init(ObjectClass *oc, void *data)
 | 
				
			||||||
static void test_dynamic_globalprop(void)
 | 
					{
 | 
				
			||||||
 | 
					    DeviceClass *dc = DEVICE_CLASS(oc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dc->realize = NULL;
 | 
				
			||||||
 | 
					    dc->hotpluggable = true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const TypeInfo hotplug_type = {
 | 
				
			||||||
 | 
					    .name = TYPE_UNUSED_HOTPLUG,
 | 
				
			||||||
 | 
					    .parent = TYPE_DEVICE,
 | 
				
			||||||
 | 
					    .instance_size = sizeof(MyType),
 | 
				
			||||||
 | 
					    .instance_init = dynamic_instance_init,
 | 
				
			||||||
 | 
					    .class_init = hotplug_class_init,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void nohotplug_class_init(ObjectClass *oc, void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    DeviceClass *dc = DEVICE_CLASS(oc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dc->realize = NULL;
 | 
				
			||||||
 | 
					    dc->hotpluggable = false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const TypeInfo nohotplug_type = {
 | 
				
			||||||
 | 
					    .name = TYPE_UNUSED_NOHOTPLUG,
 | 
				
			||||||
 | 
					    .parent = TYPE_DEVICE,
 | 
				
			||||||
 | 
					    .instance_size = sizeof(MyType),
 | 
				
			||||||
 | 
					    .instance_init = dynamic_instance_init,
 | 
				
			||||||
 | 
					    .class_init = nohotplug_class_init,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TYPE_NONDEVICE "nondevice-type"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const TypeInfo nondevice_type = {
 | 
				
			||||||
 | 
					    .name = TYPE_NONDEVICE,
 | 
				
			||||||
 | 
					    .parent = TYPE_OBJECT,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Test setting of dynamic properties using global properties */
 | 
				
			||||||
 | 
					static void test_dynamic_globalprop_subprocess(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    MyType *mt;
 | 
					    MyType *mt;
 | 
				
			||||||
    static GlobalProperty props[] = {
 | 
					    static GlobalProperty props[] = {
 | 
				
			||||||
        { TYPE_DYNAMIC_PROPS, "prop1", "101" },
 | 
					        { TYPE_DYNAMIC_PROPS, "prop1", "101", true },
 | 
				
			||||||
        { TYPE_DYNAMIC_PROPS, "prop2", "102" },
 | 
					        { TYPE_DYNAMIC_PROPS, "prop2", "102", true },
 | 
				
			||||||
        { TYPE_DYNAMIC_PROPS"-bad", "prop3", "103", true },
 | 
					        { TYPE_DYNAMIC_PROPS"-bad", "prop3", "103", true },
 | 
				
			||||||
 | 
					        { TYPE_UNUSED_HOTPLUG, "prop4", "104", true },
 | 
				
			||||||
 | 
					        { TYPE_UNUSED_NOHOTPLUG, "prop5", "105", true },
 | 
				
			||||||
 | 
					        { TYPE_NONDEVICE, "prop6", "106", true },
 | 
				
			||||||
        {}
 | 
					        {}
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    int all_used;
 | 
					    int all_used;
 | 
				
			||||||
@ -162,8 +223,67 @@ static void test_dynamic_globalprop(void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    g_assert_cmpuint(mt->prop1, ==, 101);
 | 
					    g_assert_cmpuint(mt->prop1, ==, 101);
 | 
				
			||||||
    g_assert_cmpuint(mt->prop2, ==, 102);
 | 
					    g_assert_cmpuint(mt->prop2, ==, 102);
 | 
				
			||||||
    all_used = qdev_prop_check_global();
 | 
					    all_used = qdev_prop_check_globals();
 | 
				
			||||||
    g_assert_cmpuint(all_used, ==, 1);
 | 
					    g_assert_cmpuint(all_used, ==, 1);
 | 
				
			||||||
 | 
					    g_assert(props[0].used);
 | 
				
			||||||
 | 
					    g_assert(props[1].used);
 | 
				
			||||||
 | 
					    g_assert(!props[2].used);
 | 
				
			||||||
 | 
					    g_assert(!props[3].used);
 | 
				
			||||||
 | 
					    g_assert(!props[4].used);
 | 
				
			||||||
 | 
					    g_assert(!props[5].used);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void test_dynamic_globalprop(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_test_trap_subprocess("/qdev/properties/dynamic/global/subprocess", 0, 0);
 | 
				
			||||||
 | 
					    g_test_trap_assert_passed();
 | 
				
			||||||
 | 
					    g_test_trap_assert_stderr_unmatched("*prop1*");
 | 
				
			||||||
 | 
					    g_test_trap_assert_stderr_unmatched("*prop2*");
 | 
				
			||||||
 | 
					    g_test_trap_assert_stderr("*Warning: global dynamic-prop-type-bad.prop3 has invalid class name\n*");
 | 
				
			||||||
 | 
					    g_test_trap_assert_stderr_unmatched("*prop4*");
 | 
				
			||||||
 | 
					    g_test_trap_assert_stderr("*Warning: global nohotplug-type.prop5=105 not used\n*");
 | 
				
			||||||
 | 
					    g_test_trap_assert_stderr("*Warning: global nondevice-type.prop6 has invalid class name\n*");
 | 
				
			||||||
 | 
					    g_test_trap_assert_stdout("");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Test setting of dynamic properties using user_provided=false properties */
 | 
				
			||||||
 | 
					static void test_dynamic_globalprop_nouser_subprocess(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    MyType *mt;
 | 
				
			||||||
 | 
					    static GlobalProperty props[] = {
 | 
				
			||||||
 | 
					        { TYPE_DYNAMIC_PROPS, "prop1", "101" },
 | 
				
			||||||
 | 
					        { TYPE_DYNAMIC_PROPS, "prop2", "102" },
 | 
				
			||||||
 | 
					        { TYPE_DYNAMIC_PROPS"-bad", "prop3", "103" },
 | 
				
			||||||
 | 
					        { TYPE_UNUSED_HOTPLUG, "prop4", "104" },
 | 
				
			||||||
 | 
					        { TYPE_UNUSED_NOHOTPLUG, "prop5", "105" },
 | 
				
			||||||
 | 
					        { TYPE_NONDEVICE, "prop6", "106" },
 | 
				
			||||||
 | 
					        {}
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    int all_used;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qdev_prop_register_global_list(props);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mt = DYNAMIC_TYPE(object_new(TYPE_DYNAMIC_PROPS));
 | 
				
			||||||
 | 
					    qdev_init_nofail(DEVICE(mt));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_assert_cmpuint(mt->prop1, ==, 101);
 | 
				
			||||||
 | 
					    g_assert_cmpuint(mt->prop2, ==, 102);
 | 
				
			||||||
 | 
					    all_used = qdev_prop_check_globals();
 | 
				
			||||||
 | 
					    g_assert_cmpuint(all_used, ==, 0);
 | 
				
			||||||
 | 
					    g_assert(props[0].used);
 | 
				
			||||||
 | 
					    g_assert(props[1].used);
 | 
				
			||||||
 | 
					    g_assert(!props[2].used);
 | 
				
			||||||
 | 
					    g_assert(!props[3].used);
 | 
				
			||||||
 | 
					    g_assert(!props[4].used);
 | 
				
			||||||
 | 
					    g_assert(!props[5].used);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void test_dynamic_globalprop_nouser(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    g_test_trap_subprocess("/qdev/properties/dynamic/global/nouser/subprocess", 0, 0);
 | 
				
			||||||
 | 
					    g_test_trap_assert_passed();
 | 
				
			||||||
 | 
					    g_test_trap_assert_stderr("");
 | 
				
			||||||
 | 
					    g_test_trap_assert_stdout("");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, char **argv)
 | 
					int main(int argc, char **argv)
 | 
				
			||||||
@ -173,10 +293,29 @@ int main(int argc, char **argv)
 | 
				
			|||||||
    module_call_init(MODULE_INIT_QOM);
 | 
					    module_call_init(MODULE_INIT_QOM);
 | 
				
			||||||
    type_register_static(&static_prop_type);
 | 
					    type_register_static(&static_prop_type);
 | 
				
			||||||
    type_register_static(&dynamic_prop_type);
 | 
					    type_register_static(&dynamic_prop_type);
 | 
				
			||||||
 | 
					    type_register_static(&hotplug_type);
 | 
				
			||||||
 | 
					    type_register_static(&nohotplug_type);
 | 
				
			||||||
 | 
					    type_register_static(&nondevice_type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    g_test_add_func("/qdev/properties/static/default", test_static_prop);
 | 
					    g_test_add_func("/qdev/properties/static/default/subprocess",
 | 
				
			||||||
    g_test_add_func("/qdev/properties/static/global", test_static_globalprop);
 | 
					                    test_static_prop_subprocess);
 | 
				
			||||||
    g_test_add_func("/qdev/properties/dynamic/global", test_dynamic_globalprop);
 | 
					    g_test_add_func("/qdev/properties/static/default",
 | 
				
			||||||
 | 
					                    test_static_prop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_test_add_func("/qdev/properties/static/global/subprocess",
 | 
				
			||||||
 | 
					                    test_static_globalprop_subprocess);
 | 
				
			||||||
 | 
					    g_test_add_func("/qdev/properties/static/global",
 | 
				
			||||||
 | 
					                    test_static_globalprop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_test_add_func("/qdev/properties/dynamic/global/subprocess",
 | 
				
			||||||
 | 
					                    test_dynamic_globalprop_subprocess);
 | 
				
			||||||
 | 
					    g_test_add_func("/qdev/properties/dynamic/global",
 | 
				
			||||||
 | 
					                    test_dynamic_globalprop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g_test_add_func("/qdev/properties/dynamic/global/nouser/subprocess",
 | 
				
			||||||
 | 
					                    test_dynamic_globalprop_nouser_subprocess);
 | 
				
			||||||
 | 
					    g_test_add_func("/qdev/properties/dynamic/global/nouser",
 | 
				
			||||||
 | 
					                    test_dynamic_globalprop_nouser);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    g_test_run();
 | 
					    g_test_run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2
									
								
								vl.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								vl.c
									
									
									
									
									
								
							@ -4542,7 +4542,7 @@ int main(int argc, char **argv, char **envp)
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qdev_prop_check_global();
 | 
					    qdev_prop_check_globals();
 | 
				
			||||||
    if (vmstate_dump_file) {
 | 
					    if (vmstate_dump_file) {
 | 
				
			||||||
        /* dump and exit */
 | 
					        /* dump and exit */
 | 
				
			||||||
        dump_vmstate_json_to_file(vmstate_dump_file);
 | 
					        dump_vmstate_json_to_file(vmstate_dump_file);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user