All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/44] Make qdev static property API usable by any QOM type
@ 2020-11-04 15:59 Eduardo Habkost
  2020-11-04 15:59 ` [PATCH v2 01/44] cs4231: Get rid of empty property array Eduardo Habkost
                   ` (45 more replies)
  0 siblings, 46 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 15:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

This series refactor the qdev property code so the static
property system can be used by any QOM type.  As an example, at
the end of the series some properties in TYPE_MACHINE are
converted to static properties to demonstrate the new API.

Changes v1 -> v2
----------------

* Rename functions and source files to call the new feature
  "field property" instead of "static property"

* Change the API signature from an array-based interface similar
  to device_class_set_props() to a object_property_add()-like
  interface.

  This means instead of doing this:

    object_class_property_add_static_props(oc, my_array_of_props);

  properties are registered like this:

    object_class_property_add_field(oc, "property-name"
                                    PROP_XXX(MyState, my_field),
                                    prop_allow_set_always);

  where PROP_XXX is a PROP_* macro like PROP_STRING, PROP_BOOL,
  etc.

* Make Property.name optional.  Rename it to qdev_prop_name,
  and restrict its usage to qdev property tracking code.

* Make allow_set callback mandatory, to avoid ambiguity

* Big cleanup of array property code.  We don't need a custom
  release function for array elements anymore, because we don't
  need to save the property name in the Property struct anymore.

* Moved UUID property to qdev-properties-system, because
  it still has dependencies on qdev code

Eduardo Habkost (44):
  cs4231: Get rid of empty property array
  cpu: Move cpu_common_props to hw/core/cpu.c
  qdev: Move property code to qdev-properties.[ch]
  qdev: Check dev->realized at set_size()
  sparc: Check dev->realized at sparc_set_nwindows()
  qdev: Don't use dev->id on set_size32() error message
  qdev: Make PropertyInfo.print method get Object* argument
  qdev: Make bit_prop_set() get Object* argument
  qdev: Make qdev_get_prop_ptr() get Object* arg
  qdev: Make qdev_find_global_prop() get Object* argument
  qdev: Make check_prop_still_unset() get Object* argument
  qdev: Make error_set_from_qdev_prop_error() get Object* argument
  qdev: Move UUID property to qdev-properties-system.c
  qdev: Move softmmu properties to qdev-properties-system.h
  qdev: Reuse DEFINE_PROP in all DEFINE_PROP_* macros
  sparc: Use DEFINE_PROP for nwindows property
  qdev: Get just property name at error_set_from_qdev_prop_error()
  qdev: Avoid using prop->name unnecessarily
  qdev: Add name parameter to qdev_class_add_property()
  qdev: Add name argument to PropertyInfo.create method
  qdev: Wrap getters and setters in separate helpers
  qdev: Move dev->realized check to qdev_property_set()
  qdev: Make PropertyInfo.create return ObjectProperty*
  qdev: Make qdev_class_add_property() more flexible
  qdev: Separate generic and device-specific property registration
  qdev: Rename Property.name to Property.qdev_prop_name
  qdev: Don't set qdev_prop_name for array elements
  qdev: Avoid unnecessary DeviceState* variable at set_prop_arraylen()
  qdev: Remove ArrayElementProperty.propname field
  qdev: Get rid of ArrayElementProperty struct
  qdev: Reuse object_property_add_field() when adding array elements
  qom: Add allow_set callback to ObjectProperty
  qdev: Make qdev_prop_allow_set() a ObjectProperty.allow_set callback
  qdev: Make qdev_propinfo_get_uint16() static
  qdev: Rename qdev_propinfo_* to field_prop_*
  qdev: Rename qdev_get_prop_ptr() to object_field_prop_ptr()
  qdev: Move qdev_prop_tpm declaration to tpm_prop.h
  qdev: Rename qdev_prop_* to prop_info_*
  qdev: PROP_* macros
  qdev: Move core field property code to QOM
  qdev: Move base property types to qom/property-types.c
  qom: Include static property API reference in documentation
  tests: Use field properties at check-qom-proplist test case
  machine: Register most properties as field properties

 docs/devel/qom.rst                    |  17 +-
 audio/audio.h                         |   1 +
 hw/core/qdev-prop-internal.h          |  30 -
 hw/tpm/tpm_prop.h                     |   2 +
 include/hw/block/block.h              |   1 +
 include/hw/core/cpu.h                 |   1 -
 include/hw/qdev-core.h                |  37 --
 include/hw/qdev-properties-system.h   |  77 +++
 include/hw/qdev-properties.h          | 244 +-------
 include/net/net.h                     |   1 +
 include/qom/field-property-internal.h |  43 ++
 include/qom/field-property.h          | 112 ++++
 include/qom/object.h                  |  38 ++
 include/qom/property-types.h          | 292 ++++++++++
 backends/tpm/tpm_util.c               |  16 +-
 cpu.c                                 |  15 -
 hw/acpi/vmgenid.c                     |   1 +
 hw/arm/pxa2xx.c                       |   1 +
 hw/arm/strongarm.c                    |   1 +
 hw/audio/cs4231.c                     |   5 -
 hw/block/fdc.c                        |   1 +
 hw/block/m25p80.c                     |   1 +
 hw/block/nand.c                       |   1 +
 hw/block/onenand.c                    |   1 +
 hw/block/pflash_cfi01.c               |   1 +
 hw/block/pflash_cfi02.c               |   1 +
 hw/block/vhost-user-blk.c             |   1 +
 hw/block/xen-block.c                  |  11 +-
 hw/char/avr_usart.c                   |   1 +
 hw/char/bcm2835_aux.c                 |   1 +
 hw/char/cadence_uart.c                |   1 +
 hw/char/cmsdk-apb-uart.c              |   1 +
 hw/char/debugcon.c                    |   1 +
 hw/char/digic-uart.c                  |   1 +
 hw/char/escc.c                        |   1 +
 hw/char/etraxfs_ser.c                 |   1 +
 hw/char/exynos4210_uart.c             |   1 +
 hw/char/grlib_apbuart.c               |   1 +
 hw/char/ibex_uart.c                   |   1 +
 hw/char/imx_serial.c                  |   1 +
 hw/char/ipoctal232.c                  |   1 +
 hw/char/lm32_juart.c                  |   1 +
 hw/char/lm32_uart.c                   |   1 +
 hw/char/mcf_uart.c                    |   1 +
 hw/char/milkymist-uart.c              |   1 +
 hw/char/nrf51_uart.c                  |   1 +
 hw/char/parallel.c                    |   1 +
 hw/char/pl011.c                       |   1 +
 hw/char/renesas_sci.c                 |   1 +
 hw/char/sclpconsole-lm.c              |   1 +
 hw/char/sclpconsole.c                 |   1 +
 hw/char/serial-pci-multi.c            |   1 +
 hw/char/serial.c                      |   1 +
 hw/char/spapr_vty.c                   |   1 +
 hw/char/stm32f2xx_usart.c             |   1 +
 hw/char/terminal3270.c                |   1 +
 hw/char/virtio-console.c              |   1 +
 hw/char/xilinx_uartlite.c             |   1 +
 hw/core/cpu.c                         |  15 +
 hw/core/machine.c                     | 256 ++------
 hw/core/qdev-properties-system.c      | 258 ++++-----
 hw/core/qdev-properties.c             | 806 +++-----------------------
 hw/core/qdev.c                        | 120 ----
 hw/hyperv/vmbus.c                     |   1 +
 hw/i386/kvm/i8254.c                   |   1 +
 hw/ide/qdev.c                         |   1 +
 hw/intc/arm_gicv3_common.c            |   2 +-
 hw/intc/rx_icu.c                      |   4 +-
 hw/ipmi/ipmi_bmc_extern.c             |   1 +
 hw/ipmi/ipmi_bmc_sim.c                |   1 +
 hw/misc/allwinner-sid.c               |   1 +
 hw/misc/arm_sysctl.c                  |   4 +-
 hw/misc/ivshmem.c                     |   1 +
 hw/misc/mac_via.c                     |   1 +
 hw/misc/sifive_u_otp.c                |   1 +
 hw/net/e1000e.c                       |   6 +-
 hw/net/rocker/rocker.c                |   1 +
 hw/nvram/eeprom_at24c.c               |   1 +
 hw/nvram/spapr_nvram.c                |   1 +
 hw/pci-bridge/gen_pcie_root_port.c    |   1 +
 hw/pci/pci.c                          |   1 +
 hw/ppc/pnv_pnor.c                     |   1 +
 hw/rdma/vmw/pvrdma_main.c             |   1 +
 hw/rtc/mc146818rtc.c                  |   1 +
 hw/s390x/css.c                        |  13 +-
 hw/s390x/s390-pci-bus.c               |  10 +-
 hw/scsi/scsi-disk.c                   |   1 +
 hw/scsi/scsi-generic.c                |   1 +
 hw/scsi/vhost-user-scsi.c             |   1 +
 hw/sd/sd.c                            |   1 +
 hw/usb/ccid-card-passthru.c           |   1 +
 hw/usb/dev-serial.c                   |   1 +
 hw/usb/redirect.c                     |   1 +
 hw/vfio/pci-quirks.c                  |  11 +-
 hw/vfio/pci.c                         |   1 +
 hw/virtio/vhost-user-fs.c             |   1 +
 hw/virtio/vhost-user-vsock.c          |   1 +
 hw/virtio/virtio-iommu-pci.c          |   1 +
 hw/xen/xen_pt.c                       |   1 +
 migration/migration.c                 |   1 +
 qom/field-property.c                  | 108 ++++
 qom/object.c                          |  16 +
 qom/property-types.c                  | 545 +++++++++++++++++
 softmmu/qdev-monitor.c                |   9 +-
 target/arm/cpu.c                      |   2 +-
 target/sparc/cpu.c                    |   5 +-
 tests/check-qom-proplist.c            |  64 +-
 qom/meson.build                       |   2 +
 108 files changed, 1630 insertions(+), 1639 deletions(-)
 delete mode 100644 hw/core/qdev-prop-internal.h
 create mode 100644 include/hw/qdev-properties-system.h
 create mode 100644 include/qom/field-property-internal.h
 create mode 100644 include/qom/field-property.h
 create mode 100644 include/qom/property-types.h
 create mode 100644 qom/field-property.c
 create mode 100644 qom/property-types.c

-- 
2.28.0




^ permalink raw reply	[flat|nested] 77+ messages in thread

* [PATCH v2 01/44] cs4231: Get rid of empty property array
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
@ 2020-11-04 15:59 ` Eduardo Habkost
  2020-11-04 15:59 ` [PATCH v2 02/44] cpu: Move cpu_common_props to hw/core/cpu.c Eduardo Habkost
                   ` (44 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 15:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Gerd Hoffmann, Igor Mammedov,
	Paolo Bonzini, Stefan Berger

An empty props array is unnecessary, we can just not call
device_class_set_props().

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: qemu-devel@nongnu.org
---
 hw/audio/cs4231.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/hw/audio/cs4231.c b/hw/audio/cs4231.c
index 8e9554ce9b..209c05a0a0 100644
--- a/hw/audio/cs4231.c
+++ b/hw/audio/cs4231.c
@@ -160,17 +160,12 @@ static void cs4231_init(Object *obj)
     sysbus_init_irq(dev, &s->irq);
 }
 
-static Property cs4231_properties[] = {
-    {.name = NULL},
-};
-
 static void cs4231_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
 
     dc->reset = cs_reset;
     dc->vmsd = &vmstate_cs4231;
-    device_class_set_props(dc, cs4231_properties);
 }
 
 static const TypeInfo cs4231_info = {
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 02/44] cpu: Move cpu_common_props to hw/core/cpu.c
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
  2020-11-04 15:59 ` [PATCH v2 01/44] cs4231: Get rid of empty property array Eduardo Habkost
@ 2020-11-04 15:59 ` Eduardo Habkost
  2020-11-04 15:59 ` [PATCH v2 03/44] qdev: Move property code to qdev-properties.[ch] Eduardo Habkost
                   ` (43 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 15:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

There's no reason to keep the property list separate from the CPU
class code.  Move the variable to hw/core/cpu.c and make it
static.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
Cc: qemu-devel@nongnu.org
---
 include/hw/core/cpu.h |  1 -
 cpu.c                 | 15 ---------------
 hw/core/cpu.c         | 15 +++++++++++++++
 3 files changed, 15 insertions(+), 16 deletions(-)

diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 3d92c967ff..8e7552910d 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -1111,7 +1111,6 @@ AddressSpace *cpu_get_address_space(CPUState *cpu, int asidx);
 
 void QEMU_NORETURN cpu_abort(CPUState *cpu, const char *fmt, ...)
     GCC_FMT_ATTR(2, 3);
-extern Property cpu_common_props[];
 void cpu_exec_initfn(CPUState *cpu);
 void cpu_exec_realizefn(CPUState *cpu, Error **errp);
 void cpu_exec_unrealizefn(CPUState *cpu);
diff --git a/cpu.c b/cpu.c
index 0be5dcb6f3..0c485cdf2d 100644
--- a/cpu.c
+++ b/cpu.c
@@ -144,21 +144,6 @@ void cpu_exec_unrealizefn(CPUState *cpu)
 #endif
 }
 
-Property cpu_common_props[] = {
-#ifndef CONFIG_USER_ONLY
-    /* Create a memory property for softmmu CPU object,
-     * so users can wire up its memory. (This can't go in hw/core/cpu.c
-     * because that file is compiled only once for both user-mode
-     * and system builds.) The default if no link is set up is to use
-     * the system address space.
-     */
-    DEFINE_PROP_LINK("memory", CPUState, memory, TYPE_MEMORY_REGION,
-                     MemoryRegion *),
-#endif
-    DEFINE_PROP_BOOL("start-powered-off", CPUState, start_powered_off, false),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
 void cpu_exec_initfn(CPUState *cpu)
 {
     cpu->as = NULL;
diff --git a/hw/core/cpu.c b/hw/core/cpu.c
index 576fa1d7ba..5c89c858aa 100644
--- a/hw/core/cpu.c
+++ b/hw/core/cpu.c
@@ -393,6 +393,21 @@ static vaddr cpu_adjust_watchpoint_address(CPUState *cpu, vaddr addr, int len)
     return addr;
 }
 
+static Property cpu_common_props[] = {
+#ifndef CONFIG_USER_ONLY
+    /* Create a memory property for softmmu CPU object,
+     * so users can wire up its memory. (This can't go in hw/core/cpu.c
+     * because that file is compiled only once for both user-mode
+     * and system builds.) The default if no link is set up is to use
+     * the system address space.
+     */
+    DEFINE_PROP_LINK("memory", CPUState, memory, TYPE_MEMORY_REGION,
+                     MemoryRegion *),
+#endif
+    DEFINE_PROP_BOOL("start-powered-off", CPUState, start_powered_off, false),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void cpu_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 03/44] qdev: Move property code to qdev-properties.[ch]
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
  2020-11-04 15:59 ` [PATCH v2 01/44] cs4231: Get rid of empty property array Eduardo Habkost
  2020-11-04 15:59 ` [PATCH v2 02/44] cpu: Move cpu_common_props to hw/core/cpu.c Eduardo Habkost
@ 2020-11-04 15:59 ` Eduardo Habkost
  2020-11-04 15:59 ` [PATCH v2 04/44] qdev: Check dev->realized at set_size() Eduardo Habkost
                   ` (42 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 15:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

Move everything related to Property and PropertyInfo to
qdev-properties.[ch] to make it easier to refactor that code.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 include/hw/qdev-core.h       |  37 -----------
 include/hw/qdev-properties.h |  38 +++++++++++
 hw/core/qdev-properties.c    | 120 +++++++++++++++++++++++++++++++++++
 hw/core/qdev.c               | 120 -----------------------------------
 softmmu/qdev-monitor.c       |   1 +
 5 files changed, 159 insertions(+), 157 deletions(-)

diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 5e737195b5..d75cf47145 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -274,43 +274,6 @@ struct BusState {
     ResettableState reset;
 };
 
-/**
- * Property:
- * @set_default: true if the default value should be set from @defval,
- *    in which case @info->set_default_value must not be NULL
- *    (if false then no default value is set by the property system
- *     and the field retains whatever value it was given by instance_init).
- * @defval: default value for the property. This is used only if @set_default
- *     is true.
- */
-struct Property {
-    const char   *name;
-    const PropertyInfo *info;
-    ptrdiff_t    offset;
-    uint8_t      bitnr;
-    bool         set_default;
-    union {
-        int64_t i;
-        uint64_t u;
-    } defval;
-    int          arrayoffset;
-    const PropertyInfo *arrayinfo;
-    int          arrayfieldsize;
-    const char   *link_type;
-};
-
-struct PropertyInfo {
-    const char *name;
-    const char *description;
-    const QEnumLookup *enum_table;
-    int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len);
-    void (*set_default_value)(ObjectProperty *op, const Property *prop);
-    void (*create)(ObjectClass *oc, Property *prop);
-    ObjectPropertyAccessor *get;
-    ObjectPropertyAccessor *set;
-    ObjectPropertyRelease *release;
-};
-
 /**
  * GlobalProperty:
  * @used: Set to true if property was used when initializing a device.
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 4437450065..db7ce51dd5 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -3,6 +3,44 @@
 
 #include "hw/qdev-core.h"
 
+/**
+ * Property:
+ * @set_default: true if the default value should be set from @defval,
+ *    in which case @info->set_default_value must not be NULL
+ *    (if false then no default value is set by the property system
+ *     and the field retains whatever value it was given by instance_init).
+ * @defval: default value for the property. This is used only if @set_default
+ *     is true.
+ */
+struct Property {
+    const char   *name;
+    const PropertyInfo *info;
+    ptrdiff_t    offset;
+    uint8_t      bitnr;
+    bool         set_default;
+    union {
+        int64_t i;
+        uint64_t u;
+    } defval;
+    int          arrayoffset;
+    const PropertyInfo *arrayinfo;
+    int          arrayfieldsize;
+    const char   *link_type;
+};
+
+struct PropertyInfo {
+    const char *name;
+    const char *description;
+    const QEnumLookup *enum_table;
+    int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len);
+    void (*set_default_value)(ObjectProperty *op, const Property *prop);
+    void (*create)(ObjectClass *oc, Property *prop);
+    ObjectPropertyAccessor *get;
+    ObjectPropertyAccessor *set;
+    ObjectPropertyRelease *release;
+};
+
+
 /*** qdev-properties.c ***/
 
 extern const PropertyInfo qdev_prop_bit;
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 509cbf155d..12a053e732 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -929,3 +929,123 @@ const PropertyInfo qdev_prop_link = {
     .name = "link",
     .create = create_link_property,
 };
+
+void qdev_property_add_static(DeviceState *dev, Property *prop)
+{
+    Object *obj = OBJECT(dev);
+    ObjectProperty *op;
+
+    assert(!prop->info->create);
+
+    op = object_property_add(obj, prop->name, prop->info->name,
+                             prop->info->get, prop->info->set,
+                             prop->info->release,
+                             prop);
+
+    object_property_set_description(obj, prop->name,
+                                    prop->info->description);
+
+    if (prop->set_default) {
+        prop->info->set_default_value(op, prop);
+        if (op->init) {
+            op->init(obj, op);
+        }
+    }
+}
+
+static void qdev_class_add_property(DeviceClass *klass, Property *prop)
+{
+    ObjectClass *oc = OBJECT_CLASS(klass);
+
+    if (prop->info->create) {
+        prop->info->create(oc, prop);
+    } else {
+        ObjectProperty *op;
+
+        op = object_class_property_add(oc,
+                                       prop->name, prop->info->name,
+                                       prop->info->get, prop->info->set,
+                                       prop->info->release,
+                                       prop);
+        if (prop->set_default) {
+            prop->info->set_default_value(op, prop);
+        }
+    }
+    object_class_property_set_description(oc, prop->name,
+                                          prop->info->description);
+}
+
+/**
+ * Legacy property handling
+ */
+
+static void qdev_get_legacy_property(Object *obj, Visitor *v,
+                                     const char *name, void *opaque,
+                                     Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+
+    char buffer[1024];
+    char *ptr = buffer;
+
+    prop->info->print(dev, prop, buffer, sizeof(buffer));
+    visit_type_str(v, name, &ptr, errp);
+}
+
+/**
+ * qdev_class_add_legacy_property:
+ * @dev: Device to add the property to.
+ * @prop: The qdev property definition.
+ *
+ * Add a legacy QOM property to @dev for qdev property @prop.
+ *
+ * Legacy properties are string versions of QOM properties.  The format of
+ * the string depends on the property type.  Legacy properties are only
+ * needed for "info qtree".
+ *
+ * Do not use this in new code!  QOM Properties added through this interface
+ * will be given names in the "legacy" namespace.
+ */
+static void qdev_class_add_legacy_property(DeviceClass *dc, Property *prop)
+{
+    g_autofree char *name = NULL;
+
+    /* Register pointer properties as legacy properties */
+    if (!prop->info->print && prop->info->get) {
+        return;
+    }
+
+    name = g_strdup_printf("legacy-%s", prop->name);
+    object_class_property_add(OBJECT_CLASS(dc), name, "str",
+        prop->info->print ? qdev_get_legacy_property : prop->info->get,
+        NULL, NULL, prop);
+}
+
+void device_class_set_props(DeviceClass *dc, Property *props)
+{
+    Property *prop;
+
+    dc->props_ = props;
+    for (prop = props; prop && prop->name; prop++) {
+        qdev_class_add_legacy_property(dc, prop);
+        qdev_class_add_property(dc, prop);
+    }
+}
+
+void qdev_alias_all_properties(DeviceState *target, Object *source)
+{
+    ObjectClass *class;
+    Property *prop;
+
+    class = object_get_class(OBJECT(target));
+    do {
+        DeviceClass *dc = DEVICE_CLASS(class);
+
+        for (prop = dc->props_; prop && prop->name; prop++) {
+            object_property_add_alias(source, prop->name,
+                                      OBJECT(target), prop->name);
+        }
+        class = object_class_get_parent(class);
+    } while (class != object_class_by_name(TYPE_DEVICE));
+}
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index fc4daa36fa..3c43107f71 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -714,115 +714,6 @@ char *qdev_get_dev_path(DeviceState *dev)
     return NULL;
 }
 
-/**
- * Legacy property handling
- */
-
-static void qdev_get_legacy_property(Object *obj, Visitor *v,
-                                     const char *name, void *opaque,
-                                     Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-
-    char buffer[1024];
-    char *ptr = buffer;
-
-    prop->info->print(dev, prop, buffer, sizeof(buffer));
-    visit_type_str(v, name, &ptr, errp);
-}
-
-/**
- * qdev_class_add_legacy_property:
- * @dev: Device to add the property to.
- * @prop: The qdev property definition.
- *
- * Add a legacy QOM property to @dev for qdev property @prop.
- *
- * Legacy properties are string versions of QOM properties.  The format of
- * the string depends on the property type.  Legacy properties are only
- * needed for "info qtree".
- *
- * Do not use this in new code!  QOM Properties added through this interface
- * will be given names in the "legacy" namespace.
- */
-static void qdev_class_add_legacy_property(DeviceClass *dc, Property *prop)
-{
-    g_autofree char *name = NULL;
-
-    /* Register pointer properties as legacy properties */
-    if (!prop->info->print && prop->info->get) {
-        return;
-    }
-
-    name = g_strdup_printf("legacy-%s", prop->name);
-    object_class_property_add(OBJECT_CLASS(dc), name, "str",
-        prop->info->print ? qdev_get_legacy_property : prop->info->get,
-        NULL, NULL, prop);
-}
-
-void qdev_property_add_static(DeviceState *dev, Property *prop)
-{
-    Object *obj = OBJECT(dev);
-    ObjectProperty *op;
-
-    assert(!prop->info->create);
-
-    op = object_property_add(obj, prop->name, prop->info->name,
-                             prop->info->get, prop->info->set,
-                             prop->info->release,
-                             prop);
-
-    object_property_set_description(obj, prop->name,
-                                    prop->info->description);
-
-    if (prop->set_default) {
-        prop->info->set_default_value(op, prop);
-        if (op->init) {
-            op->init(obj, op);
-        }
-    }
-}
-
-static void qdev_class_add_property(DeviceClass *klass, Property *prop)
-{
-    ObjectClass *oc = OBJECT_CLASS(klass);
-
-    if (prop->info->create) {
-        prop->info->create(oc, prop);
-    } else {
-        ObjectProperty *op;
-
-        op = object_class_property_add(oc,
-                                       prop->name, prop->info->name,
-                                       prop->info->get, prop->info->set,
-                                       prop->info->release,
-                                       prop);
-        if (prop->set_default) {
-            prop->info->set_default_value(op, prop);
-        }
-    }
-    object_class_property_set_description(oc, prop->name,
-                                          prop->info->description);
-}
-
-void qdev_alias_all_properties(DeviceState *target, Object *source)
-{
-    ObjectClass *class;
-    Property *prop;
-
-    class = object_get_class(OBJECT(target));
-    do {
-        DeviceClass *dc = DEVICE_CLASS(class);
-
-        for (prop = dc->props_; prop && prop->name; prop++) {
-            object_property_add_alias(source, prop->name,
-                                      OBJECT(target), prop->name);
-        }
-        class = object_class_get_parent(class);
-    } while (class != object_class_by_name(TYPE_DEVICE));
-}
-
 static bool device_get_realized(Object *obj, Error **errp)
 {
     DeviceState *dev = DEVICE(obj);
@@ -1217,17 +1108,6 @@ static void device_class_init(ObjectClass *class, void *data)
                                    offsetof(DeviceState, parent_bus), NULL, 0);
 }
 
-void device_class_set_props(DeviceClass *dc, Property *props)
-{
-    Property *prop;
-
-    dc->props_ = props;
-    for (prop = props; prop && prop->name; prop++) {
-        qdev_class_add_legacy_property(dc, prop);
-        qdev_class_add_property(dc, prop);
-    }
-}
-
 void device_class_set_parent_reset(DeviceClass *dc,
                                    DeviceReset dev_reset,
                                    DeviceReset *parent_reset)
diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
index bcfb90a08f..79164e4a3f 100644
--- a/softmmu/qdev-monitor.c
+++ b/softmmu/qdev-monitor.c
@@ -38,6 +38,7 @@
 #include "migration/misc.h"
 #include "migration/migration.h"
 #include "qemu/cutils.h"
+#include "hw/qdev-properties.h"
 #include "hw/clock.h"
 
 /*
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 04/44] qdev: Check dev->realized at set_size()
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (2 preceding siblings ...)
  2020-11-04 15:59 ` [PATCH v2 03/44] qdev: Move property code to qdev-properties.[ch] Eduardo Habkost
@ 2020-11-04 15:59 ` Eduardo Habkost
  2020-11-04 15:59 ` [PATCH v2 05/44] sparc: Check dev->realized at sparc_set_nwindows() Eduardo Habkost
                   ` (41 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 15:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

This setter is one of the very few property setters that don't
check dev->realized, and there's no reason to make size
properties different from the rest.  Add the missing check.

Fixes: e8cd45c78f53 ("qdev: Add SIZE type to qdev properties")
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 hw/core/qdev-properties.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 12a053e732..67ae19df05 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -905,6 +905,11 @@ static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
     Property *prop = opaque;
     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
 
+    if (dev->realized) {
+        qdev_prop_set_after_realize(dev, name, errp);
+        return;
+    }
+
     visit_type_size(v, name, ptr, errp);
 }
 
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 05/44] sparc: Check dev->realized at sparc_set_nwindows()
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (3 preceding siblings ...)
  2020-11-04 15:59 ` [PATCH v2 04/44] qdev: Check dev->realized at set_size() Eduardo Habkost
@ 2020-11-04 15:59 ` Eduardo Habkost
  2020-11-04 15:59 ` [PATCH v2 06/44] qdev: Don't use dev->id on set_size32() error message Eduardo Habkost
                   ` (40 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 15:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Mark Cave-Ayland,
	Markus Armbruster, Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Artyom Tarasenko, Stefan Berger

sparc_set_nwindows() is one of the very few property setters that
don't check dev->realized, and there's no reason for it to be
special.  Check dev->realized like the other setters.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Cc: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Cc: Artyom Tarasenko <atar4qemu@gmail.com>
Cc: qemu-devel@nongnu.org
---
 target/sparc/cpu.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index cf21efd85f..8ecb20e55f 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -798,11 +798,17 @@ static void sparc_get_nwindows(Object *obj, Visitor *v, const char *name,
 static void sparc_set_nwindows(Object *obj, Visitor *v, const char *name,
                                void *opaque, Error **errp)
 {
+    DeviceState *dev = DEVICE(obj);
     const int64_t min = MIN_NWINDOWS;
     const int64_t max = MAX_NWINDOWS;
     SPARCCPU *cpu = SPARC_CPU(obj);
     int64_t value;
 
+    if (dev->realized) {
+        qdev_prop_set_after_realize(dev, name, errp);
+        return;
+    }
+
     if (!visit_type_int(v, name, &value, errp)) {
         return;
     }
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 06/44] qdev: Don't use dev->id on set_size32() error message
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (4 preceding siblings ...)
  2020-11-04 15:59 ` [PATCH v2 05/44] sparc: Check dev->realized at sparc_set_nwindows() Eduardo Habkost
@ 2020-11-04 15:59 ` Eduardo Habkost
  2020-11-04 15:59 ` [PATCH v2 07/44] qdev: Make PropertyInfo.print method get Object* argument Eduardo Habkost
                   ` (39 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 15:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

All other qdev property error messages use "<type>.<property>"
instead of "<id>.<property>".  Change set_size32() for consistency,
and to make the code not specific to TYPE_DEVICE.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 hw/core/qdev-properties.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 67ae19df05..daf844c2d3 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -542,7 +542,7 @@ static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
         error_setg(errp,
                    "Property %s.%s doesn't take value %" PRIu64
                    " (maximum: %u)",
-                   dev->id ? : "", name, value, UINT32_MAX);
+                   object_get_typename(obj), name, value, UINT32_MAX);
         return;
     }
 
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 07/44] qdev: Make PropertyInfo.print method get Object* argument
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (5 preceding siblings ...)
  2020-11-04 15:59 ` [PATCH v2 06/44] qdev: Don't use dev->id on set_size32() error message Eduardo Habkost
@ 2020-11-04 15:59 ` Eduardo Habkost
  2020-11-04 15:59 ` [PATCH v2 08/44] qdev: Make bit_prop_set() " Eduardo Habkost
                   ` (38 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 15:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

Make the code more generic and not specific to TYPE_DEVICE.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 include/hw/qdev-properties.h     | 2 +-
 hw/core/qdev-properties-system.c | 3 ++-
 hw/core/qdev-properties.c        | 3 +--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index db7ce51dd5..0ea822e6a7 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -32,7 +32,7 @@ struct PropertyInfo {
     const char *name;
     const char *description;
     const QEnumLookup *enum_table;
-    int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len);
+    int (*print)(Object *obj, Property *prop, char *dest, size_t len);
     void (*set_default_value)(ObjectProperty *op, const Property *prop);
     void (*create)(ObjectClass *oc, Property *prop);
     ObjectPropertyAccessor *get;
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index b81a4e8d14..d0fb063a49 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -801,9 +801,10 @@ invalid:
     g_free(str);
 }
 
-static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest,
+static int print_pci_devfn(Object *obj, Property *prop, char *dest,
                            size_t len)
 {
+    DeviceState *dev = DEVICE(obj);
     int32_t *ptr = qdev_get_prop_ptr(dev, prop);
 
     if (*ptr == -1) {
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index daf844c2d3..b6cf53e929 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -988,13 +988,12 @@ static void qdev_get_legacy_property(Object *obj, Visitor *v,
                                      const char *name, void *opaque,
                                      Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
 
     char buffer[1024];
     char *ptr = buffer;
 
-    prop->info->print(dev, prop, buffer, sizeof(buffer));
+    prop->info->print(obj, prop, buffer, sizeof(buffer));
     visit_type_str(v, name, &ptr, errp);
 }
 
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 08/44] qdev: Make bit_prop_set() get Object* argument
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (6 preceding siblings ...)
  2020-11-04 15:59 ` [PATCH v2 07/44] qdev: Make PropertyInfo.print method get Object* argument Eduardo Habkost
@ 2020-11-04 15:59 ` Eduardo Habkost
  2020-11-04 15:59   ` Eduardo Habkost
                   ` (37 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 15:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

Make the code more generic and not specific to TYPE_DEVICE.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 hw/core/qdev-properties.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index b6cf53e929..3a4638f4de 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -92,8 +92,9 @@ static uint32_t qdev_get_prop_mask(Property *prop)
     return 0x1 << prop->bitnr;
 }
 
-static void bit_prop_set(DeviceState *dev, Property *props, bool val)
+static void bit_prop_set(Object *obj, Property *props, bool val)
 {
+    DeviceState *dev = DEVICE(obj);
     uint32_t *p = qdev_get_prop_ptr(dev, props);
     uint32_t mask = qdev_get_prop_mask(props);
     if (val) {
@@ -129,7 +130,7 @@ static void prop_set_bit(Object *obj, Visitor *v, const char *name,
     if (!visit_type_bool(v, name, &value, errp)) {
         return;
     }
-    bit_prop_set(dev, prop, value);
+    bit_prop_set(obj, prop, value);
 }
 
 static void set_default_value_bool(ObjectProperty *op, const Property *prop)
@@ -153,8 +154,9 @@ static uint64_t qdev_get_prop_mask64(Property *prop)
     return 0x1ull << prop->bitnr;
 }
 
-static void bit64_prop_set(DeviceState *dev, Property *props, bool val)
+static void bit64_prop_set(Object *obj, Property *props, bool val)
 {
+    DeviceState *dev = DEVICE(obj);
     uint64_t *p = qdev_get_prop_ptr(dev, props);
     uint64_t mask = qdev_get_prop_mask64(props);
     if (val) {
@@ -190,7 +192,7 @@ static void prop_set_bit64(Object *obj, Visitor *v, const char *name,
     if (!visit_type_bool(v, name, &value, errp)) {
         return;
     }
-    bit64_prop_set(dev, prop, value);
+    bit64_prop_set(obj, prop, value);
 }
 
 const PropertyInfo qdev_prop_bit64 = {
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 09/44] qdev: Make qdev_get_prop_ptr() get Object* arg
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
@ 2020-11-04 15:59   ` Eduardo Habkost
  2020-11-04 15:59 ` [PATCH v2 02/44] cpu: Move cpu_common_props to hw/core/cpu.c Eduardo Habkost
                     ` (44 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 15:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Matthew Rosato, Paul Durrant, Stefano Stabellini, xen-devel,
	qemu-block, Stefan Berger, David Hildenbrand, Markus Armbruster,
	Halil Pasic, Christian Borntraeger, Anthony Perard,
	Marc-André Lureau, Philippe Mathieu-Daudé,
	Thomas Huth, Alex Williamson, Paolo Bonzini, John Snow,
	Richard Henderson, Kevin Wolf, Daniel P. Berrange, Cornelia Huck,
	qemu-s390x, Max Reitz, Igor Mammedov, Stefan Berger

Make the code more generic and not specific to TYPE_DEVICE.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Changes v1 -> v2:
- Fix build error with CONFIG_XEN
  I took the liberty of keeping the Reviewed-by line from
  Marc-André as the build fix is a trivial one line change
---
Cc: Stefan Berger <stefanb@linux.vnet.ibm.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Paul Durrant <paul@xen.org>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: Cornelia Huck <cohuck@redhat.com>
Cc: Thomas Huth <thuth@redhat.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: David Hildenbrand <david@redhat.com>
Cc: Halil Pasic <pasic@linux.ibm.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Matthew Rosato <mjrosato@linux.ibm.com>
Cc: Alex Williamson <alex.williamson@redhat.com>
Cc: qemu-devel@nongnu.org
Cc: xen-devel@lists.xenproject.org
Cc: qemu-block@nongnu.org
Cc: qemu-s390x@nongnu.org
---
 include/hw/qdev-properties.h     |  2 +-
 backends/tpm/tpm_util.c          |  8 ++--
 hw/block/xen-block.c             |  5 +-
 hw/core/qdev-properties-system.c | 57 +++++++++-------------
 hw/core/qdev-properties.c        | 82 +++++++++++++-------------------
 hw/s390x/css.c                   |  5 +-
 hw/s390x/s390-pci-bus.c          |  4 +-
 hw/vfio/pci-quirks.c             |  5 +-
 8 files changed, 68 insertions(+), 100 deletions(-)

diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 0ea822e6a7..0b92cfc761 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -302,7 +302,7 @@ void qdev_prop_set_macaddr(DeviceState *dev, const char *name,
                            const uint8_t *value);
 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value);
 
-void *qdev_get_prop_ptr(DeviceState *dev, Property *prop);
+void *qdev_get_prop_ptr(Object *obj, Property *prop);
 
 void qdev_prop_register_global(GlobalProperty *prop);
 const GlobalProperty *qdev_find_global_prop(DeviceState *dev,
diff --git a/backends/tpm/tpm_util.c b/backends/tpm/tpm_util.c
index b58d298c1a..e91c21dd4a 100644
--- a/backends/tpm/tpm_util.c
+++ b/backends/tpm/tpm_util.c
@@ -35,8 +35,7 @@
 static void get_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
-    TPMBackend **be = qdev_get_prop_ptr(dev, opaque);
+    TPMBackend **be = qdev_get_prop_ptr(obj, opaque);
     char *p;
 
     p = g_strdup(*be ? (*be)->id : "");
@@ -49,7 +48,7 @@ static void set_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    TPMBackend *s, **be = qdev_get_prop_ptr(dev, prop);
+    TPMBackend *s, **be = qdev_get_prop_ptr(obj, prop);
     char *str;
 
     if (dev->realized) {
@@ -73,9 +72,8 @@ static void set_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
 
 static void release_tpm(Object *obj, const char *name, void *opaque)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    TPMBackend **be = qdev_get_prop_ptr(dev, prop);
+    TPMBackend **be = qdev_get_prop_ptr(obj, prop);
 
     if (*be) {
         tpm_backend_reset(*be);
diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
index 8a7a3f5452..905e4acd97 100644
--- a/hw/block/xen-block.c
+++ b/hw/block/xen-block.c
@@ -335,9 +335,8 @@ static char *disk_to_vbd_name(unsigned int disk)
 static void xen_block_get_vdev(Object *obj, Visitor *v, const char *name,
                                void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    XenBlockVdev *vdev = qdev_get_prop_ptr(dev, prop);
+    XenBlockVdev *vdev = qdev_get_prop_ptr(obj, prop);
     char *str;
 
     switch (vdev->type) {
@@ -398,7 +397,7 @@ static void xen_block_set_vdev(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    XenBlockVdev *vdev = qdev_get_prop_ptr(dev, prop);
+    XenBlockVdev *vdev = qdev_get_prop_ptr(obj, prop);
     char *str, *p;
     const char *end;
 
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index d0fb063a49..c8c73c371b 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -59,9 +59,8 @@ static bool check_prop_still_unset(DeviceState *dev, const char *name,
 static void get_drive(Object *obj, Visitor *v, const char *name, void *opaque,
                       Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    void **ptr = qdev_get_prop_ptr(dev, prop);
+    void **ptr = qdev_get_prop_ptr(obj, prop);
     const char *value;
     char *p;
 
@@ -87,7 +86,7 @@ static void set_drive_helper(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    void **ptr = qdev_get_prop_ptr(dev, prop);
+    void **ptr = qdev_get_prop_ptr(obj, prop);
     char *str;
     BlockBackend *blk;
     bool blk_created = false;
@@ -185,7 +184,7 @@ static void release_drive(Object *obj, const char *name, void *opaque)
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    BlockBackend **ptr = qdev_get_prop_ptr(dev, prop);
+    BlockBackend **ptr = qdev_get_prop_ptr(obj, prop);
 
     if (*ptr) {
         AioContext *ctx = blk_get_aio_context(*ptr);
@@ -218,8 +217,7 @@ const PropertyInfo qdev_prop_drive_iothread = {
 static void get_chr(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
-    CharBackend *be = qdev_get_prop_ptr(dev, opaque);
+    CharBackend *be = qdev_get_prop_ptr(obj, opaque);
     char *p;
 
     p = g_strdup(be->chr && be->chr->label ? be->chr->label : "");
@@ -232,7 +230,7 @@ static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    CharBackend *be = qdev_get_prop_ptr(dev, prop);
+    CharBackend *be = qdev_get_prop_ptr(obj, prop);
     Chardev *s;
     char *str;
 
@@ -272,9 +270,8 @@ static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
 
 static void release_chr(Object *obj, const char *name, void *opaque)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    CharBackend *be = qdev_get_prop_ptr(dev, prop);
+    CharBackend *be = qdev_get_prop_ptr(obj, prop);
 
     qemu_chr_fe_deinit(be, false);
 }
@@ -297,9 +294,8 @@ const PropertyInfo qdev_prop_chr = {
 static void get_mac(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    MACAddr *mac = qdev_get_prop_ptr(dev, prop);
+    MACAddr *mac = qdev_get_prop_ptr(obj, prop);
     char buffer[2 * 6 + 5 + 1];
     char *p = buffer;
 
@@ -315,7 +311,7 @@ static void set_mac(Object *obj, Visitor *v, const char *name, void *opaque,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    MACAddr *mac = qdev_get_prop_ptr(dev, prop);
+    MACAddr *mac = qdev_get_prop_ptr(obj, prop);
     int i, pos;
     char *str;
     const char *p;
@@ -381,9 +377,8 @@ void qdev_prop_set_macaddr(DeviceState *dev, const char *name,
 static void get_netdev(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    NICPeers *peers_ptr = qdev_get_prop_ptr(dev, prop);
+    NICPeers *peers_ptr = qdev_get_prop_ptr(obj, prop);
     char *p = g_strdup(peers_ptr->ncs[0] ? peers_ptr->ncs[0]->name : "");
 
     visit_type_str(v, name, &p, errp);
@@ -395,7 +390,7 @@ static void set_netdev(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    NICPeers *peers_ptr = qdev_get_prop_ptr(dev, prop);
+    NICPeers *peers_ptr = qdev_get_prop_ptr(obj, prop);
     NetClientState **ncs = peers_ptr->ncs;
     NetClientState *peers[MAX_QUEUE_NUM];
     int queues, err = 0, i = 0;
@@ -461,9 +456,8 @@ const PropertyInfo qdev_prop_netdev = {
 static void get_audiodev(Object *obj, Visitor *v, const char* name,
                          void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    QEMUSoundCard *card = qdev_get_prop_ptr(dev, prop);
+    QEMUSoundCard *card = qdev_get_prop_ptr(obj, prop);
     char *p = g_strdup(audio_get_id(card));
 
     visit_type_str(v, name, &p, errp);
@@ -475,7 +469,7 @@ static void set_audiodev(Object *obj, Visitor *v, const char* name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    QEMUSoundCard *card = qdev_get_prop_ptr(dev, prop);
+    QEMUSoundCard *card = qdev_get_prop_ptr(obj, prop);
     AudioState *state;
     int err = 0;
     char *str;
@@ -582,7 +576,7 @@ static void set_blocksize(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
     uint64_t value;
     Error *local_err = NULL;
 
@@ -674,9 +668,8 @@ const PropertyInfo qdev_prop_multifd_compression = {
 static void get_reserved_region(Object *obj, Visitor *v, const char *name,
                                 void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    ReservedRegion *rr = qdev_get_prop_ptr(dev, prop);
+    ReservedRegion *rr = qdev_get_prop_ptr(obj, prop);
     char buffer[64];
     char *p = buffer;
     int rc;
@@ -693,7 +686,7 @@ static void set_reserved_region(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    ReservedRegion *rr = qdev_get_prop_ptr(dev, prop);
+    ReservedRegion *rr = qdev_get_prop_ptr(obj, prop);
     Error *local_err = NULL;
     const char *endptr;
     char *str;
@@ -761,7 +754,7 @@ static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    int32_t value, *ptr = qdev_get_prop_ptr(dev, prop);
+    int32_t value, *ptr = qdev_get_prop_ptr(obj, prop);
     unsigned int slot, fn, n;
     char *str;
 
@@ -804,8 +797,7 @@ invalid:
 static int print_pci_devfn(Object *obj, Property *prop, char *dest,
                            size_t len)
 {
-    DeviceState *dev = DEVICE(obj);
-    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    int32_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     if (*ptr == -1) {
         return snprintf(dest, len, "<unset>");
@@ -828,9 +820,8 @@ const PropertyInfo qdev_prop_pci_devfn = {
 static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
                                  void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
+    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(obj, prop);
     char buffer[] = "ffff:ff:ff.f";
     char *p = buffer;
     int rc = 0;
@@ -857,7 +848,7 @@ static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
+    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(obj, prop);
     char *str, *p;
     const char *e;
     unsigned long val;
@@ -950,9 +941,8 @@ const PropertyInfo qdev_prop_off_auto_pcibar = {
 static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
                                    void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    PCIExpLinkSpeed *p = qdev_get_prop_ptr(dev, prop);
+    PCIExpLinkSpeed *p = qdev_get_prop_ptr(obj, prop);
     int speed;
 
     switch (*p) {
@@ -981,7 +971,7 @@ static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    PCIExpLinkSpeed *p = qdev_get_prop_ptr(dev, prop);
+    PCIExpLinkSpeed *p = qdev_get_prop_ptr(obj, prop);
     int speed;
 
     if (dev->realized) {
@@ -1027,9 +1017,8 @@ const PropertyInfo qdev_prop_pcie_link_speed = {
 static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
                                    void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    PCIExpLinkWidth *p = qdev_get_prop_ptr(dev, prop);
+    PCIExpLinkWidth *p = qdev_get_prop_ptr(obj, prop);
     int width;
 
     switch (*p) {
@@ -1067,7 +1056,7 @@ static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    PCIExpLinkWidth *p = qdev_get_prop_ptr(dev, prop);
+    PCIExpLinkWidth *p = qdev_get_prop_ptr(obj, prop);
     int width;
 
     if (dev->realized) {
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 3a4638f4de..0a54a922c8 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -38,9 +38,9 @@ void qdev_prop_allow_set_link_before_realize(const Object *obj,
     }
 }
 
-void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
+void *qdev_get_prop_ptr(Object *obj, Property *prop)
 {
-    void *ptr = dev;
+    void *ptr = obj;
     ptr += prop->offset;
     return ptr;
 }
@@ -48,9 +48,8 @@ void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
 void qdev_propinfo_get_enum(Object *obj, Visitor *v, const char *name,
                             void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    int *ptr = qdev_get_prop_ptr(dev, prop);
+    int *ptr = qdev_get_prop_ptr(obj, prop);
 
     visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp);
 }
@@ -60,7 +59,7 @@ void qdev_propinfo_set_enum(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    int *ptr = qdev_get_prop_ptr(dev, prop);
+    int *ptr = qdev_get_prop_ptr(obj, prop);
 
     if (dev->realized) {
         qdev_prop_set_after_realize(dev, name, errp);
@@ -94,8 +93,7 @@ static uint32_t qdev_get_prop_mask(Property *prop)
 
 static void bit_prop_set(Object *obj, Property *props, bool val)
 {
-    DeviceState *dev = DEVICE(obj);
-    uint32_t *p = qdev_get_prop_ptr(dev, props);
+    uint32_t *p = qdev_get_prop_ptr(obj, props);
     uint32_t mask = qdev_get_prop_mask(props);
     if (val) {
         *p |= mask;
@@ -107,9 +105,8 @@ static void bit_prop_set(Object *obj, Property *props, bool val)
 static void prop_get_bit(Object *obj, Visitor *v, const char *name,
                          void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint32_t *p = qdev_get_prop_ptr(dev, prop);
+    uint32_t *p = qdev_get_prop_ptr(obj, prop);
     bool value = (*p & qdev_get_prop_mask(prop)) != 0;
 
     visit_type_bool(v, name, &value, errp);
@@ -156,8 +153,7 @@ static uint64_t qdev_get_prop_mask64(Property *prop)
 
 static void bit64_prop_set(Object *obj, Property *props, bool val)
 {
-    DeviceState *dev = DEVICE(obj);
-    uint64_t *p = qdev_get_prop_ptr(dev, props);
+    uint64_t *p = qdev_get_prop_ptr(obj, props);
     uint64_t mask = qdev_get_prop_mask64(props);
     if (val) {
         *p |= mask;
@@ -169,9 +165,8 @@ static void bit64_prop_set(Object *obj, Property *props, bool val)
 static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
                            void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint64_t *p = qdev_get_prop_ptr(dev, prop);
+    uint64_t *p = qdev_get_prop_ptr(obj, prop);
     bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
 
     visit_type_bool(v, name, &value, errp);
@@ -208,9 +203,8 @@ const PropertyInfo qdev_prop_bit64 = {
 static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    bool *ptr = qdev_get_prop_ptr(dev, prop);
+    bool *ptr = qdev_get_prop_ptr(obj, prop);
 
     visit_type_bool(v, name, ptr, errp);
 }
@@ -220,7 +214,7 @@ static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    bool *ptr = qdev_get_prop_ptr(dev, prop);
+    bool *ptr = qdev_get_prop_ptr(obj, prop);
 
     if (dev->realized) {
         qdev_prop_set_after_realize(dev, name, errp);
@@ -242,9 +236,8 @@ const PropertyInfo qdev_prop_bool = {
 static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
                       Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint8_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     visit_type_uint8(v, name, ptr, errp);
 }
@@ -254,7 +247,7 @@ static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint8_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     if (dev->realized) {
         qdev_prop_set_after_realize(dev, name, errp);
@@ -288,9 +281,8 @@ const PropertyInfo qdev_prop_uint8 = {
 void qdev_propinfo_get_uint16(Object *obj, Visitor *v, const char *name,
                               void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint16_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     visit_type_uint16(v, name, ptr, errp);
 }
@@ -300,7 +292,7 @@ static void set_uint16(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint16_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     if (dev->realized) {
         qdev_prop_set_after_realize(dev, name, errp);
@@ -322,9 +314,8 @@ const PropertyInfo qdev_prop_uint16 = {
 static void get_uint32(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     visit_type_uint32(v, name, ptr, errp);
 }
@@ -334,7 +325,7 @@ static void set_uint32(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     if (dev->realized) {
         qdev_prop_set_after_realize(dev, name, errp);
@@ -347,9 +338,8 @@ static void set_uint32(Object *obj, Visitor *v, const char *name,
 void qdev_propinfo_get_int32(Object *obj, Visitor *v, const char *name,
                              void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    int32_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     visit_type_int32(v, name, ptr, errp);
 }
@@ -359,7 +349,7 @@ static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    int32_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     if (dev->realized) {
         qdev_prop_set_after_realize(dev, name, errp);
@@ -388,9 +378,8 @@ const PropertyInfo qdev_prop_int32 = {
 static void get_uint64(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     visit_type_uint64(v, name, ptr, errp);
 }
@@ -400,7 +389,7 @@ static void set_uint64(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     if (dev->realized) {
         qdev_prop_set_after_realize(dev, name, errp);
@@ -413,9 +402,8 @@ static void set_uint64(Object *obj, Visitor *v, const char *name,
 static void get_int64(Object *obj, Visitor *v, const char *name,
                       void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    int64_t *ptr = qdev_get_prop_ptr(dev, prop);
+    int64_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     visit_type_int64(v, name, ptr, errp);
 }
@@ -425,7 +413,7 @@ static void set_int64(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    int64_t *ptr = qdev_get_prop_ptr(dev, prop);
+    int64_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     if (dev->realized) {
         qdev_prop_set_after_realize(dev, name, errp);
@@ -454,15 +442,14 @@ const PropertyInfo qdev_prop_int64 = {
 static void release_string(Object *obj, const char *name, void *opaque)
 {
     Property *prop = opaque;
-    g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
+    g_free(*(char **)qdev_get_prop_ptr(obj, prop));
 }
 
 static void get_string(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    char **ptr = qdev_get_prop_ptr(dev, prop);
+    char **ptr = qdev_get_prop_ptr(obj, prop);
 
     if (!*ptr) {
         char *str = (char *)"";
@@ -477,7 +464,7 @@ static void set_string(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    char **ptr = qdev_get_prop_ptr(dev, prop);
+    char **ptr = qdev_get_prop_ptr(obj, prop);
     char *str;
 
     if (dev->realized) {
@@ -515,9 +502,8 @@ const PropertyInfo qdev_prop_on_off_auto = {
 void qdev_propinfo_get_size32(Object *obj, Visitor *v, const char *name,
                               void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
     uint64_t value = *ptr;
 
     visit_type_size(v, name, &value, errp);
@@ -528,7 +514,7 @@ static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
     uint64_t value;
 
     if (dev->realized) {
@@ -563,9 +549,8 @@ const PropertyInfo qdev_prop_size32 = {
 static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    QemuUUID *uuid = qdev_get_prop_ptr(dev, prop);
+    QemuUUID *uuid = qdev_get_prop_ptr(obj, prop);
     char buffer[UUID_FMT_LEN + 1];
     char *p = buffer;
 
@@ -581,7 +566,7 @@ static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    QemuUUID *uuid = qdev_get_prop_ptr(dev, prop);
+    QemuUUID *uuid = qdev_get_prop_ptr(obj, prop);
     char *str;
 
     if (dev->realized) {
@@ -653,7 +638,7 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
      */
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint32_t *alenptr = qdev_get_prop_ptr(dev, prop);
+    uint32_t *alenptr = qdev_get_prop_ptr(obj, prop);
     void **arrayptr = (void *)dev + prop->arrayoffset;
     void *eltptr;
     const char *arrayname;
@@ -699,7 +684,7 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
          * being inside the device struct.
          */
         arrayprop->prop.offset = eltptr - (void *)dev;
-        assert(qdev_get_prop_ptr(dev, &arrayprop->prop) == eltptr);
+        assert(qdev_get_prop_ptr(obj, &arrayprop->prop) == eltptr);
         object_property_add(obj, propname,
                             arrayprop->prop.info->name,
                             arrayprop->prop.info->get,
@@ -893,9 +878,8 @@ void qdev_prop_set_globals(DeviceState *dev)
 static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     visit_type_size(v, name, ptr, errp);
 }
@@ -905,7 +889,7 @@ static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     if (dev->realized) {
         qdev_prop_set_after_realize(dev, name, errp);
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 9961cfe7bf..2b8f33fec2 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -2343,9 +2343,8 @@ void css_reset(void)
 static void get_css_devid(Object *obj, Visitor *v, const char *name,
                           void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    CssDevId *dev_id = qdev_get_prop_ptr(dev, prop);
+    CssDevId *dev_id = qdev_get_prop_ptr(obj, prop);
     char buffer[] = "xx.x.xxxx";
     char *p = buffer;
     int r;
@@ -2375,7 +2374,7 @@ static void set_css_devid(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    CssDevId *dev_id = qdev_get_prop_ptr(dev, prop);
+    CssDevId *dev_id = qdev_get_prop_ptr(obj, prop);
     char *str;
     int num, n1, n2;
     unsigned int cssid, ssid, devid;
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 48a3be802f..ab27b6e848 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -1323,7 +1323,7 @@ static void s390_pci_get_fid(Object *obj, Visitor *v, const char *name,
                          void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(DEVICE(obj), prop);
+    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     visit_type_uint32(v, name, ptr, errp);
 }
@@ -1334,7 +1334,7 @@ static void s390_pci_set_fid(Object *obj, Visitor *v, const char *name,
     DeviceState *dev = DEVICE(obj);
     S390PCIBusDevice *zpci = S390_PCI_DEVICE(obj);
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     if (dev->realized) {
         qdev_prop_set_after_realize(dev, name, errp);
diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
index 57150913b7..53569925a2 100644
--- a/hw/vfio/pci-quirks.c
+++ b/hw/vfio/pci-quirks.c
@@ -1488,9 +1488,8 @@ static void get_nv_gpudirect_clique_id(Object *obj, Visitor *v,
                                        const char *name, void *opaque,
                                        Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint8_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     visit_type_uint8(v, name, ptr, errp);
 }
@@ -1501,7 +1500,7 @@ static void set_nv_gpudirect_clique_id(Object *obj, Visitor *v,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint8_t value, *ptr = qdev_get_prop_ptr(dev, prop);
+    uint8_t value, *ptr = qdev_get_prop_ptr(obj, prop);
 
     if (dev->realized) {
         qdev_prop_set_after_realize(dev, name, errp);
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 09/44] qdev: Make qdev_get_prop_ptr() get Object* arg
@ 2020-11-04 15:59   ` Eduardo Habkost
  0 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 15:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, Paolo Bonzini, Igor Mammedov, Eric Blake,
	Stefan Berger, Markus Armbruster, Marc-André Lureau,
	John Snow, Philippe Mathieu-Daudé,
	Stefan Berger, Stefano Stabellini, Anthony Perard, Paul Durrant,
	Kevin Wolf, Max Reitz, Cornelia Huck, Thomas Huth,
	Richard Henderson, David Hildenbrand, Halil Pasic,
	Christian Borntraeger, Matthew Rosato, Alex Williamson,
	xen-devel, qemu-block, qemu-s390x

Make the code more generic and not specific to TYPE_DEVICE.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Changes v1 -> v2:
- Fix build error with CONFIG_XEN
  I took the liberty of keeping the Reviewed-by line from
  Marc-André as the build fix is a trivial one line change
---
Cc: Stefan Berger <stefanb@linux.vnet.ibm.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Paul Durrant <paul@xen.org>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: Cornelia Huck <cohuck@redhat.com>
Cc: Thomas Huth <thuth@redhat.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: David Hildenbrand <david@redhat.com>
Cc: Halil Pasic <pasic@linux.ibm.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Matthew Rosato <mjrosato@linux.ibm.com>
Cc: Alex Williamson <alex.williamson@redhat.com>
Cc: qemu-devel@nongnu.org
Cc: xen-devel@lists.xenproject.org
Cc: qemu-block@nongnu.org
Cc: qemu-s390x@nongnu.org
---
 include/hw/qdev-properties.h     |  2 +-
 backends/tpm/tpm_util.c          |  8 ++--
 hw/block/xen-block.c             |  5 +-
 hw/core/qdev-properties-system.c | 57 +++++++++-------------
 hw/core/qdev-properties.c        | 82 +++++++++++++-------------------
 hw/s390x/css.c                   |  5 +-
 hw/s390x/s390-pci-bus.c          |  4 +-
 hw/vfio/pci-quirks.c             |  5 +-
 8 files changed, 68 insertions(+), 100 deletions(-)

diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 0ea822e6a7..0b92cfc761 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -302,7 +302,7 @@ void qdev_prop_set_macaddr(DeviceState *dev, const char *name,
                            const uint8_t *value);
 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value);
 
-void *qdev_get_prop_ptr(DeviceState *dev, Property *prop);
+void *qdev_get_prop_ptr(Object *obj, Property *prop);
 
 void qdev_prop_register_global(GlobalProperty *prop);
 const GlobalProperty *qdev_find_global_prop(DeviceState *dev,
diff --git a/backends/tpm/tpm_util.c b/backends/tpm/tpm_util.c
index b58d298c1a..e91c21dd4a 100644
--- a/backends/tpm/tpm_util.c
+++ b/backends/tpm/tpm_util.c
@@ -35,8 +35,7 @@
 static void get_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
-    TPMBackend **be = qdev_get_prop_ptr(dev, opaque);
+    TPMBackend **be = qdev_get_prop_ptr(obj, opaque);
     char *p;
 
     p = g_strdup(*be ? (*be)->id : "");
@@ -49,7 +48,7 @@ static void set_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    TPMBackend *s, **be = qdev_get_prop_ptr(dev, prop);
+    TPMBackend *s, **be = qdev_get_prop_ptr(obj, prop);
     char *str;
 
     if (dev->realized) {
@@ -73,9 +72,8 @@ static void set_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
 
 static void release_tpm(Object *obj, const char *name, void *opaque)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    TPMBackend **be = qdev_get_prop_ptr(dev, prop);
+    TPMBackend **be = qdev_get_prop_ptr(obj, prop);
 
     if (*be) {
         tpm_backend_reset(*be);
diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
index 8a7a3f5452..905e4acd97 100644
--- a/hw/block/xen-block.c
+++ b/hw/block/xen-block.c
@@ -335,9 +335,8 @@ static char *disk_to_vbd_name(unsigned int disk)
 static void xen_block_get_vdev(Object *obj, Visitor *v, const char *name,
                                void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    XenBlockVdev *vdev = qdev_get_prop_ptr(dev, prop);
+    XenBlockVdev *vdev = qdev_get_prop_ptr(obj, prop);
     char *str;
 
     switch (vdev->type) {
@@ -398,7 +397,7 @@ static void xen_block_set_vdev(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    XenBlockVdev *vdev = qdev_get_prop_ptr(dev, prop);
+    XenBlockVdev *vdev = qdev_get_prop_ptr(obj, prop);
     char *str, *p;
     const char *end;
 
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index d0fb063a49..c8c73c371b 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -59,9 +59,8 @@ static bool check_prop_still_unset(DeviceState *dev, const char *name,
 static void get_drive(Object *obj, Visitor *v, const char *name, void *opaque,
                       Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    void **ptr = qdev_get_prop_ptr(dev, prop);
+    void **ptr = qdev_get_prop_ptr(obj, prop);
     const char *value;
     char *p;
 
@@ -87,7 +86,7 @@ static void set_drive_helper(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    void **ptr = qdev_get_prop_ptr(dev, prop);
+    void **ptr = qdev_get_prop_ptr(obj, prop);
     char *str;
     BlockBackend *blk;
     bool blk_created = false;
@@ -185,7 +184,7 @@ static void release_drive(Object *obj, const char *name, void *opaque)
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    BlockBackend **ptr = qdev_get_prop_ptr(dev, prop);
+    BlockBackend **ptr = qdev_get_prop_ptr(obj, prop);
 
     if (*ptr) {
         AioContext *ctx = blk_get_aio_context(*ptr);
@@ -218,8 +217,7 @@ const PropertyInfo qdev_prop_drive_iothread = {
 static void get_chr(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
-    CharBackend *be = qdev_get_prop_ptr(dev, opaque);
+    CharBackend *be = qdev_get_prop_ptr(obj, opaque);
     char *p;
 
     p = g_strdup(be->chr && be->chr->label ? be->chr->label : "");
@@ -232,7 +230,7 @@ static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    CharBackend *be = qdev_get_prop_ptr(dev, prop);
+    CharBackend *be = qdev_get_prop_ptr(obj, prop);
     Chardev *s;
     char *str;
 
@@ -272,9 +270,8 @@ static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
 
 static void release_chr(Object *obj, const char *name, void *opaque)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    CharBackend *be = qdev_get_prop_ptr(dev, prop);
+    CharBackend *be = qdev_get_prop_ptr(obj, prop);
 
     qemu_chr_fe_deinit(be, false);
 }
@@ -297,9 +294,8 @@ const PropertyInfo qdev_prop_chr = {
 static void get_mac(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    MACAddr *mac = qdev_get_prop_ptr(dev, prop);
+    MACAddr *mac = qdev_get_prop_ptr(obj, prop);
     char buffer[2 * 6 + 5 + 1];
     char *p = buffer;
 
@@ -315,7 +311,7 @@ static void set_mac(Object *obj, Visitor *v, const char *name, void *opaque,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    MACAddr *mac = qdev_get_prop_ptr(dev, prop);
+    MACAddr *mac = qdev_get_prop_ptr(obj, prop);
     int i, pos;
     char *str;
     const char *p;
@@ -381,9 +377,8 @@ void qdev_prop_set_macaddr(DeviceState *dev, const char *name,
 static void get_netdev(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    NICPeers *peers_ptr = qdev_get_prop_ptr(dev, prop);
+    NICPeers *peers_ptr = qdev_get_prop_ptr(obj, prop);
     char *p = g_strdup(peers_ptr->ncs[0] ? peers_ptr->ncs[0]->name : "");
 
     visit_type_str(v, name, &p, errp);
@@ -395,7 +390,7 @@ static void set_netdev(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    NICPeers *peers_ptr = qdev_get_prop_ptr(dev, prop);
+    NICPeers *peers_ptr = qdev_get_prop_ptr(obj, prop);
     NetClientState **ncs = peers_ptr->ncs;
     NetClientState *peers[MAX_QUEUE_NUM];
     int queues, err = 0, i = 0;
@@ -461,9 +456,8 @@ const PropertyInfo qdev_prop_netdev = {
 static void get_audiodev(Object *obj, Visitor *v, const char* name,
                          void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    QEMUSoundCard *card = qdev_get_prop_ptr(dev, prop);
+    QEMUSoundCard *card = qdev_get_prop_ptr(obj, prop);
     char *p = g_strdup(audio_get_id(card));
 
     visit_type_str(v, name, &p, errp);
@@ -475,7 +469,7 @@ static void set_audiodev(Object *obj, Visitor *v, const char* name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    QEMUSoundCard *card = qdev_get_prop_ptr(dev, prop);
+    QEMUSoundCard *card = qdev_get_prop_ptr(obj, prop);
     AudioState *state;
     int err = 0;
     char *str;
@@ -582,7 +576,7 @@ static void set_blocksize(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
     uint64_t value;
     Error *local_err = NULL;
 
@@ -674,9 +668,8 @@ const PropertyInfo qdev_prop_multifd_compression = {
 static void get_reserved_region(Object *obj, Visitor *v, const char *name,
                                 void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    ReservedRegion *rr = qdev_get_prop_ptr(dev, prop);
+    ReservedRegion *rr = qdev_get_prop_ptr(obj, prop);
     char buffer[64];
     char *p = buffer;
     int rc;
@@ -693,7 +686,7 @@ static void set_reserved_region(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    ReservedRegion *rr = qdev_get_prop_ptr(dev, prop);
+    ReservedRegion *rr = qdev_get_prop_ptr(obj, prop);
     Error *local_err = NULL;
     const char *endptr;
     char *str;
@@ -761,7 +754,7 @@ static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    int32_t value, *ptr = qdev_get_prop_ptr(dev, prop);
+    int32_t value, *ptr = qdev_get_prop_ptr(obj, prop);
     unsigned int slot, fn, n;
     char *str;
 
@@ -804,8 +797,7 @@ invalid:
 static int print_pci_devfn(Object *obj, Property *prop, char *dest,
                            size_t len)
 {
-    DeviceState *dev = DEVICE(obj);
-    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    int32_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     if (*ptr == -1) {
         return snprintf(dest, len, "<unset>");
@@ -828,9 +820,8 @@ const PropertyInfo qdev_prop_pci_devfn = {
 static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
                                  void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
+    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(obj, prop);
     char buffer[] = "ffff:ff:ff.f";
     char *p = buffer;
     int rc = 0;
@@ -857,7 +848,7 @@ static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
+    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(obj, prop);
     char *str, *p;
     const char *e;
     unsigned long val;
@@ -950,9 +941,8 @@ const PropertyInfo qdev_prop_off_auto_pcibar = {
 static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
                                    void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    PCIExpLinkSpeed *p = qdev_get_prop_ptr(dev, prop);
+    PCIExpLinkSpeed *p = qdev_get_prop_ptr(obj, prop);
     int speed;
 
     switch (*p) {
@@ -981,7 +971,7 @@ static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    PCIExpLinkSpeed *p = qdev_get_prop_ptr(dev, prop);
+    PCIExpLinkSpeed *p = qdev_get_prop_ptr(obj, prop);
     int speed;
 
     if (dev->realized) {
@@ -1027,9 +1017,8 @@ const PropertyInfo qdev_prop_pcie_link_speed = {
 static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
                                    void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    PCIExpLinkWidth *p = qdev_get_prop_ptr(dev, prop);
+    PCIExpLinkWidth *p = qdev_get_prop_ptr(obj, prop);
     int width;
 
     switch (*p) {
@@ -1067,7 +1056,7 @@ static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    PCIExpLinkWidth *p = qdev_get_prop_ptr(dev, prop);
+    PCIExpLinkWidth *p = qdev_get_prop_ptr(obj, prop);
     int width;
 
     if (dev->realized) {
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 3a4638f4de..0a54a922c8 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -38,9 +38,9 @@ void qdev_prop_allow_set_link_before_realize(const Object *obj,
     }
 }
 
-void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
+void *qdev_get_prop_ptr(Object *obj, Property *prop)
 {
-    void *ptr = dev;
+    void *ptr = obj;
     ptr += prop->offset;
     return ptr;
 }
@@ -48,9 +48,8 @@ void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
 void qdev_propinfo_get_enum(Object *obj, Visitor *v, const char *name,
                             void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    int *ptr = qdev_get_prop_ptr(dev, prop);
+    int *ptr = qdev_get_prop_ptr(obj, prop);
 
     visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp);
 }
@@ -60,7 +59,7 @@ void qdev_propinfo_set_enum(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    int *ptr = qdev_get_prop_ptr(dev, prop);
+    int *ptr = qdev_get_prop_ptr(obj, prop);
 
     if (dev->realized) {
         qdev_prop_set_after_realize(dev, name, errp);
@@ -94,8 +93,7 @@ static uint32_t qdev_get_prop_mask(Property *prop)
 
 static void bit_prop_set(Object *obj, Property *props, bool val)
 {
-    DeviceState *dev = DEVICE(obj);
-    uint32_t *p = qdev_get_prop_ptr(dev, props);
+    uint32_t *p = qdev_get_prop_ptr(obj, props);
     uint32_t mask = qdev_get_prop_mask(props);
     if (val) {
         *p |= mask;
@@ -107,9 +105,8 @@ static void bit_prop_set(Object *obj, Property *props, bool val)
 static void prop_get_bit(Object *obj, Visitor *v, const char *name,
                          void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint32_t *p = qdev_get_prop_ptr(dev, prop);
+    uint32_t *p = qdev_get_prop_ptr(obj, prop);
     bool value = (*p & qdev_get_prop_mask(prop)) != 0;
 
     visit_type_bool(v, name, &value, errp);
@@ -156,8 +153,7 @@ static uint64_t qdev_get_prop_mask64(Property *prop)
 
 static void bit64_prop_set(Object *obj, Property *props, bool val)
 {
-    DeviceState *dev = DEVICE(obj);
-    uint64_t *p = qdev_get_prop_ptr(dev, props);
+    uint64_t *p = qdev_get_prop_ptr(obj, props);
     uint64_t mask = qdev_get_prop_mask64(props);
     if (val) {
         *p |= mask;
@@ -169,9 +165,8 @@ static void bit64_prop_set(Object *obj, Property *props, bool val)
 static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
                            void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint64_t *p = qdev_get_prop_ptr(dev, prop);
+    uint64_t *p = qdev_get_prop_ptr(obj, prop);
     bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
 
     visit_type_bool(v, name, &value, errp);
@@ -208,9 +203,8 @@ const PropertyInfo qdev_prop_bit64 = {
 static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    bool *ptr = qdev_get_prop_ptr(dev, prop);
+    bool *ptr = qdev_get_prop_ptr(obj, prop);
 
     visit_type_bool(v, name, ptr, errp);
 }
@@ -220,7 +214,7 @@ static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    bool *ptr = qdev_get_prop_ptr(dev, prop);
+    bool *ptr = qdev_get_prop_ptr(obj, prop);
 
     if (dev->realized) {
         qdev_prop_set_after_realize(dev, name, errp);
@@ -242,9 +236,8 @@ const PropertyInfo qdev_prop_bool = {
 static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
                       Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint8_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     visit_type_uint8(v, name, ptr, errp);
 }
@@ -254,7 +247,7 @@ static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint8_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     if (dev->realized) {
         qdev_prop_set_after_realize(dev, name, errp);
@@ -288,9 +281,8 @@ const PropertyInfo qdev_prop_uint8 = {
 void qdev_propinfo_get_uint16(Object *obj, Visitor *v, const char *name,
                               void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint16_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     visit_type_uint16(v, name, ptr, errp);
 }
@@ -300,7 +292,7 @@ static void set_uint16(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint16_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     if (dev->realized) {
         qdev_prop_set_after_realize(dev, name, errp);
@@ -322,9 +314,8 @@ const PropertyInfo qdev_prop_uint16 = {
 static void get_uint32(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     visit_type_uint32(v, name, ptr, errp);
 }
@@ -334,7 +325,7 @@ static void set_uint32(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     if (dev->realized) {
         qdev_prop_set_after_realize(dev, name, errp);
@@ -347,9 +338,8 @@ static void set_uint32(Object *obj, Visitor *v, const char *name,
 void qdev_propinfo_get_int32(Object *obj, Visitor *v, const char *name,
                              void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    int32_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     visit_type_int32(v, name, ptr, errp);
 }
@@ -359,7 +349,7 @@ static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    int32_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     if (dev->realized) {
         qdev_prop_set_after_realize(dev, name, errp);
@@ -388,9 +378,8 @@ const PropertyInfo qdev_prop_int32 = {
 static void get_uint64(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     visit_type_uint64(v, name, ptr, errp);
 }
@@ -400,7 +389,7 @@ static void set_uint64(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     if (dev->realized) {
         qdev_prop_set_after_realize(dev, name, errp);
@@ -413,9 +402,8 @@ static void set_uint64(Object *obj, Visitor *v, const char *name,
 static void get_int64(Object *obj, Visitor *v, const char *name,
                       void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    int64_t *ptr = qdev_get_prop_ptr(dev, prop);
+    int64_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     visit_type_int64(v, name, ptr, errp);
 }
@@ -425,7 +413,7 @@ static void set_int64(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    int64_t *ptr = qdev_get_prop_ptr(dev, prop);
+    int64_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     if (dev->realized) {
         qdev_prop_set_after_realize(dev, name, errp);
@@ -454,15 +442,14 @@ const PropertyInfo qdev_prop_int64 = {
 static void release_string(Object *obj, const char *name, void *opaque)
 {
     Property *prop = opaque;
-    g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
+    g_free(*(char **)qdev_get_prop_ptr(obj, prop));
 }
 
 static void get_string(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    char **ptr = qdev_get_prop_ptr(dev, prop);
+    char **ptr = qdev_get_prop_ptr(obj, prop);
 
     if (!*ptr) {
         char *str = (char *)"";
@@ -477,7 +464,7 @@ static void set_string(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    char **ptr = qdev_get_prop_ptr(dev, prop);
+    char **ptr = qdev_get_prop_ptr(obj, prop);
     char *str;
 
     if (dev->realized) {
@@ -515,9 +502,8 @@ const PropertyInfo qdev_prop_on_off_auto = {
 void qdev_propinfo_get_size32(Object *obj, Visitor *v, const char *name,
                               void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
     uint64_t value = *ptr;
 
     visit_type_size(v, name, &value, errp);
@@ -528,7 +514,7 @@ static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
     uint64_t value;
 
     if (dev->realized) {
@@ -563,9 +549,8 @@ const PropertyInfo qdev_prop_size32 = {
 static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    QemuUUID *uuid = qdev_get_prop_ptr(dev, prop);
+    QemuUUID *uuid = qdev_get_prop_ptr(obj, prop);
     char buffer[UUID_FMT_LEN + 1];
     char *p = buffer;
 
@@ -581,7 +566,7 @@ static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    QemuUUID *uuid = qdev_get_prop_ptr(dev, prop);
+    QemuUUID *uuid = qdev_get_prop_ptr(obj, prop);
     char *str;
 
     if (dev->realized) {
@@ -653,7 +638,7 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
      */
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint32_t *alenptr = qdev_get_prop_ptr(dev, prop);
+    uint32_t *alenptr = qdev_get_prop_ptr(obj, prop);
     void **arrayptr = (void *)dev + prop->arrayoffset;
     void *eltptr;
     const char *arrayname;
@@ -699,7 +684,7 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
          * being inside the device struct.
          */
         arrayprop->prop.offset = eltptr - (void *)dev;
-        assert(qdev_get_prop_ptr(dev, &arrayprop->prop) == eltptr);
+        assert(qdev_get_prop_ptr(obj, &arrayprop->prop) == eltptr);
         object_property_add(obj, propname,
                             arrayprop->prop.info->name,
                             arrayprop->prop.info->get,
@@ -893,9 +878,8 @@ void qdev_prop_set_globals(DeviceState *dev)
 static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     visit_type_size(v, name, ptr, errp);
 }
@@ -905,7 +889,7 @@ static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     if (dev->realized) {
         qdev_prop_set_after_realize(dev, name, errp);
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 9961cfe7bf..2b8f33fec2 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -2343,9 +2343,8 @@ void css_reset(void)
 static void get_css_devid(Object *obj, Visitor *v, const char *name,
                           void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    CssDevId *dev_id = qdev_get_prop_ptr(dev, prop);
+    CssDevId *dev_id = qdev_get_prop_ptr(obj, prop);
     char buffer[] = "xx.x.xxxx";
     char *p = buffer;
     int r;
@@ -2375,7 +2374,7 @@ static void set_css_devid(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    CssDevId *dev_id = qdev_get_prop_ptr(dev, prop);
+    CssDevId *dev_id = qdev_get_prop_ptr(obj, prop);
     char *str;
     int num, n1, n2;
     unsigned int cssid, ssid, devid;
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 48a3be802f..ab27b6e848 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -1323,7 +1323,7 @@ static void s390_pci_get_fid(Object *obj, Visitor *v, const char *name,
                          void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(DEVICE(obj), prop);
+    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     visit_type_uint32(v, name, ptr, errp);
 }
@@ -1334,7 +1334,7 @@ static void s390_pci_set_fid(Object *obj, Visitor *v, const char *name,
     DeviceState *dev = DEVICE(obj);
     S390PCIBusDevice *zpci = S390_PCI_DEVICE(obj);
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     if (dev->realized) {
         qdev_prop_set_after_realize(dev, name, errp);
diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
index 57150913b7..53569925a2 100644
--- a/hw/vfio/pci-quirks.c
+++ b/hw/vfio/pci-quirks.c
@@ -1488,9 +1488,8 @@ static void get_nv_gpudirect_clique_id(Object *obj, Visitor *v,
                                        const char *name, void *opaque,
                                        Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
+    uint8_t *ptr = qdev_get_prop_ptr(obj, prop);
 
     visit_type_uint8(v, name, ptr, errp);
 }
@@ -1501,7 +1500,7 @@ static void set_nv_gpudirect_clique_id(Object *obj, Visitor *v,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint8_t value, *ptr = qdev_get_prop_ptr(dev, prop);
+    uint8_t value, *ptr = qdev_get_prop_ptr(obj, prop);
 
     if (dev->realized) {
         qdev_prop_set_after_realize(dev, name, errp);
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 10/44] qdev: Make qdev_find_global_prop() get Object* argument
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (8 preceding siblings ...)
  2020-11-04 15:59   ` Eduardo Habkost
@ 2020-11-04 15:59 ` Eduardo Habkost
  2020-11-04 15:59 ` [PATCH v2 11/44] qdev: Make check_prop_still_unset() " Eduardo Habkost
                   ` (35 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 15:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

Make the code more generic and not specific to TYPE_DEVICE.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 include/hw/qdev-properties.h     | 2 +-
 hw/core/qdev-properties-system.c | 2 +-
 hw/core/qdev-properties.c        | 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 0b92cfc761..7620095fed 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -305,7 +305,7 @@ void qdev_prop_set_enum(DeviceState *dev, const char *name, int value);
 void *qdev_get_prop_ptr(Object *obj, Property *prop);
 
 void qdev_prop_register_global(GlobalProperty *prop);
-const GlobalProperty *qdev_find_global_prop(DeviceState *dev,
+const GlobalProperty *qdev_find_global_prop(Object *obj,
                                             const char *name);
 int qdev_prop_check_globals(void);
 void qdev_prop_set_globals(DeviceState *dev);
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index c8c73c371b..af1339e562 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -36,7 +36,7 @@ static bool check_prop_still_unset(DeviceState *dev, const char *name,
                                    const void *old_val, const char *new_val,
                                    Error **errp)
 {
-    const GlobalProperty *prop = qdev_find_global_prop(dev, name);
+    const GlobalProperty *prop = qdev_find_global_prop(OBJECT(dev), name);
 
     if (!old_val) {
         return true;
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 0a54a922c8..41482d83d1 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -818,7 +818,7 @@ void qdev_prop_register_global(GlobalProperty *prop)
     g_ptr_array_add(global_props(), prop);
 }
 
-const GlobalProperty *qdev_find_global_prop(DeviceState *dev,
+const GlobalProperty *qdev_find_global_prop(Object *obj,
                                             const char *name)
 {
     GPtrArray *props = global_props();
@@ -827,7 +827,7 @@ const GlobalProperty *qdev_find_global_prop(DeviceState *dev,
 
     for (i = 0; i < props->len; i++) {
         p = g_ptr_array_index(props, i);
-        if (object_dynamic_cast(OBJECT(dev), p->driver)
+        if (object_dynamic_cast(obj, p->driver)
             && !strcmp(p->property, name)) {
             return p;
         }
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 11/44] qdev: Make check_prop_still_unset() get Object* argument
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (9 preceding siblings ...)
  2020-11-04 15:59 ` [PATCH v2 10/44] qdev: Make qdev_find_global_prop() get Object* argument Eduardo Habkost
@ 2020-11-04 15:59 ` Eduardo Habkost
  2020-11-04 15:59 ` [PATCH v2 12/44] qdev: Make error_set_from_qdev_prop_error() " Eduardo Habkost
                   ` (34 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 15:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

Make the code more generic and not specific to TYPE_DEVICE.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 hw/core/qdev-properties-system.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index af1339e562..85dd38db0f 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -32,11 +32,11 @@
 #include "hw/pci/pci.h"
 #include "util/block-helpers.h"
 
-static bool check_prop_still_unset(DeviceState *dev, const char *name,
+static bool check_prop_still_unset(Object *obj, const char *name,
                                    const void *old_val, const char *new_val,
                                    Error **errp)
 {
-    const GlobalProperty *prop = qdev_find_global_prop(OBJECT(dev), name);
+    const GlobalProperty *prop = qdev_find_global_prop(obj, name);
 
     if (!old_val) {
         return true;
@@ -105,7 +105,7 @@ static void set_drive_helper(Object *obj, Visitor *v, const char *name,
      * TODO Should this really be an error?  If no, the old value
      * needs to be released before we store the new one.
      */
-    if (!check_prop_still_unset(dev, name, *ptr, str, errp)) {
+    if (!check_prop_still_unset(obj, name, *ptr, str, errp)) {
         return;
     }
 
@@ -247,7 +247,7 @@ static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
      * TODO Should this really be an error?  If no, the old value
      * needs to be released before we store the new one.
      */
-    if (!check_prop_still_unset(dev, name, be->chr, str, errp)) {
+    if (!check_prop_still_unset(obj, name, be->chr, str, errp)) {
         return;
     }
 
@@ -429,7 +429,7 @@ static void set_netdev(Object *obj, Visitor *v, const char *name,
          * TODO Should this really be an error?  If no, the old value
          * needs to be released before we store the new one.
          */
-        if (!check_prop_still_unset(dev, name, ncs[i], str, errp)) {
+        if (!check_prop_still_unset(obj, name, ncs[i], str, errp)) {
             goto out;
         }
 
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 12/44] qdev: Make error_set_from_qdev_prop_error() get Object* argument
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (10 preceding siblings ...)
  2020-11-04 15:59 ` [PATCH v2 11/44] qdev: Make check_prop_still_unset() " Eduardo Habkost
@ 2020-11-04 15:59 ` Eduardo Habkost
  2020-11-04 15:59 ` [PATCH v2 13/44] qdev: Move UUID property to qdev-properties-system.c Eduardo Habkost
                   ` (33 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 15:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, Daniel P. Berrange, David Hildenbrand, John Snow,
	Cornelia Huck, Markus Armbruster, Philippe Mathieu-Daudé,
	Halil Pasic, Marc-André Lureau, qemu-s390x, Igor Mammedov,
	Paolo Bonzini, Richard Henderson, Christian Borntraeger,
	Stefan Berger

Make the code more generic and not specific to TYPE_DEVICE.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: Cornelia Huck <cohuck@redhat.com>
Cc: Thomas Huth <thuth@redhat.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: David Hildenbrand <david@redhat.com>
Cc: Halil Pasic <pasic@linux.ibm.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: qemu-devel@nongnu.org
Cc: qemu-s390x@nongnu.org
---
 include/hw/qdev-properties.h     |  2 +-
 hw/core/qdev-properties-system.c | 10 +++++-----
 hw/core/qdev-properties.c        | 10 +++++-----
 hw/s390x/css.c                   |  2 +-
 4 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 7620095fed..530286e869 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -309,7 +309,7 @@ const GlobalProperty *qdev_find_global_prop(Object *obj,
                                             const char *name);
 int qdev_prop_check_globals(void);
 void qdev_prop_set_globals(DeviceState *dev);
-void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
+void error_set_from_qdev_prop_error(Error **errp, int ret, Object *obj,
                                     Property *prop, const char *value);
 
 /**
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 85dd38db0f..fca1b694ca 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -352,7 +352,7 @@ static void set_mac(Object *obj, Visitor *v, const char *name, void *opaque,
     return;
 
 inval:
-    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
+    error_set_from_qdev_prop_error(errp, EINVAL, obj, prop, str);
     g_free(str);
 }
 
@@ -440,7 +440,7 @@ static void set_netdev(Object *obj, Visitor *v, const char *name,
     peers_ptr->queues = queues;
 
 out:
-    error_set_from_qdev_prop_error(errp, err, dev, prop, str);
+    error_set_from_qdev_prop_error(errp, err, obj, prop, str);
     g_free(str);
 }
 
@@ -492,7 +492,7 @@ static void set_audiodev(Object *obj, Visitor *v, const char* name,
     card->state = state;
 
 out:
-    error_set_from_qdev_prop_error(errp, err, dev, prop, str);
+    error_set_from_qdev_prop_error(errp, err, obj, prop, str);
     g_free(str);
 }
 
@@ -790,7 +790,7 @@ static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
     return;
 
 invalid:
-    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
+    error_set_from_qdev_prop_error(errp, EINVAL, obj, prop, str);
     g_free(str);
 }
 
@@ -913,7 +913,7 @@ static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
     return;
 
 inval:
-    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
+    error_set_from_qdev_prop_error(errp, EINVAL, obj, prop, str);
     g_free(str);
 }
 
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 41482d83d1..5e010afdb8 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -581,7 +581,7 @@ static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
     if (!strcmp(str, UUID_VALUE_AUTO)) {
         qemu_uuid_generate(uuid);
     } else if (qemu_uuid_parse(str, uuid) < 0) {
-        error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
+        error_set_from_qdev_prop_error(errp, EINVAL, obj, prop, str);
     }
     g_free(str);
 }
@@ -735,22 +735,22 @@ static Property *qdev_prop_find(DeviceState *dev, const char *name)
     return NULL;
 }
 
-void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
+void error_set_from_qdev_prop_error(Error **errp, int ret, Object *obj,
                                     Property *prop, const char *value)
 {
     switch (ret) {
     case -EEXIST:
         error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use",
-                  object_get_typename(OBJECT(dev)), prop->name, value);
+                  object_get_typename(obj), prop->name, value);
         break;
     default:
     case -EINVAL:
         error_setg(errp, QERR_PROPERTY_VALUE_BAD,
-                   object_get_typename(OBJECT(dev)), prop->name, value);
+                   object_get_typename(obj), prop->name, value);
         break;
     case -ENOENT:
         error_setg(errp, "Property '%s.%s' can't find value '%s'",
-                  object_get_typename(OBJECT(dev)), prop->name, value);
+                  object_get_typename(obj), prop->name, value);
         break;
     case 0:
         break;
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 2b8f33fec2..38fd46b9a9 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -2390,7 +2390,7 @@ static void set_css_devid(Object *obj, Visitor *v, const char *name,
 
     num = sscanf(str, "%2x.%1x%n.%4x%n", &cssid, &ssid, &n1, &devid, &n2);
     if (num != 3 || (n2 - n1) != 5 || strlen(str) != n2) {
-        error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
+        error_set_from_qdev_prop_error(errp, EINVAL, obj, prop, str);
         goto out;
     }
     if ((cssid > MAX_CSSID) || (ssid > MAX_SSID)) {
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 13/44] qdev: Move UUID property to qdev-properties-system.c
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (11 preceding siblings ...)
  2020-11-04 15:59 ` [PATCH v2 12/44] qdev: Make error_set_from_qdev_prop_error() " Eduardo Habkost
@ 2020-11-04 15:59 ` Eduardo Habkost
  2020-11-04 15:59 ` [PATCH v2 14/44] qdev: Move softmmu properties to qdev-properties-system.h Eduardo Habkost
                   ` (32 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 15:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

Only softmmu code uses DEFINE_PROP_UUID, and it currently depends
on error_set_from_qdev_prop_error().  Move it to
qdev-properties-system.c to get out of our way when refactoring
the qdev property system.

We can eventually move it back to the core property system later,
after removing usage of error_set_from_qdev_prop_error().

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
This is a new patch added in series v2
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 hw/core/qdev-properties-system.c | 57 ++++++++++++++++++++++++++++++++
 hw/core/qdev-properties.c        | 57 --------------------------------
 2 files changed, 57 insertions(+), 57 deletions(-)

diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index fca1b694ca..35515886a9 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -21,6 +21,7 @@
 #include "qemu/ctype.h"
 #include "qemu/cutils.h"
 #include "qemu/units.h"
+#include "qemu/uuid.h"
 #include "qemu/error-report.h"
 #include "qdev-prop-internal.h"
 
@@ -1105,3 +1106,59 @@ const PropertyInfo qdev_prop_pcie_link_width = {
     .set = set_prop_pcielinkwidth,
     .set_default_value = qdev_propinfo_set_default_value_enum,
 };
+
+/* --- UUID --- */
+
+static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
+                     Error **errp)
+{
+    Property *prop = opaque;
+    QemuUUID *uuid = qdev_get_prop_ptr(obj, prop);
+    char buffer[UUID_FMT_LEN + 1];
+    char *p = buffer;
+
+    qemu_uuid_unparse(uuid, buffer);
+
+    visit_type_str(v, name, &p, errp);
+}
+
+#define UUID_VALUE_AUTO        "auto"
+
+static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
+                    Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    QemuUUID *uuid = qdev_get_prop_ptr(obj, prop);
+    char *str;
+
+    if (dev->realized) {
+        qdev_prop_set_after_realize(dev, name, errp);
+        return;
+    }
+
+    if (!visit_type_str(v, name, &str, errp)) {
+        return;
+    }
+
+    if (!strcmp(str, UUID_VALUE_AUTO)) {
+        qemu_uuid_generate(uuid);
+    } else if (qemu_uuid_parse(str, uuid) < 0) {
+        error_set_from_qdev_prop_error(errp, EINVAL, obj, prop, str);
+    }
+    g_free(str);
+}
+
+static void set_default_uuid_auto(ObjectProperty *op, const Property *prop)
+{
+    object_property_set_default_str(op, UUID_VALUE_AUTO);
+}
+
+const PropertyInfo qdev_prop_uuid = {
+    .name  = "str",
+    .description = "UUID (aka GUID) or \"" UUID_VALUE_AUTO
+        "\" for random value (default)",
+    .get   = get_uuid,
+    .set   = set_uuid,
+    .set_default_value = set_default_uuid_auto,
+};
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 5e010afdb8..d7796e8cc3 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -6,7 +6,6 @@
 #include "qemu/ctype.h"
 #include "qemu/error-report.h"
 #include "qapi/visitor.h"
-#include "qemu/uuid.h"
 #include "qemu/units.h"
 #include "qemu/cutils.h"
 #include "qdev-prop-internal.h"
@@ -544,62 +543,6 @@ const PropertyInfo qdev_prop_size32 = {
     .set_default_value = qdev_propinfo_set_default_value_uint,
 };
 
-/* --- UUID --- */
-
-static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
-                     Error **errp)
-{
-    Property *prop = opaque;
-    QemuUUID *uuid = qdev_get_prop_ptr(obj, prop);
-    char buffer[UUID_FMT_LEN + 1];
-    char *p = buffer;
-
-    qemu_uuid_unparse(uuid, buffer);
-
-    visit_type_str(v, name, &p, errp);
-}
-
-#define UUID_VALUE_AUTO        "auto"
-
-static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
-                    Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    QemuUUID *uuid = qdev_get_prop_ptr(obj, prop);
-    char *str;
-
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
-    if (!visit_type_str(v, name, &str, errp)) {
-        return;
-    }
-
-    if (!strcmp(str, UUID_VALUE_AUTO)) {
-        qemu_uuid_generate(uuid);
-    } else if (qemu_uuid_parse(str, uuid) < 0) {
-        error_set_from_qdev_prop_error(errp, EINVAL, obj, prop, str);
-    }
-    g_free(str);
-}
-
-static void set_default_uuid_auto(ObjectProperty *op, const Property *prop)
-{
-    object_property_set_default_str(op, UUID_VALUE_AUTO);
-}
-
-const PropertyInfo qdev_prop_uuid = {
-    .name  = "str",
-    .description = "UUID (aka GUID) or \"" UUID_VALUE_AUTO
-        "\" for random value (default)",
-    .get   = get_uuid,
-    .set   = set_uuid,
-    .set_default_value = set_default_uuid_auto,
-};
-
 /* --- support for array properties --- */
 
 /* Used as an opaque for the object properties we add for each
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 14/44] qdev: Move softmmu properties to qdev-properties-system.h
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (12 preceding siblings ...)
  2020-11-04 15:59 ` [PATCH v2 13/44] qdev: Move UUID property to qdev-properties-system.c Eduardo Habkost
@ 2020-11-04 15:59 ` Eduardo Habkost
  2020-11-04 15:59 ` [PATCH v2 15/44] qdev: Reuse DEFINE_PROP in all DEFINE_PROP_* macros Eduardo Habkost
                   ` (31 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 15:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

Move the property types and property macros implemented in
qdev-properties-system.c to a new qdev-properties-system.h
header.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Changes v1 -> v2:
* Move UUID property type too, as it was moved to
  qdev-properties-system.c in the previous patch
---
 audio/audio.h                       |  1 +
 include/hw/block/block.h            |  1 +
 include/hw/qdev-properties-system.h | 84 +++++++++++++++++++++++++++++
 include/hw/qdev-properties.h        | 75 --------------------------
 include/net/net.h                   |  1 +
 hw/acpi/vmgenid.c                   |  1 +
 hw/arm/pxa2xx.c                     |  1 +
 hw/arm/strongarm.c                  |  1 +
 hw/block/fdc.c                      |  1 +
 hw/block/m25p80.c                   |  1 +
 hw/block/nand.c                     |  1 +
 hw/block/onenand.c                  |  1 +
 hw/block/pflash_cfi01.c             |  1 +
 hw/block/pflash_cfi02.c             |  1 +
 hw/block/vhost-user-blk.c           |  1 +
 hw/char/avr_usart.c                 |  1 +
 hw/char/bcm2835_aux.c               |  1 +
 hw/char/cadence_uart.c              |  1 +
 hw/char/cmsdk-apb-uart.c            |  1 +
 hw/char/debugcon.c                  |  1 +
 hw/char/digic-uart.c                |  1 +
 hw/char/escc.c                      |  1 +
 hw/char/etraxfs_ser.c               |  1 +
 hw/char/exynos4210_uart.c           |  1 +
 hw/char/grlib_apbuart.c             |  1 +
 hw/char/ibex_uart.c                 |  1 +
 hw/char/imx_serial.c                |  1 +
 hw/char/ipoctal232.c                |  1 +
 hw/char/lm32_juart.c                |  1 +
 hw/char/lm32_uart.c                 |  1 +
 hw/char/mcf_uart.c                  |  1 +
 hw/char/milkymist-uart.c            |  1 +
 hw/char/nrf51_uart.c                |  1 +
 hw/char/parallel.c                  |  1 +
 hw/char/pl011.c                     |  1 +
 hw/char/renesas_sci.c               |  1 +
 hw/char/sclpconsole-lm.c            |  1 +
 hw/char/sclpconsole.c               |  1 +
 hw/char/serial-pci-multi.c          |  1 +
 hw/char/serial.c                    |  1 +
 hw/char/spapr_vty.c                 |  1 +
 hw/char/stm32f2xx_usart.c           |  1 +
 hw/char/terminal3270.c              |  1 +
 hw/char/virtio-console.c            |  1 +
 hw/char/xilinx_uartlite.c           |  1 +
 hw/core/qdev-properties-system.c    |  1 +
 hw/hyperv/vmbus.c                   |  1 +
 hw/i386/kvm/i8254.c                 |  1 +
 hw/ide/qdev.c                       |  1 +
 hw/ipmi/ipmi_bmc_extern.c           |  1 +
 hw/ipmi/ipmi_bmc_sim.c              |  1 +
 hw/misc/allwinner-sid.c             |  1 +
 hw/misc/ivshmem.c                   |  1 +
 hw/misc/mac_via.c                   |  1 +
 hw/misc/sifive_u_otp.c              |  1 +
 hw/net/rocker/rocker.c              |  1 +
 hw/nvram/eeprom_at24c.c             |  1 +
 hw/nvram/spapr_nvram.c              |  1 +
 hw/pci-bridge/gen_pcie_root_port.c  |  1 +
 hw/pci/pci.c                        |  1 +
 hw/ppc/pnv_pnor.c                   |  1 +
 hw/rdma/vmw/pvrdma_main.c           |  1 +
 hw/rtc/mc146818rtc.c                |  1 +
 hw/scsi/scsi-disk.c                 |  1 +
 hw/scsi/scsi-generic.c              |  1 +
 hw/scsi/vhost-user-scsi.c           |  1 +
 hw/sd/sd.c                          |  1 +
 hw/usb/ccid-card-passthru.c         |  1 +
 hw/usb/dev-serial.c                 |  1 +
 hw/usb/redirect.c                   |  1 +
 hw/vfio/pci.c                       |  1 +
 hw/virtio/vhost-user-fs.c           |  1 +
 hw/virtio/vhost-user-vsock.c        |  1 +
 hw/virtio/virtio-iommu-pci.c        |  1 +
 hw/xen/xen_pt.c                     |  1 +
 migration/migration.c               |  1 +
 76 files changed, 158 insertions(+), 75 deletions(-)
 create mode 100644 include/hw/qdev-properties-system.h

diff --git a/audio/audio.h b/audio/audio.h
index b883ebfb1f..21fe3226ae 100644
--- a/audio/audio.h
+++ b/audio/audio.h
@@ -28,6 +28,7 @@
 #include "qemu/queue.h"
 #include "qapi/qapi-types-audio.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 
 typedef void (*audio_callback_fn) (void *opaque, int avail);
 
diff --git a/include/hw/block/block.h b/include/hw/block/block.h
index 1e8b6253dd..c172cbe65f 100644
--- a/include/hw/block/block.h
+++ b/include/hw/block/block.h
@@ -13,6 +13,7 @@
 
 #include "exec/hwaddr.h"
 #include "qapi/qapi-types-block-core.h"
+#include "hw/qdev-properties-system.h"
 
 /* Configuration */
 
diff --git a/include/hw/qdev-properties-system.h b/include/hw/qdev-properties-system.h
new file mode 100644
index 0000000000..29529dc999
--- /dev/null
+++ b/include/hw/qdev-properties-system.h
@@ -0,0 +1,84 @@
+#ifndef HW_QDEV_PROPERTIES_SYSTEM_H
+#define HW_QDEV_PROPERTIES_SYSTEM_H
+
+#include "hw/qdev-properties.h"
+
+extern const PropertyInfo qdev_prop_chr;
+extern const PropertyInfo qdev_prop_macaddr;
+extern const PropertyInfo qdev_prop_reserved_region;
+extern const PropertyInfo qdev_prop_multifd_compression;
+extern const PropertyInfo qdev_prop_losttickpolicy;
+extern const PropertyInfo qdev_prop_blockdev_on_error;
+extern const PropertyInfo qdev_prop_bios_chs_trans;
+extern const PropertyInfo qdev_prop_fdc_drive_type;
+extern const PropertyInfo qdev_prop_drive;
+extern const PropertyInfo qdev_prop_drive_iothread;
+extern const PropertyInfo qdev_prop_netdev;
+extern const PropertyInfo qdev_prop_pci_devfn;
+extern const PropertyInfo qdev_prop_blocksize;
+extern const PropertyInfo qdev_prop_pci_host_devaddr;
+extern const PropertyInfo qdev_prop_uuid;
+extern const PropertyInfo qdev_prop_audiodev;
+extern const PropertyInfo qdev_prop_off_auto_pcibar;
+extern const PropertyInfo qdev_prop_pcie_link_speed;
+extern const PropertyInfo qdev_prop_pcie_link_width;
+
+#define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d)                   \
+    DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t)
+
+#define DEFINE_PROP_CHR(_n, _s, _f)             \
+    DEFINE_PROP(_n, _s, _f, qdev_prop_chr, CharBackend)
+#define DEFINE_PROP_NETDEV(_n, _s, _f)             \
+    DEFINE_PROP(_n, _s, _f, qdev_prop_netdev, NICPeers)
+#define DEFINE_PROP_DRIVE(_n, _s, _f) \
+    DEFINE_PROP(_n, _s, _f, qdev_prop_drive, BlockBackend *)
+#define DEFINE_PROP_DRIVE_IOTHREAD(_n, _s, _f) \
+    DEFINE_PROP(_n, _s, _f, qdev_prop_drive_iothread, BlockBackend *)
+#define DEFINE_PROP_MACADDR(_n, _s, _f)         \
+    DEFINE_PROP(_n, _s, _f, qdev_prop_macaddr, MACAddr)
+#define DEFINE_PROP_RESERVED_REGION(_n, _s, _f)         \
+    DEFINE_PROP(_n, _s, _f, qdev_prop_reserved_region, ReservedRegion)
+#define DEFINE_PROP_MULTIFD_COMPRESSION(_n, _s, _f, _d) \
+    DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_multifd_compression, \
+                       MultiFDCompression)
+#define DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \
+    DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_losttickpolicy, \
+                        LostTickPolicy)
+#define DEFINE_PROP_BLOCKDEV_ON_ERROR(_n, _s, _f, _d) \
+    DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_blockdev_on_error, \
+                        BlockdevOnError)
+#define DEFINE_PROP_BIOS_CHS_TRANS(_n, _s, _f, _d) \
+    DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_bios_chs_trans, int)
+#define DEFINE_PROP_BLOCKSIZE(_n, _s, _f) \
+    DEFINE_PROP_UNSIGNED(_n, _s, _f, 0, qdev_prop_blocksize, uint32_t)
+#define DEFINE_PROP_PCI_HOST_DEVADDR(_n, _s, _f) \
+    DEFINE_PROP(_n, _s, _f, qdev_prop_pci_host_devaddr, PCIHostDeviceAddress)
+#define DEFINE_PROP_OFF_AUTO_PCIBAR(_n, _s, _f, _d) \
+    DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_off_auto_pcibar, \
+                        OffAutoPCIBAR)
+#define DEFINE_PROP_PCIE_LINK_SPEED(_n, _s, _f, _d) \
+    DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pcie_link_speed, \
+                        PCIExpLinkSpeed)
+#define DEFINE_PROP_PCIE_LINK_WIDTH(_n, _s, _f, _d) \
+    DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pcie_link_width, \
+                        PCIExpLinkWidth)
+
+#define DEFINE_PROP_UUID(_name, _state, _field) {                  \
+        .name      = (_name),                                      \
+        .info      = &qdev_prop_uuid,                              \
+        .offset    = offsetof(_state, _field)                      \
+            + type_check(QemuUUID, typeof_field(_state, _field)),  \
+        .set_default = true,                                       \
+        }
+#define DEFINE_PROP_AUDIODEV(_n, _s, _f) \
+    DEFINE_PROP(_n, _s, _f, qdev_prop_audiodev, QEMUSoundCard)
+
+#define DEFINE_PROP_UUID_NODEFAULT(_name, _state, _field) {        \
+        .name      = (_name),                                      \
+        .info      = &qdev_prop_uuid,                              \
+        .offset    = offsetof(_state, _field)                      \
+            + type_check(QemuUUID, typeof_field(_state, _field)),  \
+        }
+
+
+#endif
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 530286e869..d35d4aae84 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -55,30 +55,11 @@ extern const PropertyInfo qdev_prop_uint64;
 extern const PropertyInfo qdev_prop_int64;
 extern const PropertyInfo qdev_prop_size;
 extern const PropertyInfo qdev_prop_string;
-extern const PropertyInfo qdev_prop_chr;
 extern const PropertyInfo qdev_prop_tpm;
-extern const PropertyInfo qdev_prop_macaddr;
-extern const PropertyInfo qdev_prop_reserved_region;
 extern const PropertyInfo qdev_prop_on_off_auto;
-extern const PropertyInfo qdev_prop_multifd_compression;
-extern const PropertyInfo qdev_prop_losttickpolicy;
-extern const PropertyInfo qdev_prop_blockdev_on_error;
-extern const PropertyInfo qdev_prop_bios_chs_trans;
-extern const PropertyInfo qdev_prop_fdc_drive_type;
-extern const PropertyInfo qdev_prop_drive;
-extern const PropertyInfo qdev_prop_drive_iothread;
-extern const PropertyInfo qdev_prop_netdev;
-extern const PropertyInfo qdev_prop_pci_devfn;
 extern const PropertyInfo qdev_prop_size32;
-extern const PropertyInfo qdev_prop_blocksize;
-extern const PropertyInfo qdev_prop_pci_host_devaddr;
-extern const PropertyInfo qdev_prop_uuid;
 extern const PropertyInfo qdev_prop_arraylen;
-extern const PropertyInfo qdev_prop_audiodev;
 extern const PropertyInfo qdev_prop_link;
-extern const PropertyInfo qdev_prop_off_auto_pcibar;
-extern const PropertyInfo qdev_prop_pcie_link_speed;
-extern const PropertyInfo qdev_prop_pcie_link_width;
 
 #define DEFINE_PROP(_name, _state, _field, _prop, _type) { \
         .name      = (_name),                                    \
@@ -209,68 +190,12 @@ extern const PropertyInfo qdev_prop_pcie_link_width;
     DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_int64, int64_t)
 #define DEFINE_PROP_SIZE(_n, _s, _f, _d)                       \
     DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, qdev_prop_size, uint64_t)
-#define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d)                   \
-    DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t)
-
-#define DEFINE_PROP_CHR(_n, _s, _f)             \
-    DEFINE_PROP(_n, _s, _f, qdev_prop_chr, CharBackend)
 #define DEFINE_PROP_STRING(_n, _s, _f)             \
     DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*)
-#define DEFINE_PROP_NETDEV(_n, _s, _f)             \
-    DEFINE_PROP(_n, _s, _f, qdev_prop_netdev, NICPeers)
-#define DEFINE_PROP_DRIVE(_n, _s, _f) \
-    DEFINE_PROP(_n, _s, _f, qdev_prop_drive, BlockBackend *)
-#define DEFINE_PROP_DRIVE_IOTHREAD(_n, _s, _f) \
-    DEFINE_PROP(_n, _s, _f, qdev_prop_drive_iothread, BlockBackend *)
-#define DEFINE_PROP_MACADDR(_n, _s, _f)         \
-    DEFINE_PROP(_n, _s, _f, qdev_prop_macaddr, MACAddr)
-#define DEFINE_PROP_RESERVED_REGION(_n, _s, _f)         \
-    DEFINE_PROP(_n, _s, _f, qdev_prop_reserved_region, ReservedRegion)
 #define DEFINE_PROP_ON_OFF_AUTO(_n, _s, _f, _d) \
     DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_on_off_auto, OnOffAuto)
-#define DEFINE_PROP_MULTIFD_COMPRESSION(_n, _s, _f, _d) \
-    DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_multifd_compression, \
-                       MultiFDCompression)
-#define DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \
-    DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_losttickpolicy, \
-                        LostTickPolicy)
-#define DEFINE_PROP_BLOCKDEV_ON_ERROR(_n, _s, _f, _d) \
-    DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_blockdev_on_error, \
-                        BlockdevOnError)
-#define DEFINE_PROP_BIOS_CHS_TRANS(_n, _s, _f, _d) \
-    DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_bios_chs_trans, int)
 #define DEFINE_PROP_SIZE32(_n, _s, _f, _d)                       \
     DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, qdev_prop_size32, uint32_t)
-#define DEFINE_PROP_BLOCKSIZE(_n, _s, _f) \
-    DEFINE_PROP_UNSIGNED(_n, _s, _f, 0, qdev_prop_blocksize, uint32_t)
-#define DEFINE_PROP_PCI_HOST_DEVADDR(_n, _s, _f) \
-    DEFINE_PROP(_n, _s, _f, qdev_prop_pci_host_devaddr, PCIHostDeviceAddress)
-#define DEFINE_PROP_OFF_AUTO_PCIBAR(_n, _s, _f, _d) \
-    DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_off_auto_pcibar, \
-                        OffAutoPCIBAR)
-#define DEFINE_PROP_PCIE_LINK_SPEED(_n, _s, _f, _d) \
-    DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pcie_link_speed, \
-                        PCIExpLinkSpeed)
-#define DEFINE_PROP_PCIE_LINK_WIDTH(_n, _s, _f, _d) \
-    DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pcie_link_width, \
-                        PCIExpLinkWidth)
-
-#define DEFINE_PROP_UUID(_name, _state, _field) {                  \
-        .name      = (_name),                                      \
-        .info      = &qdev_prop_uuid,                              \
-        .offset    = offsetof(_state, _field)                      \
-            + type_check(QemuUUID, typeof_field(_state, _field)),  \
-        .set_default = true,                                       \
-        }
-#define DEFINE_PROP_AUDIODEV(_n, _s, _f) \
-    DEFINE_PROP(_n, _s, _f, qdev_prop_audiodev, QEMUSoundCard)
-
-#define DEFINE_PROP_UUID_NODEFAULT(_name, _state, _field) {        \
-        .name      = (_name),                                      \
-        .info      = &qdev_prop_uuid,                              \
-        .offset    = offsetof(_state, _field)                      \
-            + type_check(QemuUUID, typeof_field(_state, _field)),  \
-        }
 
 #define DEFINE_PROP_END_OF_LIST()               \
     {}
diff --git a/include/net/net.h b/include/net/net.h
index 897b2d7595..da48bc8254 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -4,6 +4,7 @@
 #include "qemu/queue.h"
 #include "qapi/qapi-types-net.h"
 #include "net/queue.h"
+#include "hw/qdev-properties-system.h"
 
 #define MAC_FMT "%02X:%02X:%02X:%02X:%02X:%02X"
 #define MAC_ARG(x) ((uint8_t *)(x))[0], ((uint8_t *)(x))[1], \
diff --git a/hw/acpi/vmgenid.c b/hw/acpi/vmgenid.c
index 2c8152d508..6c92fdae49 100644
--- a/hw/acpi/vmgenid.c
+++ b/hw/acpi/vmgenid.c
@@ -19,6 +19,7 @@
 #include "hw/acpi/vmgenid.h"
 #include "hw/nvram/fw_cfg.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "migration/vmstate.h"
 #include "sysemu/reset.h"
 
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index 591776ba88..9c8030a271 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -21,6 +21,7 @@
 #include "hw/i2c/i2c.h"
 #include "hw/irq.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "hw/ssi/ssi.h"
 #include "hw/sd/sd.h"
 #include "chardev/char-fe.h"
diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
index ca7c385f31..c7ca54bcea 100644
--- a/hw/arm/strongarm.c
+++ b/hw/arm/strongarm.c
@@ -33,6 +33,7 @@
 #include "hw/boards.h"
 #include "hw/irq.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "hw/sysbus.h"
 #include "migration/vmstate.h"
 #include "strongarm.h"
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 4c2c35e223..3636874432 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -36,6 +36,7 @@
 #include "hw/irq.h"
 #include "hw/isa/isa.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "hw/sysbus.h"
 #include "migration/vmstate.h"
 #include "hw/block/block.h"
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index 483925f57a..0ef7f00cb6 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -25,6 +25,7 @@
 #include "qemu/units.h"
 #include "sysemu/block-backend.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "hw/ssi/ssi.h"
 #include "migration/vmstate.h"
 #include "qemu/bitops.h"
diff --git a/hw/block/nand.c b/hw/block/nand.c
index bcceb64ebb..5558f5d2fa 100644
--- a/hw/block/nand.c
+++ b/hw/block/nand.c
@@ -21,6 +21,7 @@
 #include "qemu/osdep.h"
 #include "hw/hw.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "hw/block/flash.h"
 #include "sysemu/block-backend.h"
 #include "migration/vmstate.h"
diff --git a/hw/block/onenand.c b/hw/block/onenand.c
index 5ff7be86bb..579a73d7f7 100644
--- a/hw/block/onenand.c
+++ b/hw/block/onenand.c
@@ -24,6 +24,7 @@
 #include "hw/block/flash.h"
 #include "hw/irq.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "sysemu/block-backend.h"
 #include "exec/memory.h"
 #include "hw/sysbus.h"
diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index f0fcd63f84..90baa72f82 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -40,6 +40,7 @@
 #include "hw/block/block.h"
 #include "hw/block/flash.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "sysemu/block-backend.h"
 #include "qapi/error.h"
 #include "qemu/error-report.h"
diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index eb02fccfa5..e2d8a004fe 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -36,6 +36,7 @@
 #include "hw/block/block.h"
 #include "hw/block/flash.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "qapi/error.h"
 #include "qemu/error-report.h"
 #include "qemu/bitmap.h"
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index f67b29bbf3..d0d12e7f29 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -22,6 +22,7 @@
 #include "qemu/cutils.h"
 #include "hw/qdev-core.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-user-blk.h"
 #include "hw/virtio/virtio.h"
diff --git a/hw/char/avr_usart.c b/hw/char/avr_usart.c
index fbe2a112b7..5bcf9db0b7 100644
--- a/hw/char/avr_usart.c
+++ b/hw/char/avr_usart.c
@@ -24,6 +24,7 @@
 #include "qemu/log.h"
 #include "hw/irq.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 
 static int avr_usart_can_receive(void *opaque)
 {
diff --git a/hw/char/bcm2835_aux.c b/hw/char/bcm2835_aux.c
index dade2ab5fd..96410b1ff8 100644
--- a/hw/char/bcm2835_aux.c
+++ b/hw/char/bcm2835_aux.c
@@ -24,6 +24,7 @@
 #include "hw/char/bcm2835_aux.h"
 #include "hw/irq.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "migration/vmstate.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
index e196906c92..c603e14012 100644
--- a/hw/char/cadence_uart.c
+++ b/hw/char/cadence_uart.c
@@ -32,6 +32,7 @@
 #include "hw/char/cadence_uart.h"
 #include "hw/irq.h"
 #include "hw/qdev-clock.h"
+#include "hw/qdev-properties-system.h"
 #include "trace.h"
 
 #ifdef CADENCE_UART_ERR_DEBUG
diff --git a/hw/char/cmsdk-apb-uart.c b/hw/char/cmsdk-apb-uart.c
index 626b68f2ec..ba2cbbee3d 100644
--- a/hw/char/cmsdk-apb-uart.c
+++ b/hw/char/cmsdk-apb-uart.c
@@ -27,6 +27,7 @@
 #include "chardev/char-serial.h"
 #include "hw/char/cmsdk-apb-uart.h"
 #include "hw/irq.h"
+#include "hw/qdev-properties-system.h"
 
 REG32(DATA, 0)
 REG32(STATE, 4)
diff --git a/hw/char/debugcon.c b/hw/char/debugcon.c
index 2a063ad72c..fdb04fee09 100644
--- a/hw/char/debugcon.c
+++ b/hw/char/debugcon.c
@@ -30,6 +30,7 @@
 #include "chardev/char-fe.h"
 #include "hw/isa/isa.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "qom/object.h"
 
 #define TYPE_ISA_DEBUGCON_DEVICE "isa-debugcon"
diff --git a/hw/char/digic-uart.c b/hw/char/digic-uart.c
index e130cb4692..00e5df5517 100644
--- a/hw/char/digic-uart.c
+++ b/hw/char/digic-uart.c
@@ -35,6 +35,7 @@
 
 #include "hw/char/digic-uart.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 
 enum {
     ST_RX_RDY = (1 << 0),
diff --git a/hw/char/escc.c b/hw/char/escc.c
index 7d16ee8688..52e7978287 100644
--- a/hw/char/escc.c
+++ b/hw/char/escc.c
@@ -25,6 +25,7 @@
 #include "qemu/osdep.h"
 #include "hw/irq.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "hw/sysbus.h"
 #include "migration/vmstate.h"
 #include "qemu/module.h"
diff --git a/hw/char/etraxfs_ser.c b/hw/char/etraxfs_ser.c
index d9fba2ae6c..6bee3ee18e 100644
--- a/hw/char/etraxfs_ser.c
+++ b/hw/char/etraxfs_ser.c
@@ -25,6 +25,7 @@
 #include "qemu/osdep.h"
 #include "hw/irq.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "hw/sysbus.h"
 #include "chardev/char-fe.h"
 #include "qemu/log.h"
diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c
index 96afe3580f..6361df2ad3 100644
--- a/hw/char/exynos4210_uart.c
+++ b/hw/char/exynos4210_uart.c
@@ -32,6 +32,7 @@
 #include "hw/arm/exynos4210.h"
 #include "hw/irq.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 
 #include "trace.h"
 #include "qom/object.h"
diff --git a/hw/char/grlib_apbuart.c b/hw/char/grlib_apbuart.c
index 3f80f6824e..82ff40a530 100644
--- a/hw/char/grlib_apbuart.c
+++ b/hw/char/grlib_apbuart.c
@@ -25,6 +25,7 @@
 #include "qemu/osdep.h"
 #include "hw/irq.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "hw/sparc/grlib.h"
 #include "hw/sysbus.h"
 #include "qemu/module.h"
diff --git a/hw/char/ibex_uart.c b/hw/char/ibex_uart.c
index cc49a35013..89f1182c9b 100644
--- a/hw/char/ibex_uart.c
+++ b/hw/char/ibex_uart.c
@@ -30,6 +30,7 @@
 #include "hw/irq.h"
 #include "hw/qdev-clock.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "migration/vmstate.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
index 731b8fc64c..ee1375e26d 100644
--- a/hw/char/imx_serial.c
+++ b/hw/char/imx_serial.c
@@ -22,6 +22,7 @@
 #include "hw/char/imx_serial.h"
 #include "hw/irq.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "migration/vmstate.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
diff --git a/hw/char/ipoctal232.c b/hw/char/ipoctal232.c
index ad000a39b9..3311e0872c 100644
--- a/hw/char/ipoctal232.c
+++ b/hw/char/ipoctal232.c
@@ -12,6 +12,7 @@
 #include "hw/ipack/ipack.h"
 #include "hw/irq.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "migration/vmstate.h"
 #include "qemu/bitops.h"
 #include "qemu/module.h"
diff --git a/hw/char/lm32_juart.c b/hw/char/lm32_juart.c
index b97aacba91..c5ead05e08 100644
--- a/hw/char/lm32_juart.c
+++ b/hw/char/lm32_juart.c
@@ -26,6 +26,7 @@
 
 #include "hw/char/lm32_juart.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "qom/object.h"
 
 enum {
diff --git a/hw/char/lm32_uart.c b/hw/char/lm32_uart.c
index 0e8b4e46a3..5cb87de548 100644
--- a/hw/char/lm32_uart.c
+++ b/hw/char/lm32_uart.c
@@ -25,6 +25,7 @@
 #include "qemu/osdep.h"
 #include "hw/irq.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "hw/sysbus.h"
 #include "migration/vmstate.h"
 #include "trace.h"
diff --git a/hw/char/mcf_uart.c b/hw/char/mcf_uart.c
index e6814faffb..6fa4ac502c 100644
--- a/hw/char/mcf_uart.c
+++ b/hw/char/mcf_uart.c
@@ -13,6 +13,7 @@
 #include "qapi/error.h"
 #include "hw/m68k/mcf.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "chardev/char-fe.h"
 #include "qom/object.h"
 
diff --git a/hw/char/milkymist-uart.c b/hw/char/milkymist-uart.c
index 1e83dbcafa..09e2f6bd76 100644
--- a/hw/char/milkymist-uart.c
+++ b/hw/char/milkymist-uart.c
@@ -24,6 +24,7 @@
 #include "qemu/osdep.h"
 #include "hw/irq.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "hw/sysbus.h"
 #include "migration/vmstate.h"
 #include "trace.h"
diff --git a/hw/char/nrf51_uart.c b/hw/char/nrf51_uart.c
index d1fef77acd..045ca5fa40 100644
--- a/hw/char/nrf51_uart.c
+++ b/hw/char/nrf51_uart.c
@@ -18,6 +18,7 @@
 #include "hw/char/nrf51_uart.h"
 #include "hw/irq.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "migration/vmstate.h"
 #include "trace.h"
 
diff --git a/hw/char/parallel.c b/hw/char/parallel.c
index 8b418abf71..b45e67bfbb 100644
--- a/hw/char/parallel.c
+++ b/hw/char/parallel.c
@@ -32,6 +32,7 @@
 #include "hw/irq.h"
 #include "hw/isa/isa.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "migration/vmstate.h"
 #include "hw/char/parallel.h"
 #include "sysemu/reset.h"
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
index ede16c781c..ea4a4e5235 100644
--- a/hw/char/pl011.c
+++ b/hw/char/pl011.c
@@ -23,6 +23,7 @@
 #include "hw/irq.h"
 #include "hw/sysbus.h"
 #include "hw/qdev-clock.h"
+#include "hw/qdev-properties-system.h"
 #include "migration/vmstate.h"
 #include "chardev/char-fe.h"
 #include "qemu/log.h"
diff --git a/hw/char/renesas_sci.c b/hw/char/renesas_sci.c
index 5d7c6e6523..1c63467290 100644
--- a/hw/char/renesas_sci.c
+++ b/hw/char/renesas_sci.c
@@ -26,6 +26,7 @@
 #include "hw/irq.h"
 #include "hw/registerfields.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "hw/char/renesas_sci.h"
 #include "migration/vmstate.h"
 
diff --git a/hw/char/sclpconsole-lm.c b/hw/char/sclpconsole-lm.c
index 81f6d0ed4f..b9e9b2d453 100644
--- a/hw/char/sclpconsole-lm.c
+++ b/hw/char/sclpconsole-lm.c
@@ -23,6 +23,7 @@
 #include "migration/vmstate.h"
 #include "hw/s390x/event-facility.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "hw/s390x/ebcdic.h"
 #include "qom/object.h"
 
diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c
index aa72ab40b9..c36b572222 100644
--- a/hw/char/sclpconsole.c
+++ b/hw/char/sclpconsole.c
@@ -20,6 +20,7 @@
 #include "hw/s390x/sclp.h"
 #include "migration/vmstate.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "hw/s390x/event-facility.h"
 #include "chardev/char-fe.h"
 #include "qom/object.h"
diff --git a/hw/char/serial-pci-multi.c b/hw/char/serial-pci-multi.c
index 2cf3e44177..3a9f96c2d1 100644
--- a/hw/char/serial-pci-multi.c
+++ b/hw/char/serial-pci-multi.c
@@ -33,6 +33,7 @@
 #include "hw/irq.h"
 #include "hw/pci/pci.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "migration/vmstate.h"
 
 #define PCI_SERIAL_MAX_PORTS 4
diff --git a/hw/char/serial.c b/hw/char/serial.c
index 97f71879ff..d99daa7695 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -35,6 +35,7 @@
 #include "qemu/error-report.h"
 #include "trace.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 
 #define UART_LCR_DLAB	0x80	/* Divisor latch access bit */
 
diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c
index e726d4d915..79eaa2fa52 100644
--- a/hw/char/spapr_vty.c
+++ b/hw/char/spapr_vty.c
@@ -8,6 +8,7 @@
 #include "hw/ppc/spapr.h"
 #include "hw/ppc/spapr_vio.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "qom/object.h"
 
 #define VTERM_BUFSIZE   16
diff --git a/hw/char/stm32f2xx_usart.c b/hw/char/stm32f2xx_usart.c
index 0d661be6d3..8df0832424 100644
--- a/hw/char/stm32f2xx_usart.c
+++ b/hw/char/stm32f2xx_usart.c
@@ -26,6 +26,7 @@
 #include "hw/char/stm32f2xx_usart.h"
 #include "hw/irq.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
 
diff --git a/hw/char/terminal3270.c b/hw/char/terminal3270.c
index d77981bb6d..a9a46c8ed3 100644
--- a/hw/char/terminal3270.c
+++ b/hw/char/terminal3270.c
@@ -16,6 +16,7 @@
 #include "qemu/module.h"
 #include "chardev/char-fe.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "hw/s390x/3270-ccw.h"
 #include "qom/object.h"
 
diff --git a/hw/char/virtio-console.c b/hw/char/virtio-console.c
index bc752cf90f..6b132caa29 100644
--- a/hw/char/virtio-console.c
+++ b/hw/char/virtio-console.c
@@ -16,6 +16,7 @@
 #include "qemu/module.h"
 #include "trace.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "hw/virtio/virtio-serial.h"
 #include "qapi/error.h"
 #include "qapi/qapi-events-char.h"
diff --git a/hw/char/xilinx_uartlite.c b/hw/char/xilinx_uartlite.c
index 2e773ec4c4..99b9a6f851 100644
--- a/hw/char/xilinx_uartlite.c
+++ b/hw/char/xilinx_uartlite.c
@@ -26,6 +26,7 @@
 #include "qemu/log.h"
 #include "hw/irq.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "hw/sysbus.h"
 #include "qemu/module.h"
 #include "chardev/char-fe.h"
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 35515886a9..a05150bfd0 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -12,6 +12,7 @@
 
 #include "qemu/osdep.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "qapi/error.h"
 #include "qapi/visitor.h"
 #include "qapi/qapi-types-block.h"
diff --git a/hw/hyperv/vmbus.c b/hw/hyperv/vmbus.c
index 896e981f85..984caf898d 100644
--- a/hw/hyperv/vmbus.c
+++ b/hw/hyperv/vmbus.c
@@ -13,6 +13,7 @@
 #include "qapi/error.h"
 #include "migration/vmstate.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "hw/hyperv/hyperv.h"
 #include "hw/hyperv/vmbus.h"
 #include "hw/hyperv/vmbus-bridge.h"
diff --git a/hw/i386/kvm/i8254.c b/hw/i386/kvm/i8254.c
index 40d84734e7..c73254e886 100644
--- a/hw/i386/kvm/i8254.c
+++ b/hw/i386/kvm/i8254.c
@@ -32,6 +32,7 @@
 #include "sysemu/runstate.h"
 #include "hw/timer/i8254.h"
 #include "hw/timer/i8254_internal.h"
+#include "hw/qdev-properties-system.h"
 #include "sysemu/kvm.h"
 #include "qom/object.h"
 
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 27ff1f7f66..73499a6235 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -26,6 +26,7 @@
 #include "qemu/module.h"
 #include "hw/ide/internal.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "hw/block/block.h"
diff --git a/hw/ipmi/ipmi_bmc_extern.c b/hw/ipmi/ipmi_bmc_extern.c
index c3f3306e66..e141a5cd45 100644
--- a/hw/ipmi/ipmi_bmc_extern.c
+++ b/hw/ipmi/ipmi_bmc_extern.c
@@ -35,6 +35,7 @@
 #include "chardev/char-fe.h"
 #include "hw/ipmi/ipmi.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "migration/vmstate.h"
 #include "qom/object.h"
 
diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c
index f78e92d3d5..55fb81fa5a 100644
--- a/hw/ipmi/ipmi_bmc_sim.c
+++ b/hw/ipmi/ipmi_bmc_sim.c
@@ -30,6 +30,7 @@
 #include "qemu/module.h"
 #include "hw/loader.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "migration/vmstate.h"
 
 #define IPMI_NETFN_CHASSIS            0x00
diff --git a/hw/misc/allwinner-sid.c b/hw/misc/allwinner-sid.c
index 196380c33a..6d61f55b1d 100644
--- a/hw/misc/allwinner-sid.c
+++ b/hw/misc/allwinner-sid.c
@@ -26,6 +26,7 @@
 #include "qemu/guest-random.h"
 #include "qapi/error.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "hw/misc/allwinner-sid.h"
 #include "trace.h"
 
diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index e321e5cb69..0505b52c98 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -23,6 +23,7 @@
 #include "qemu/cutils.h"
 #include "hw/pci/pci.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "hw/pci/msi.h"
 #include "hw/pci/msix.h"
 #include "sysemu/kvm.h"
diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c
index 6db62dab7d..488d086a17 100644
--- a/hw/misc/mac_via.c
+++ b/hw/misc/mac_via.c
@@ -28,6 +28,7 @@
 #include "qapi/error.h"
 #include "qemu/cutils.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "sysemu/block-backend.h"
 #include "trace.h"
 #include "qemu/log.h"
diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c
index 60066375ab..4401787a5c 100644
--- a/hw/misc/sifive_u_otp.c
+++ b/hw/misc/sifive_u_otp.c
@@ -21,6 +21,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "hw/sysbus.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c
index 1af1e6fa2f..0fb8db1dee 100644
--- a/hw/net/rocker/rocker.c
+++ b/hw/net/rocker/rocker.c
@@ -18,6 +18,7 @@
 #include "qemu/osdep.h"
 #include "hw/pci/pci.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "migration/vmstate.h"
 #include "hw/pci/msix.h"
 #include "net/net.h"
diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
index 3e93dbbffb..af6f5dbb99 100644
--- a/hw/nvram/eeprom_at24c.c
+++ b/hw/nvram/eeprom_at24c.c
@@ -13,6 +13,7 @@
 #include "qemu/module.h"
 #include "hw/i2c/i2c.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "sysemu/block-backend.h"
 #include "qom/object.h"
 
diff --git a/hw/nvram/spapr_nvram.c b/hw/nvram/spapr_nvram.c
index fc53a42572..9e51bc82ae 100644
--- a/hw/nvram/spapr_nvram.c
+++ b/hw/nvram/spapr_nvram.c
@@ -39,6 +39,7 @@
 #include "hw/ppc/spapr.h"
 #include "hw/ppc/spapr_vio.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "qom/object.h"
 
 struct SpaprNvram {
diff --git a/hw/pci-bridge/gen_pcie_root_port.c b/hw/pci-bridge/gen_pcie_root_port.c
index 8931afc049..ec9907917e 100644
--- a/hw/pci-bridge/gen_pcie_root_port.c
+++ b/hw/pci-bridge/gen_pcie_root_port.c
@@ -16,6 +16,7 @@
 #include "hw/pci/msix.h"
 #include "hw/pci/pcie_port.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "migration/vmstate.h"
 #include "qom/object.h"
 
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 0131d9d02c..ad2fa1eea2 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -30,6 +30,7 @@
 #include "hw/pci/pci_bus.h"
 #include "hw/pci/pci_host.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "migration/qemu-file-types.h"
 #include "migration/vmstate.h"
 #include "monitor/monitor.h"
diff --git a/hw/ppc/pnv_pnor.c b/hw/ppc/pnv_pnor.c
index c365ee58b8..ef8dff03e0 100644
--- a/hw/ppc/pnv_pnor.c
+++ b/hw/ppc/pnv_pnor.c
@@ -17,6 +17,7 @@
 #include "hw/loader.h"
 #include "hw/ppc/pnv_pnor.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 
 static uint64_t pnv_pnor_read(void *opaque, hwaddr addr, unsigned size)
 {
diff --git a/hw/rdma/vmw/pvrdma_main.c b/hw/rdma/vmw/pvrdma_main.c
index 77b1235a3f..8593570332 100644
--- a/hw/rdma/vmw/pvrdma_main.c
+++ b/hw/rdma/vmw/pvrdma_main.c
@@ -21,6 +21,7 @@
 #include "hw/pci/msi.h"
 #include "hw/pci/msix.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "cpu.h"
 #include "trace.h"
 #include "monitor/monitor.h"
diff --git a/hw/rtc/mc146818rtc.c b/hw/rtc/mc146818rtc.c
index 7a38540cb9..5d0fcacd0c 100644
--- a/hw/rtc/mc146818rtc.c
+++ b/hw/rtc/mc146818rtc.c
@@ -30,6 +30,7 @@
 #include "hw/acpi/aml-build.h"
 #include "hw/irq.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "qemu/timer.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/replay.h"
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index e859534eaf..f9a591cd17 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -34,6 +34,7 @@
 #include "sysemu/blockdev.h"
 #include "hw/block/block.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "sysemu/dma.h"
 #include "sysemu/sysemu.h"
 #include "qemu/cutils.h"
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
index 2cb23ca891..9740f7e36a 100644
--- a/hw/scsi/scsi-generic.c
+++ b/hw/scsi/scsi-generic.c
@@ -19,6 +19,7 @@
 #include "hw/scsi/scsi.h"
 #include "migration/qemu-file-types.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "hw/scsi/emulation.h"
 #include "sysemu/block-backend.h"
 #include "trace.h"
diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
index 7c0631656c..4666019442 100644
--- a/hw/scsi/vhost-user-scsi.c
+++ b/hw/scsi/vhost-user-scsi.c
@@ -21,6 +21,7 @@
 #include "hw/fw-path-provider.h"
 #include "hw/qdev-core.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost-backend.h"
 #include "hw/virtio/vhost-user-scsi.h"
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 3091382614..fa07398c8c 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -42,6 +42,7 @@
 #include "qapi/error.h"
 #include "qemu/bitmap.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "qemu/error-report.h"
 #include "qemu/timer.h"
 #include "qemu/log.h"
diff --git a/hw/usb/ccid-card-passthru.c b/hw/usb/ccid-card-passthru.c
index e8e9d37e88..c27c602697 100644
--- a/hw/usb/ccid-card-passthru.c
+++ b/hw/usb/ccid-card-passthru.c
@@ -14,6 +14,7 @@
 #include <libcacard.h>
 #include "chardev/char-fe.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "migration/vmstate.h"
 #include "qemu/error-report.h"
 #include "qemu/module.h"
diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c
index b1622b7c7f..504e1ef423 100644
--- a/hw/usb/dev-serial.c
+++ b/hw/usb/dev-serial.c
@@ -14,6 +14,7 @@
 #include "qemu/error-report.h"
 #include "qemu/module.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "hw/usb.h"
 #include "migration/vmstate.h"
 #include "desc.h"
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 3238de6bb8..0b7e0e15f4 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -42,6 +42,7 @@
 #include <usbredirfilter.h>
 
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "hw/usb.h"
 #include "migration/qemu-file-types.h"
 #include "migration/vmstate.h"
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 58c0ce8971..edfaed8c9a 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -27,6 +27,7 @@
 #include "hw/pci/msix.h"
 #include "hw/pci/pci_bridge.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "migration/vmstate.h"
 #include "qemu/error-report.h"
 #include "qemu/main-loop.h"
diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
index 1bc5d03a00..ed036ad9c1 100644
--- a/hw/virtio/vhost-user-fs.c
+++ b/hw/virtio/vhost-user-fs.c
@@ -16,6 +16,7 @@
 #include "standard-headers/linux/virtio_fs.h"
 #include "qapi/error.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "hw/virtio/virtio-bus.h"
 #include "hw/virtio/virtio-access.h"
 #include "qemu/error-report.h"
diff --git a/hw/virtio/vhost-user-vsock.c b/hw/virtio/vhost-user-vsock.c
index 3534a39d62..a6f08c26b9 100644
--- a/hw/virtio/vhost-user-vsock.c
+++ b/hw/virtio/vhost-user-vsock.c
@@ -13,6 +13,7 @@
 #include "qapi/error.h"
 #include "qemu/error-report.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "hw/virtio/vhost-user-vsock.h"
 
 static const int user_feature_bits[] = {
diff --git a/hw/virtio/virtio-iommu-pci.c b/hw/virtio/virtio-iommu-pci.c
index 378f63b210..770c286be7 100644
--- a/hw/virtio/virtio-iommu-pci.c
+++ b/hw/virtio/virtio-iommu-pci.c
@@ -14,6 +14,7 @@
 #include "virtio-pci.h"
 #include "hw/virtio/virtio-iommu.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "qapi/error.h"
 #include "hw/boards.h"
 #include "qom/object.h"
diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c
index 6d359ee486..3cbd08b10e 100644
--- a/hw/xen/xen_pt.c
+++ b/hw/xen/xen_pt.c
@@ -58,6 +58,7 @@
 
 #include "hw/pci/pci.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "hw/xen/xen.h"
 #include "hw/i386/pc.h"
 #include "hw/xen/xen-legacy-backend.h"
diff --git a/migration/migration.c b/migration/migration.c
index 3263aa55a9..68c8c715fa 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -52,6 +52,7 @@
 #include "migration/colo.h"
 #include "hw/boards.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
 #include "monitor/monitor.h"
 #include "net/announce.h"
 #include "qemu/queue.h"
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 15/44] qdev: Reuse DEFINE_PROP in all DEFINE_PROP_* macros
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (13 preceding siblings ...)
  2020-11-04 15:59 ` [PATCH v2 14/44] qdev: Move softmmu properties to qdev-properties-system.h Eduardo Habkost
@ 2020-11-04 15:59 ` Eduardo Habkost
  2020-11-04 15:59 ` [PATCH v2 16/44] sparc: Use DEFINE_PROP for nwindows property Eduardo Habkost
                   ` (30 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 15:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

Instead of duplicating the code that sets name, info, offset,
and does type checking, make DEFINE_PROP accept a variable number
of arguments and reuse it in all DEFINE_PROP_* macros.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Changes v1 -> v2:
* Redone after UUID property was moved
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 include/hw/qdev-properties-system.h |  19 ++---
 include/hw/qdev-properties.h        | 114 ++++++++++------------------
 2 files changed, 46 insertions(+), 87 deletions(-)

diff --git a/include/hw/qdev-properties-system.h b/include/hw/qdev-properties-system.h
index 29529dc999..0ac327ae60 100644
--- a/include/hw/qdev-properties-system.h
+++ b/include/hw/qdev-properties-system.h
@@ -63,22 +63,15 @@ extern const PropertyInfo qdev_prop_pcie_link_width;
     DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pcie_link_width, \
                         PCIExpLinkWidth)
 
-#define DEFINE_PROP_UUID(_name, _state, _field) {                  \
-        .name      = (_name),                                      \
-        .info      = &qdev_prop_uuid,                              \
-        .offset    = offsetof(_state, _field)                      \
-            + type_check(QemuUUID, typeof_field(_state, _field)),  \
-        .set_default = true,                                       \
-        }
+#define DEFINE_PROP_UUID(_name, _state, _field) \
+    DEFINE_PROP(_name, _state, _field, qdev_prop_uuid, QemuUUID, \
+                .set_default = true)
+
 #define DEFINE_PROP_AUDIODEV(_n, _s, _f) \
     DEFINE_PROP(_n, _s, _f, qdev_prop_audiodev, QEMUSoundCard)
 
-#define DEFINE_PROP_UUID_NODEFAULT(_name, _state, _field) {        \
-        .name      = (_name),                                      \
-        .info      = &qdev_prop_uuid,                              \
-        .offset    = offsetof(_state, _field)                      \
-            + type_check(QemuUUID, typeof_field(_state, _field)),  \
-        }
+#define DEFINE_PROP_UUID_NODEFAULT(_name, _state, _field) \
+    DEFINE_PROP(_name, _state, _field, qdev_prop_uuid, QemuUUID)
 
 
 #endif
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index d35d4aae84..1b58e4f922 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -61,73 +61,46 @@ extern const PropertyInfo qdev_prop_size32;
 extern const PropertyInfo qdev_prop_arraylen;
 extern const PropertyInfo qdev_prop_link;
 
-#define DEFINE_PROP(_name, _state, _field, _prop, _type) { \
+#define DEFINE_PROP(_name, _state, _field, _prop, _type, ...) {  \
         .name      = (_name),                                    \
         .info      = &(_prop),                                   \
         .offset    = offsetof(_state, _field)                    \
             + type_check(_type, typeof_field(_state, _field)),   \
+        __VA_ARGS__                                              \
         }
 
-#define DEFINE_PROP_SIGNED(_name, _state, _field, _defval, _prop, _type) { \
-        .name      = (_name),                                           \
-        .info      = &(_prop),                                          \
-        .offset    = offsetof(_state, _field)                           \
-            + type_check(_type,typeof_field(_state, _field)),           \
-        .set_default = true,                                            \
-        .defval.i  = (_type)_defval,                                    \
-        }
+#define DEFINE_PROP_SIGNED(_name, _state, _field, _defval, _prop, _type) \
+    DEFINE_PROP(_name, _state, _field, _prop, _type,                     \
+                .set_default = true,                                     \
+                .defval.i    = (_type)_defval)
 
-#define DEFINE_PROP_SIGNED_NODEFAULT(_name, _state, _field, _prop, _type) { \
-        .name      = (_name),                                           \
-        .info      = &(_prop),                                          \
-        .offset    = offsetof(_state, _field)                           \
-            + type_check(_type, typeof_field(_state, _field)),          \
-        }
+#define DEFINE_PROP_SIGNED_NODEFAULT(_name, _state, _field, _prop, _type) \
+    DEFINE_PROP(_name, _state, _field, _prop, _type)
 
-#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) {  \
-        .name      = (_name),                                    \
-        .info      = &(qdev_prop_bit),                           \
-        .bitnr    = (_bit),                                      \
-        .offset    = offsetof(_state, _field)                    \
-            + type_check(uint32_t,typeof_field(_state, _field)), \
-        .set_default = true,                                     \
-        .defval.u  = (bool)_defval,                              \
-        }
+#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval)   \
+    DEFINE_PROP(_name, _state, _field, qdev_prop_bit, uint32_t, \
+                .bitnr       = (_bit),                          \
+                .set_default = true,                            \
+                .defval.u    = (bool)_defval)
 
-#define DEFINE_PROP_UNSIGNED(_name, _state, _field, _defval, _prop, _type) { \
-        .name      = (_name),                                           \
-        .info      = &(_prop),                                          \
-        .offset    = offsetof(_state, _field)                           \
-            + type_check(_type, typeof_field(_state, _field)),          \
-        .set_default = true,                                            \
-        .defval.u  = (_type)_defval,                                    \
-        }
+#define DEFINE_PROP_UNSIGNED(_name, _state, _field, _defval, _prop, _type) \
+    DEFINE_PROP(_name, _state, _field, _prop, _type,                       \
+                .set_default = true,                                       \
+                .defval.u  = (_type)_defval)
 
-#define DEFINE_PROP_UNSIGNED_NODEFAULT(_name, _state, _field, _prop, _type) { \
-        .name      = (_name),                                           \
-        .info      = &(_prop),                                          \
-        .offset    = offsetof(_state, _field)                           \
-            + type_check(_type, typeof_field(_state, _field)),          \
-        }
+#define DEFINE_PROP_UNSIGNED_NODEFAULT(_name, _state, _field, _prop, _type) \
+    DEFINE_PROP(_name, _state, _field, _prop, _type)
 
-#define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval) {       \
-        .name      = (_name),                                           \
-        .info      = &(qdev_prop_bit64),                                \
-        .bitnr    = (_bit),                                             \
-        .offset    = offsetof(_state, _field)                           \
-            + type_check(uint64_t, typeof_field(_state, _field)),       \
-        .set_default = true,                                            \
-        .defval.u  = (bool)_defval,                                     \
-        }
+#define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval)   \
+    DEFINE_PROP(_name, _state, _field, qdev_prop_bit64, uint64_t, \
+                .bitnr    = (_bit),                               \
+                .set_default = true,                              \
+                .defval.u  = (bool)_defval)
 
-#define DEFINE_PROP_BOOL(_name, _state, _field, _defval) {       \
-        .name      = (_name),                                    \
-        .info      = &(qdev_prop_bool),                          \
-        .offset    = offsetof(_state, _field)                    \
-            + type_check(bool, typeof_field(_state, _field)),    \
-        .set_default = true,                                     \
-        .defval.u    = (bool)_defval,                            \
-        }
+#define DEFINE_PROP_BOOL(_name, _state, _field, _defval)     \
+    DEFINE_PROP(_name, _state, _field, qdev_prop_bool, bool, \
+                .set_default = true,                         \
+                .defval.u    = (bool)_defval)
 
 #define PROP_ARRAY_LEN_PREFIX "len-"
 
@@ -155,26 +128,19 @@ extern const PropertyInfo qdev_prop_link;
  * It is the responsibility of the device deinit code to free the
  * @_arrayfield memory.
  */
-#define DEFINE_PROP_ARRAY(_name, _state, _field,                        \
-                          _arrayfield, _arrayprop, _arraytype) {        \
-        .name = (PROP_ARRAY_LEN_PREFIX _name),                          \
-        .info = &(qdev_prop_arraylen),                                  \
-        .set_default = true,                                            \
-        .defval.u = 0,                                                  \
-        .offset = offsetof(_state, _field)                              \
-            + type_check(uint32_t, typeof_field(_state, _field)),       \
-        .arrayinfo = &(_arrayprop),                                     \
-        .arrayfieldsize = sizeof(_arraytype),                           \
-        .arrayoffset = offsetof(_state, _arrayfield),                   \
-        }
+#define DEFINE_PROP_ARRAY(_name, _state, _field,               \
+                          _arrayfield, _arrayprop, _arraytype) \
+    DEFINE_PROP((PROP_ARRAY_LEN_PREFIX _name),                 \
+                _state, _field, qdev_prop_arraylen, uint32_t,  \
+                .set_default = true,                           \
+                .defval.u = 0,                                 \
+                .arrayinfo = &(_arrayprop),                    \
+                .arrayfieldsize = sizeof(_arraytype),          \
+                .arrayoffset = offsetof(_state, _arrayfield))
 
-#define DEFINE_PROP_LINK(_name, _state, _field, _type, _ptr_type) {     \
-        .name = (_name),                                                \
-        .info = &(qdev_prop_link),                                      \
-        .offset = offsetof(_state, _field)                              \
-            + type_check(_ptr_type, typeof_field(_state, _field)),      \
-        .link_type  = _type,                                            \
-        }
+#define DEFINE_PROP_LINK(_name, _state, _field, _type, _ptr_type)     \
+    DEFINE_PROP(_name, _state, _field, qdev_prop_link, _ptr_type,     \
+                .link_type  = _type)
 
 #define DEFINE_PROP_UINT8(_n, _s, _f, _d)                       \
     DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, qdev_prop_uint8, uint8_t)
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 16/44] sparc: Use DEFINE_PROP for nwindows property
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (14 preceding siblings ...)
  2020-11-04 15:59 ` [PATCH v2 15/44] qdev: Reuse DEFINE_PROP in all DEFINE_PROP_* macros Eduardo Habkost
@ 2020-11-04 15:59 ` Eduardo Habkost
  2020-11-04 15:59 ` [PATCH v2 17/44] qdev: Get just property name at error_set_from_qdev_prop_error() Eduardo Habkost
                   ` (29 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 15:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Mark Cave-Ayland,
	Markus Armbruster, Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Artyom Tarasenko, Stefan Berger

Use the DEFINE_PROP macro (which will set extra fields in the
struct) instead of initializing a Property struct manually.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
This is a new patch added in v2 of the series
---
Cc: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Cc: Artyom Tarasenko <atar4qemu@gmail.com>
Cc: qemu-devel@nongnu.org
---
 target/sparc/cpu.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 8ecb20e55f..f5cff4103b 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -848,7 +848,8 @@ static Property sparc_cpu_properties[] = {
                          qdev_prop_uint64, target_ulong),
     DEFINE_PROP_UINT32("fpu-version", SPARCCPU, env.def.fpu_version, 0),
     DEFINE_PROP_UINT32("mmu-version", SPARCCPU, env.def.mmu_version, 0),
-    { .name  = "nwindows", .info  = &qdev_prop_nwindows },
+    DEFINE_PROP("nwindows",     SPARCCPU, env.def.nwindows,
+                qdev_prop_nwindows, uint32_t),
     DEFINE_PROP_END_OF_LIST()
 };
 
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 17/44] qdev: Get just property name at error_set_from_qdev_prop_error()
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (15 preceding siblings ...)
  2020-11-04 15:59 ` [PATCH v2 16/44] sparc: Use DEFINE_PROP for nwindows property Eduardo Habkost
@ 2020-11-04 15:59 ` Eduardo Habkost
  2020-11-04 15:59 ` [PATCH v2 18/44] qdev: Avoid using prop->name unnecessarily Eduardo Habkost
                   ` (28 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 15:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Thomas Huth, Daniel P. Berrange, Christian Borntraeger,
	John Snow, Cornelia Huck, David Hildenbrand, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Halil Pasic, Marc-André Lureau, qemu-s390x, Igor Mammedov,
	Paolo Bonzini, Richard Henderson, Stefan Berger

Replace `Property *prop` parameter with `char *name`, to reduce
dependency of getter and setter functions on the Property struct
(which will be changed in following patches).

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
This is a new patch added in series v2
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: Cornelia Huck <cohuck@redhat.com>
Cc: Halil Pasic <pasic@linux.ibm.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Thomas Huth <thuth@redhat.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: David Hildenbrand <david@redhat.com>
Cc: qemu-devel@nongnu.org
Cc: qemu-s390x@nongnu.org
---
 include/hw/qdev-properties.h     |  2 +-
 hw/core/qdev-properties-system.c | 12 ++++++------
 hw/core/qdev-properties.c        |  8 ++++----
 hw/s390x/css.c                   |  2 +-
 4 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 1b58e4f922..476737b9da 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -201,7 +201,7 @@ const GlobalProperty *qdev_find_global_prop(Object *obj,
 int qdev_prop_check_globals(void);
 void qdev_prop_set_globals(DeviceState *dev);
 void error_set_from_qdev_prop_error(Error **errp, int ret, Object *obj,
-                                    Property *prop, const char *value);
+                                    const char *name, const char *value);
 
 /**
  * qdev_property_add_static:
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index a05150bfd0..808e7136a0 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -354,7 +354,7 @@ static void set_mac(Object *obj, Visitor *v, const char *name, void *opaque,
     return;
 
 inval:
-    error_set_from_qdev_prop_error(errp, EINVAL, obj, prop, str);
+    error_set_from_qdev_prop_error(errp, EINVAL, obj, name, str);
     g_free(str);
 }
 
@@ -442,7 +442,7 @@ static void set_netdev(Object *obj, Visitor *v, const char *name,
     peers_ptr->queues = queues;
 
 out:
-    error_set_from_qdev_prop_error(errp, err, obj, prop, str);
+    error_set_from_qdev_prop_error(errp, err, obj, name, str);
     g_free(str);
 }
 
@@ -494,7 +494,7 @@ static void set_audiodev(Object *obj, Visitor *v, const char* name,
     card->state = state;
 
 out:
-    error_set_from_qdev_prop_error(errp, err, obj, prop, str);
+    error_set_from_qdev_prop_error(errp, err, obj, name, str);
     g_free(str);
 }
 
@@ -792,7 +792,7 @@ static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
     return;
 
 invalid:
-    error_set_from_qdev_prop_error(errp, EINVAL, obj, prop, str);
+    error_set_from_qdev_prop_error(errp, EINVAL, obj, name, str);
     g_free(str);
 }
 
@@ -915,7 +915,7 @@ static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
     return;
 
 inval:
-    error_set_from_qdev_prop_error(errp, EINVAL, obj, prop, str);
+    error_set_from_qdev_prop_error(errp, EINVAL, obj, name, str);
     g_free(str);
 }
 
@@ -1145,7 +1145,7 @@ static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
     if (!strcmp(str, UUID_VALUE_AUTO)) {
         qemu_uuid_generate(uuid);
     } else if (qemu_uuid_parse(str, uuid) < 0) {
-        error_set_from_qdev_prop_error(errp, EINVAL, obj, prop, str);
+        error_set_from_qdev_prop_error(errp, EINVAL, obj, name, str);
     }
     g_free(str);
 }
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index d7796e8cc3..a7bbc1235a 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -679,21 +679,21 @@ static Property *qdev_prop_find(DeviceState *dev, const char *name)
 }
 
 void error_set_from_qdev_prop_error(Error **errp, int ret, Object *obj,
-                                    Property *prop, const char *value)
+                                    const char *name, const char *value)
 {
     switch (ret) {
     case -EEXIST:
         error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use",
-                  object_get_typename(obj), prop->name, value);
+                  object_get_typename(obj), name, value);
         break;
     default:
     case -EINVAL:
         error_setg(errp, QERR_PROPERTY_VALUE_BAD,
-                   object_get_typename(obj), prop->name, value);
+                   object_get_typename(obj), name, value);
         break;
     case -ENOENT:
         error_setg(errp, "Property '%s.%s' can't find value '%s'",
-                  object_get_typename(obj), prop->name, value);
+                  object_get_typename(obj), name, value);
         break;
     case 0:
         break;
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 38fd46b9a9..7a44320d12 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -2390,7 +2390,7 @@ static void set_css_devid(Object *obj, Visitor *v, const char *name,
 
     num = sscanf(str, "%2x.%1x%n.%4x%n", &cssid, &ssid, &n1, &devid, &n2);
     if (num != 3 || (n2 - n1) != 5 || strlen(str) != n2) {
-        error_set_from_qdev_prop_error(errp, EINVAL, obj, prop, str);
+        error_set_from_qdev_prop_error(errp, EINVAL, obj, name, str);
         goto out;
     }
     if ((cssid > MAX_CSSID) || (ssid > MAX_SSID)) {
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 18/44] qdev: Avoid using prop->name unnecessarily
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (16 preceding siblings ...)
  2020-11-04 15:59 ` [PATCH v2 17/44] qdev: Get just property name at error_set_from_qdev_prop_error() Eduardo Habkost
@ 2020-11-04 15:59 ` Eduardo Habkost
  2020-11-04 17:25   ` Stefan Berger
  2020-11-04 15:59 ` [PATCH v2 19/44] qdev: Add name parameter to qdev_class_add_property() Eduardo Habkost
                   ` (27 subsequent siblings)
  45 siblings, 1 reply; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 15:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, Stefan Berger, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

We already get the property name as argument to the property
getter and setters, we don't need to use prop->name.  This will
make it easier to remove the Property.name field in the future.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
This is a new patch added in series v2
---
Cc: Stefan Berger <stefanb@linux.vnet.ibm.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 backends/tpm/tpm_util.c          |  2 +-
 hw/core/qdev-properties-system.c | 14 +++++++-------
 hw/core/qdev-properties.c        |  4 ++--
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/backends/tpm/tpm_util.c b/backends/tpm/tpm_util.c
index e91c21dd4a..dba2f6b04a 100644
--- a/backends/tpm/tpm_util.c
+++ b/backends/tpm/tpm_util.c
@@ -63,7 +63,7 @@ static void set_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
     s = qemu_find_tpm_be(str);
     if (s == NULL) {
         error_setg(errp, "Property '%s.%s' can't find value '%s'",
-                   object_get_typename(obj), prop->name, str);
+                   object_get_typename(obj), name, str);
     } else if (tpm_backend_init(s, TPM_IF(obj), errp) == 0) {
         *be = s; /* weak reference, avoid cyclic ref */
     }
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 808e7136a0..202abd0e4b 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -141,7 +141,7 @@ static void set_drive_helper(Object *obj, Visitor *v, const char *name,
     }
     if (!blk) {
         error_setg(errp, "Property '%s.%s' can't find value '%s'",
-                   object_get_typename(OBJECT(dev)), prop->name, str);
+                   object_get_typename(OBJECT(dev)), name, str);
         goto fail;
     }
     if (blk_attach_dev(blk, dev) < 0) {
@@ -262,10 +262,10 @@ static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
     s = qemu_chr_find(str);
     if (s == NULL) {
         error_setg(errp, "Property '%s.%s' can't find value '%s'",
-                   object_get_typename(obj), prop->name, str);
+                   object_get_typename(obj), name, str);
     } else if (!qemu_chr_fe_init(be, s, errp)) {
         error_prepend(errp, "Property '%s.%s' can't take value '%s': ",
-                      object_get_typename(obj), prop->name, str);
+                      object_get_typename(obj), name, str);
     }
     g_free(str);
 }
@@ -965,7 +965,7 @@ static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
         abort();
     }
 
-    visit_type_enum(v, prop->name, &speed, prop->info->enum_table, errp);
+    visit_type_enum(v, name, &speed, prop->info->enum_table, errp);
 }
 
 static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
@@ -981,7 +981,7 @@ static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
         return;
     }
 
-    if (!visit_type_enum(v, prop->name, &speed, prop->info->enum_table,
+    if (!visit_type_enum(v, name, &speed, prop->info->enum_table,
                          errp)) {
         return;
     }
@@ -1050,7 +1050,7 @@ static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
         abort();
     }
 
-    visit_type_enum(v, prop->name, &width, prop->info->enum_table, errp);
+    visit_type_enum(v, name, &width, prop->info->enum_table, errp);
 }
 
 static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
@@ -1066,7 +1066,7 @@ static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
         return;
     }
 
-    if (!visit_type_enum(v, prop->name, &width, prop->info->enum_table,
+    if (!visit_type_enum(v, name, &width, prop->info->enum_table,
                          errp)) {
         return;
     }
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index a7bbc1235a..69181ce31d 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -50,7 +50,7 @@ void qdev_propinfo_get_enum(Object *obj, Visitor *v, const char *name,
     Property *prop = opaque;
     int *ptr = qdev_get_prop_ptr(obj, prop);
 
-    visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp);
+    visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
 }
 
 void qdev_propinfo_set_enum(Object *obj, Visitor *v, const char *name,
@@ -65,7 +65,7 @@ void qdev_propinfo_set_enum(Object *obj, Visitor *v, const char *name,
         return;
     }
 
-    visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp);
+    visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
 }
 
 void qdev_propinfo_set_default_value_enum(ObjectProperty *op,
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 19/44] qdev: Add name parameter to qdev_class_add_property()
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (17 preceding siblings ...)
  2020-11-04 15:59 ` [PATCH v2 18/44] qdev: Avoid using prop->name unnecessarily Eduardo Habkost
@ 2020-11-04 15:59 ` Eduardo Habkost
  2020-11-04 15:59 ` [PATCH v2 20/44] qdev: Add name argument to PropertyInfo.create method Eduardo Habkost
                   ` (26 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 15:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

This will make it easier to remove Property.name in the future.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
This is a new patch added in series v2
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 hw/core/qdev-properties.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 69181ce31d..dff98646e6 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -887,7 +887,8 @@ void qdev_property_add_static(DeviceState *dev, Property *prop)
     }
 }
 
-static void qdev_class_add_property(DeviceClass *klass, Property *prop)
+static void qdev_class_add_property(DeviceClass *klass, const char *name,
+                                    Property *prop)
 {
     ObjectClass *oc = OBJECT_CLASS(klass);
 
@@ -897,7 +898,7 @@ static void qdev_class_add_property(DeviceClass *klass, Property *prop)
         ObjectProperty *op;
 
         op = object_class_property_add(oc,
-                                       prop->name, prop->info->name,
+                                       name, prop->info->name,
                                        prop->info->get, prop->info->set,
                                        prop->info->release,
                                        prop);
@@ -905,7 +906,7 @@ static void qdev_class_add_property(DeviceClass *klass, Property *prop)
             prop->info->set_default_value(op, prop);
         }
     }
-    object_class_property_set_description(oc, prop->name,
+    object_class_property_set_description(oc, name,
                                           prop->info->description);
 }
 
@@ -962,7 +963,7 @@ void device_class_set_props(DeviceClass *dc, Property *props)
     dc->props_ = props;
     for (prop = props; prop && prop->name; prop++) {
         qdev_class_add_legacy_property(dc, prop);
-        qdev_class_add_property(dc, prop);
+        qdev_class_add_property(dc, prop->name, prop);
     }
 }
 
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 20/44] qdev: Add name argument to PropertyInfo.create method
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (18 preceding siblings ...)
  2020-11-04 15:59 ` [PATCH v2 19/44] qdev: Add name parameter to qdev_class_add_property() Eduardo Habkost
@ 2020-11-04 15:59 ` Eduardo Habkost
  2020-11-04 15:59 ` [PATCH v2 21/44] qdev: Wrap getters and setters in separate helpers Eduardo Habkost
                   ` (25 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 15:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

This will make it easier to remove the Property.name field in the
future.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
This is a new patch added in series v2
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 include/hw/qdev-properties.h | 2 +-
 hw/core/qdev-properties.c    | 7 ++++---
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 476737b9da..ab9c538ba4 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -34,7 +34,7 @@ struct PropertyInfo {
     const QEnumLookup *enum_table;
     int (*print)(Object *obj, Property *prop, char *dest, size_t len);
     void (*set_default_value)(ObjectProperty *op, const Property *prop);
-    void (*create)(ObjectClass *oc, Property *prop);
+    void (*create)(ObjectClass *oc, const char *name, Property *prop);
     ObjectPropertyAccessor *get;
     ObjectPropertyAccessor *set;
     ObjectPropertyRelease *release;
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index dff98646e6..3939ace4c1 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -851,9 +851,10 @@ const PropertyInfo qdev_prop_size = {
 
 /* --- object link property --- */
 
-static void create_link_property(ObjectClass *oc, Property *prop)
+static void create_link_property(ObjectClass *oc, const char *name,
+                                 Property *prop)
 {
-    object_class_property_add_link(oc, prop->name, prop->link_type,
+    object_class_property_add_link(oc, name, prop->link_type,
                                    prop->offset,
                                    qdev_prop_allow_set_link_before_realize,
                                    OBJ_PROP_LINK_STRONG);
@@ -893,7 +894,7 @@ static void qdev_class_add_property(DeviceClass *klass, const char *name,
     ObjectClass *oc = OBJECT_CLASS(klass);
 
     if (prop->info->create) {
-        prop->info->create(oc, prop);
+        prop->info->create(oc, name, prop);
     } else {
         ObjectProperty *op;
 
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 21/44] qdev: Wrap getters and setters in separate helpers
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (19 preceding siblings ...)
  2020-11-04 15:59 ` [PATCH v2 20/44] qdev: Add name argument to PropertyInfo.create method Eduardo Habkost
@ 2020-11-04 15:59 ` Eduardo Habkost
  2020-11-04 15:59   ` Eduardo Habkost
                   ` (24 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 15:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

We'll add extra code to the qdev property getters and setters, so
add wrapper functions where additional actions can be performed.

The new functions have a "field_prop_" prefix instead of "qdev_"
because the code will eventually be moved outside
qdev-properties.c, to common QOM code.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Changes v1 -> v2:
* Redone after changes in previous patches in the series
* Renamed functions from static_prop_* to field_prop_*
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 hw/core/qdev-properties.c | 44 +++++++++++++++++++++++++++++++++++----
 1 file changed, 40 insertions(+), 4 deletions(-)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 3939ace4c1..0e5ff81da8 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -44,6 +44,40 @@ void *qdev_get_prop_ptr(Object *obj, Property *prop)
     return ptr;
 }
 
+static void field_prop_get(Object *obj, Visitor *v, const char *name,
+                           void *opaque, Error **errp)
+{
+    Property *prop = opaque;
+    return prop->info->get(obj, v, name, opaque, errp);
+}
+
+/**
+ * field_prop_getter: Return getter function to be used for property
+ *
+ * Return value can be NULL if @info has no getter function.
+ */
+static ObjectPropertyAccessor *field_prop_getter(const PropertyInfo *info)
+{
+    return info->get ? field_prop_get : NULL;
+}
+
+static void field_prop_set(Object *obj, Visitor *v, const char *name,
+                           void *opaque, Error **errp)
+{
+    Property *prop = opaque;
+    return prop->info->set(obj, v, name, opaque, errp);
+}
+
+/**
+ * field_prop_setter: Return setter function to be used for property
+ *
+ * Return value can be NULL if @info has not setter function.
+ */
+static ObjectPropertyAccessor *field_prop_setter(const PropertyInfo *info)
+{
+    return info->set ? field_prop_set : NULL;
+}
+
 void qdev_propinfo_get_enum(Object *obj, Visitor *v, const char *name,
                             void *opaque, Error **errp)
 {
@@ -630,8 +664,8 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
         assert(qdev_get_prop_ptr(obj, &arrayprop->prop) == eltptr);
         object_property_add(obj, propname,
                             arrayprop->prop.info->name,
-                            arrayprop->prop.info->get,
-                            arrayprop->prop.info->set,
+                            field_prop_getter(arrayprop->prop.info),
+                            field_prop_setter(arrayprop->prop.info),
                             array_element_release,
                             arrayprop);
     }
@@ -873,7 +907,8 @@ void qdev_property_add_static(DeviceState *dev, Property *prop)
     assert(!prop->info->create);
 
     op = object_property_add(obj, prop->name, prop->info->name,
-                             prop->info->get, prop->info->set,
+                             field_prop_getter(prop->info),
+                             field_prop_setter(prop->info),
                              prop->info->release,
                              prop);
 
@@ -900,7 +935,8 @@ static void qdev_class_add_property(DeviceClass *klass, const char *name,
 
         op = object_class_property_add(oc,
                                        name, prop->info->name,
-                                       prop->info->get, prop->info->set,
+                                       field_prop_getter(prop->info),
+                                       field_prop_setter(prop->info),
                                        prop->info->release,
                                        prop);
         if (prop->set_default) {
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 22/44] qdev: Move dev->realized check to qdev_property_set()
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
@ 2020-11-04 15:59   ` Eduardo Habkost
  2020-11-04 15:59 ` [PATCH v2 02/44] cpu: Move cpu_common_props to hw/core/cpu.c Eduardo Habkost
                     ` (44 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 15:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Matthew Rosato, Paul Durrant, Mark Cave-Ayland,
	Stefano Stabellini, xen-devel, qemu-block, Stefan Berger,
	David Hildenbrand, Markus Armbruster, Halil Pasic,
	Christian Borntraeger, Anthony Perard, Marc-André Lureau,
	Philippe Mathieu-Daudé,
	Artyom Tarasenko, Thomas Huth, Alex Williamson, Paolo Bonzini,
	John Snow, Richard Henderson, Kevin Wolf, Daniel P. Berrange,
	Cornelia Huck, qemu-s390x, Max Reitz, Igor Mammedov,
	Stefan Berger

Every single qdev property setter function manually checks
dev->realized.  We can just check dev->realized inside
qdev_property_set() instead.

The check is being added as a separate function
(qdev_prop_allow_set()) because it will become a callback later.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Changes v1 -> v2:
* Removed unused variable at xen_block_set_vdev()
* Redone patch after changes in the previous patches in the
  series
---
Cc: Stefan Berger <stefanb@linux.vnet.ibm.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Paul Durrant <paul@xen.org>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: Cornelia Huck <cohuck@redhat.com>
Cc: Halil Pasic <pasic@linux.ibm.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: David Hildenbrand <david@redhat.com>
Cc: Thomas Huth <thuth@redhat.com>
Cc: Matthew Rosato <mjrosato@linux.ibm.com>
Cc: Alex Williamson <alex.williamson@redhat.com>
Cc: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Cc: Artyom Tarasenko <atar4qemu@gmail.com>
Cc: qemu-devel@nongnu.org
Cc: xen-devel@lists.xenproject.org
Cc: qemu-block@nongnu.org
Cc: qemu-s390x@nongnu.org
---
 backends/tpm/tpm_util.c          |   6 --
 hw/block/xen-block.c             |   6 --
 hw/core/qdev-properties-system.c |  70 ----------------------
 hw/core/qdev-properties.c        | 100 ++++++-------------------------
 hw/s390x/css.c                   |   6 --
 hw/s390x/s390-pci-bus.c          |   6 --
 hw/vfio/pci-quirks.c             |   6 --
 target/sparc/cpu.c               |   6 --
 8 files changed, 18 insertions(+), 188 deletions(-)

diff --git a/backends/tpm/tpm_util.c b/backends/tpm/tpm_util.c
index dba2f6b04a..0b07cf55ea 100644
--- a/backends/tpm/tpm_util.c
+++ b/backends/tpm/tpm_util.c
@@ -46,16 +46,10 @@ static void get_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
 static void set_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     TPMBackend *s, **be = qdev_get_prop_ptr(obj, prop);
     char *str;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_str(v, name, &str, errp)) {
         return;
     }
diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
index 905e4acd97..bd1aef63a7 100644
--- a/hw/block/xen-block.c
+++ b/hw/block/xen-block.c
@@ -395,17 +395,11 @@ static int vbd_name_to_disk(const char *name, const char **endp,
 static void xen_block_set_vdev(Object *obj, Visitor *v, const char *name,
                                void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     XenBlockVdev *vdev = qdev_get_prop_ptr(obj, prop);
     char *str, *p;
     const char *end;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_str(v, name, &str, errp)) {
         return;
     }
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 202abd0e4b..0d3e57bba0 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -94,11 +94,6 @@ static void set_drive_helper(Object *obj, Visitor *v, const char *name,
     bool blk_created = false;
     int ret;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_str(v, name, &str, errp)) {
         return;
     }
@@ -230,17 +225,11 @@ static void get_chr(Object *obj, Visitor *v, const char *name, void *opaque,
 static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     CharBackend *be = qdev_get_prop_ptr(obj, prop);
     Chardev *s;
     char *str;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_str(v, name, &str, errp)) {
         return;
     }
@@ -311,18 +300,12 @@ static void get_mac(Object *obj, Visitor *v, const char *name, void *opaque,
 static void set_mac(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     MACAddr *mac = qdev_get_prop_ptr(obj, prop);
     int i, pos;
     char *str;
     const char *p;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_str(v, name, &str, errp)) {
         return;
     }
@@ -390,7 +373,6 @@ static void get_netdev(Object *obj, Visitor *v, const char *name,
 static void set_netdev(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     NICPeers *peers_ptr = qdev_get_prop_ptr(obj, prop);
     NetClientState **ncs = peers_ptr->ncs;
@@ -398,11 +380,6 @@ static void set_netdev(Object *obj, Visitor *v, const char *name,
     int queues, err = 0, i = 0;
     char *str;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_str(v, name, &str, errp)) {
         return;
     }
@@ -469,18 +446,12 @@ static void get_audiodev(Object *obj, Visitor *v, const char* name,
 static void set_audiodev(Object *obj, Visitor *v, const char* name,
                          void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     QEMUSoundCard *card = qdev_get_prop_ptr(obj, prop);
     AudioState *state;
     int err = 0;
     char *str;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_str(v, name, &str, errp)) {
         return;
     }
@@ -582,11 +553,6 @@ static void set_blocksize(Object *obj, Visitor *v, const char *name,
     uint64_t value;
     Error *local_err = NULL;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_size(v, name, &value, errp)) {
         return;
     }
@@ -686,7 +652,6 @@ static void get_reserved_region(Object *obj, Visitor *v, const char *name,
 static void set_reserved_region(Object *obj, Visitor *v, const char *name,
                                 void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     ReservedRegion *rr = qdev_get_prop_ptr(obj, prop);
     Error *local_err = NULL;
@@ -694,11 +659,6 @@ static void set_reserved_region(Object *obj, Visitor *v, const char *name,
     char *str;
     int ret;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     visit_type_str(v, name, &str, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
@@ -754,17 +714,11 @@ const PropertyInfo qdev_prop_reserved_region = {
 static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
                           void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     int32_t value, *ptr = qdev_get_prop_ptr(obj, prop);
     unsigned int slot, fn, n;
     char *str;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_str(v, name, &str, NULL)) {
         if (!visit_type_int32(v, name, &value, errp)) {
             return;
@@ -848,7 +802,6 @@ static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
 static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
                                  void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     PCIHostDeviceAddress *addr = qdev_get_prop_ptr(obj, prop);
     char *str, *p;
@@ -857,11 +810,6 @@ static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
     unsigned long dom = 0, bus = 0;
     unsigned int slot = 0, func = 0;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_str(v, name, &str, errp)) {
         return;
     }
@@ -971,16 +919,10 @@ static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
 static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
                                    void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     PCIExpLinkSpeed *p = qdev_get_prop_ptr(obj, prop);
     int speed;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_enum(v, name, &speed, prop->info->enum_table,
                          errp)) {
         return;
@@ -1056,16 +998,10 @@ static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
 static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
                                    void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     PCIExpLinkWidth *p = qdev_get_prop_ptr(obj, prop);
     int width;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_enum(v, name, &width, prop->info->enum_table,
                          errp)) {
         return;
@@ -1128,16 +1064,10 @@ static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
 static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     QemuUUID *uuid = qdev_get_prop_ptr(obj, prop);
     char *str;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_str(v, name, &str, errp)) {
         return;
     }
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 0e5ff81da8..ff36eb250e 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -24,6 +24,19 @@ void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
     }
 }
 
+/* returns: true if property is allowed to be set, false otherwise */
+static bool qdev_prop_allow_set(Object *obj, const char *name,
+                                Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+
+    if (dev->realized) {
+        qdev_prop_set_after_realize(dev, name, errp);
+        return false;
+    }
+    return true;
+}
+
 void qdev_prop_allow_set_link_before_realize(const Object *obj,
                                              const char *name,
                                              Object *val, Error **errp)
@@ -65,6 +78,11 @@ static void field_prop_set(Object *obj, Visitor *v, const char *name,
                            void *opaque, Error **errp)
 {
     Property *prop = opaque;
+
+    if (!qdev_prop_allow_set(obj, name, errp)) {
+        return;
+    }
+
     return prop->info->set(obj, v, name, opaque, errp);
 }
 
@@ -90,15 +108,9 @@ void qdev_propinfo_get_enum(Object *obj, Visitor *v, const char *name,
 void qdev_propinfo_set_enum(Object *obj, Visitor *v, const char *name,
                             void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     int *ptr = qdev_get_prop_ptr(obj, prop);
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
 }
 
@@ -148,15 +160,9 @@ static void prop_get_bit(Object *obj, Visitor *v, const char *name,
 static void prop_set_bit(Object *obj, Visitor *v, const char *name,
                          void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     bool value;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_bool(v, name, &value, errp)) {
         return;
     }
@@ -208,15 +214,9 @@ static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
 static void prop_set_bit64(Object *obj, Visitor *v, const char *name,
                            void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     bool value;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_bool(v, name, &value, errp)) {
         return;
     }
@@ -245,15 +245,9 @@ static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
 static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     bool *ptr = qdev_get_prop_ptr(obj, prop);
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     visit_type_bool(v, name, ptr, errp);
 }
 
@@ -278,15 +272,9 @@ static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
 static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
                       Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     uint8_t *ptr = qdev_get_prop_ptr(obj, prop);
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     visit_type_uint8(v, name, ptr, errp);
 }
 
@@ -323,15 +311,9 @@ void qdev_propinfo_get_uint16(Object *obj, Visitor *v, const char *name,
 static void set_uint16(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     uint16_t *ptr = qdev_get_prop_ptr(obj, prop);
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     visit_type_uint16(v, name, ptr, errp);
 }
 
@@ -356,15 +338,9 @@ static void get_uint32(Object *obj, Visitor *v, const char *name,
 static void set_uint32(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     visit_type_uint32(v, name, ptr, errp);
 }
 
@@ -380,15 +356,9 @@ void qdev_propinfo_get_int32(Object *obj, Visitor *v, const char *name,
 static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
                       Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     int32_t *ptr = qdev_get_prop_ptr(obj, prop);
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     visit_type_int32(v, name, ptr, errp);
 }
 
@@ -420,15 +390,9 @@ static void get_uint64(Object *obj, Visitor *v, const char *name,
 static void set_uint64(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     visit_type_uint64(v, name, ptr, errp);
 }
 
@@ -444,15 +408,9 @@ static void get_int64(Object *obj, Visitor *v, const char *name,
 static void set_int64(Object *obj, Visitor *v, const char *name,
                       void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     int64_t *ptr = qdev_get_prop_ptr(obj, prop);
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     visit_type_int64(v, name, ptr, errp);
 }
 
@@ -495,16 +453,10 @@ static void get_string(Object *obj, Visitor *v, const char *name,
 static void set_string(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     char **ptr = qdev_get_prop_ptr(obj, prop);
     char *str;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_str(v, name, &str, errp)) {
         return;
     }
@@ -545,16 +497,10 @@ void qdev_propinfo_get_size32(Object *obj, Visitor *v, const char *name,
 static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
                        Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
     uint64_t value;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_size(v, name, &value, errp)) {
         return;
     }
@@ -621,10 +567,6 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
     const char *arrayname;
     int i;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
     if (*alenptr) {
         error_setg(errp, "array size property %s may not be set more than once",
                    name);
@@ -864,15 +806,9 @@ static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
 static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     visit_type_size(v, name, ptr, errp);
 }
 
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 7a44320d12..496e2c5801 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -2372,18 +2372,12 @@ static void get_css_devid(Object *obj, Visitor *v, const char *name,
 static void set_css_devid(Object *obj, Visitor *v, const char *name,
                           void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     CssDevId *dev_id = qdev_get_prop_ptr(obj, prop);
     char *str;
     int num, n1, n2;
     unsigned int cssid, ssid, devid;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_str(v, name, &str, errp)) {
         return;
     }
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index ab27b6e848..54fac3851d 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -1331,16 +1331,10 @@ static void s390_pci_get_fid(Object *obj, Visitor *v, const char *name,
 static void s390_pci_set_fid(Object *obj, Visitor *v, const char *name,
                          void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     S390PCIBusDevice *zpci = S390_PCI_DEVICE(obj);
     Property *prop = opaque;
     uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_uint32(v, name, ptr, errp)) {
         return;
     }
diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
index 53569925a2..802979635c 100644
--- a/hw/vfio/pci-quirks.c
+++ b/hw/vfio/pci-quirks.c
@@ -1498,15 +1498,9 @@ static void set_nv_gpudirect_clique_id(Object *obj, Visitor *v,
                                        const char *name, void *opaque,
                                        Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     uint8_t value, *ptr = qdev_get_prop_ptr(obj, prop);
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_uint8(v, name, &value, errp)) {
         return;
     }
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index f5cff4103b..3375fffb38 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -798,17 +798,11 @@ static void sparc_get_nwindows(Object *obj, Visitor *v, const char *name,
 static void sparc_set_nwindows(Object *obj, Visitor *v, const char *name,
                                void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     const int64_t min = MIN_NWINDOWS;
     const int64_t max = MAX_NWINDOWS;
     SPARCCPU *cpu = SPARC_CPU(obj);
     int64_t value;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_int(v, name, &value, errp)) {
         return;
     }
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 22/44] qdev: Move dev->realized check to qdev_property_set()
@ 2020-11-04 15:59   ` Eduardo Habkost
  0 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 15:59 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, Paolo Bonzini, Igor Mammedov, Eric Blake,
	Stefan Berger, Markus Armbruster, Marc-André Lureau,
	John Snow, Philippe Mathieu-Daudé,
	Stefan Berger, Stefano Stabellini, Anthony Perard, Paul Durrant,
	Kevin Wolf, Max Reitz, Cornelia Huck, Halil Pasic,
	Christian Borntraeger, Richard Henderson, David Hildenbrand,
	Thomas Huth, Matthew Rosato, Alex Williamson, Mark Cave-Ayland,
	Artyom Tarasenko, xen-devel, qemu-block, qemu-s390x

Every single qdev property setter function manually checks
dev->realized.  We can just check dev->realized inside
qdev_property_set() instead.

The check is being added as a separate function
(qdev_prop_allow_set()) because it will become a callback later.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Changes v1 -> v2:
* Removed unused variable at xen_block_set_vdev()
* Redone patch after changes in the previous patches in the
  series
---
Cc: Stefan Berger <stefanb@linux.vnet.ibm.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Paul Durrant <paul@xen.org>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: Cornelia Huck <cohuck@redhat.com>
Cc: Halil Pasic <pasic@linux.ibm.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: David Hildenbrand <david@redhat.com>
Cc: Thomas Huth <thuth@redhat.com>
Cc: Matthew Rosato <mjrosato@linux.ibm.com>
Cc: Alex Williamson <alex.williamson@redhat.com>
Cc: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Cc: Artyom Tarasenko <atar4qemu@gmail.com>
Cc: qemu-devel@nongnu.org
Cc: xen-devel@lists.xenproject.org
Cc: qemu-block@nongnu.org
Cc: qemu-s390x@nongnu.org
---
 backends/tpm/tpm_util.c          |   6 --
 hw/block/xen-block.c             |   6 --
 hw/core/qdev-properties-system.c |  70 ----------------------
 hw/core/qdev-properties.c        | 100 ++++++-------------------------
 hw/s390x/css.c                   |   6 --
 hw/s390x/s390-pci-bus.c          |   6 --
 hw/vfio/pci-quirks.c             |   6 --
 target/sparc/cpu.c               |   6 --
 8 files changed, 18 insertions(+), 188 deletions(-)

diff --git a/backends/tpm/tpm_util.c b/backends/tpm/tpm_util.c
index dba2f6b04a..0b07cf55ea 100644
--- a/backends/tpm/tpm_util.c
+++ b/backends/tpm/tpm_util.c
@@ -46,16 +46,10 @@ static void get_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
 static void set_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     TPMBackend *s, **be = qdev_get_prop_ptr(obj, prop);
     char *str;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_str(v, name, &str, errp)) {
         return;
     }
diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
index 905e4acd97..bd1aef63a7 100644
--- a/hw/block/xen-block.c
+++ b/hw/block/xen-block.c
@@ -395,17 +395,11 @@ static int vbd_name_to_disk(const char *name, const char **endp,
 static void xen_block_set_vdev(Object *obj, Visitor *v, const char *name,
                                void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     XenBlockVdev *vdev = qdev_get_prop_ptr(obj, prop);
     char *str, *p;
     const char *end;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_str(v, name, &str, errp)) {
         return;
     }
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 202abd0e4b..0d3e57bba0 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -94,11 +94,6 @@ static void set_drive_helper(Object *obj, Visitor *v, const char *name,
     bool blk_created = false;
     int ret;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_str(v, name, &str, errp)) {
         return;
     }
@@ -230,17 +225,11 @@ static void get_chr(Object *obj, Visitor *v, const char *name, void *opaque,
 static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     CharBackend *be = qdev_get_prop_ptr(obj, prop);
     Chardev *s;
     char *str;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_str(v, name, &str, errp)) {
         return;
     }
@@ -311,18 +300,12 @@ static void get_mac(Object *obj, Visitor *v, const char *name, void *opaque,
 static void set_mac(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     MACAddr *mac = qdev_get_prop_ptr(obj, prop);
     int i, pos;
     char *str;
     const char *p;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_str(v, name, &str, errp)) {
         return;
     }
@@ -390,7 +373,6 @@ static void get_netdev(Object *obj, Visitor *v, const char *name,
 static void set_netdev(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     NICPeers *peers_ptr = qdev_get_prop_ptr(obj, prop);
     NetClientState **ncs = peers_ptr->ncs;
@@ -398,11 +380,6 @@ static void set_netdev(Object *obj, Visitor *v, const char *name,
     int queues, err = 0, i = 0;
     char *str;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_str(v, name, &str, errp)) {
         return;
     }
@@ -469,18 +446,12 @@ static void get_audiodev(Object *obj, Visitor *v, const char* name,
 static void set_audiodev(Object *obj, Visitor *v, const char* name,
                          void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     QEMUSoundCard *card = qdev_get_prop_ptr(obj, prop);
     AudioState *state;
     int err = 0;
     char *str;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_str(v, name, &str, errp)) {
         return;
     }
@@ -582,11 +553,6 @@ static void set_blocksize(Object *obj, Visitor *v, const char *name,
     uint64_t value;
     Error *local_err = NULL;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_size(v, name, &value, errp)) {
         return;
     }
@@ -686,7 +652,6 @@ static void get_reserved_region(Object *obj, Visitor *v, const char *name,
 static void set_reserved_region(Object *obj, Visitor *v, const char *name,
                                 void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     ReservedRegion *rr = qdev_get_prop_ptr(obj, prop);
     Error *local_err = NULL;
@@ -694,11 +659,6 @@ static void set_reserved_region(Object *obj, Visitor *v, const char *name,
     char *str;
     int ret;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     visit_type_str(v, name, &str, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
@@ -754,17 +714,11 @@ const PropertyInfo qdev_prop_reserved_region = {
 static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
                           void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     int32_t value, *ptr = qdev_get_prop_ptr(obj, prop);
     unsigned int slot, fn, n;
     char *str;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_str(v, name, &str, NULL)) {
         if (!visit_type_int32(v, name, &value, errp)) {
             return;
@@ -848,7 +802,6 @@ static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
 static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
                                  void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     PCIHostDeviceAddress *addr = qdev_get_prop_ptr(obj, prop);
     char *str, *p;
@@ -857,11 +810,6 @@ static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
     unsigned long dom = 0, bus = 0;
     unsigned int slot = 0, func = 0;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_str(v, name, &str, errp)) {
         return;
     }
@@ -971,16 +919,10 @@ static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
 static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
                                    void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     PCIExpLinkSpeed *p = qdev_get_prop_ptr(obj, prop);
     int speed;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_enum(v, name, &speed, prop->info->enum_table,
                          errp)) {
         return;
@@ -1056,16 +998,10 @@ static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
 static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
                                    void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     PCIExpLinkWidth *p = qdev_get_prop_ptr(obj, prop);
     int width;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_enum(v, name, &width, prop->info->enum_table,
                          errp)) {
         return;
@@ -1128,16 +1064,10 @@ static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
 static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     QemuUUID *uuid = qdev_get_prop_ptr(obj, prop);
     char *str;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_str(v, name, &str, errp)) {
         return;
     }
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 0e5ff81da8..ff36eb250e 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -24,6 +24,19 @@ void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
     }
 }
 
+/* returns: true if property is allowed to be set, false otherwise */
+static bool qdev_prop_allow_set(Object *obj, const char *name,
+                                Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+
+    if (dev->realized) {
+        qdev_prop_set_after_realize(dev, name, errp);
+        return false;
+    }
+    return true;
+}
+
 void qdev_prop_allow_set_link_before_realize(const Object *obj,
                                              const char *name,
                                              Object *val, Error **errp)
@@ -65,6 +78,11 @@ static void field_prop_set(Object *obj, Visitor *v, const char *name,
                            void *opaque, Error **errp)
 {
     Property *prop = opaque;
+
+    if (!qdev_prop_allow_set(obj, name, errp)) {
+        return;
+    }
+
     return prop->info->set(obj, v, name, opaque, errp);
 }
 
@@ -90,15 +108,9 @@ void qdev_propinfo_get_enum(Object *obj, Visitor *v, const char *name,
 void qdev_propinfo_set_enum(Object *obj, Visitor *v, const char *name,
                             void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     int *ptr = qdev_get_prop_ptr(obj, prop);
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
 }
 
@@ -148,15 +160,9 @@ static void prop_get_bit(Object *obj, Visitor *v, const char *name,
 static void prop_set_bit(Object *obj, Visitor *v, const char *name,
                          void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     bool value;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_bool(v, name, &value, errp)) {
         return;
     }
@@ -208,15 +214,9 @@ static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
 static void prop_set_bit64(Object *obj, Visitor *v, const char *name,
                            void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     bool value;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_bool(v, name, &value, errp)) {
         return;
     }
@@ -245,15 +245,9 @@ static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
 static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     bool *ptr = qdev_get_prop_ptr(obj, prop);
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     visit_type_bool(v, name, ptr, errp);
 }
 
@@ -278,15 +272,9 @@ static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
 static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
                       Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     uint8_t *ptr = qdev_get_prop_ptr(obj, prop);
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     visit_type_uint8(v, name, ptr, errp);
 }
 
@@ -323,15 +311,9 @@ void qdev_propinfo_get_uint16(Object *obj, Visitor *v, const char *name,
 static void set_uint16(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     uint16_t *ptr = qdev_get_prop_ptr(obj, prop);
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     visit_type_uint16(v, name, ptr, errp);
 }
 
@@ -356,15 +338,9 @@ static void get_uint32(Object *obj, Visitor *v, const char *name,
 static void set_uint32(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     visit_type_uint32(v, name, ptr, errp);
 }
 
@@ -380,15 +356,9 @@ void qdev_propinfo_get_int32(Object *obj, Visitor *v, const char *name,
 static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
                       Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     int32_t *ptr = qdev_get_prop_ptr(obj, prop);
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     visit_type_int32(v, name, ptr, errp);
 }
 
@@ -420,15 +390,9 @@ static void get_uint64(Object *obj, Visitor *v, const char *name,
 static void set_uint64(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     visit_type_uint64(v, name, ptr, errp);
 }
 
@@ -444,15 +408,9 @@ static void get_int64(Object *obj, Visitor *v, const char *name,
 static void set_int64(Object *obj, Visitor *v, const char *name,
                       void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     int64_t *ptr = qdev_get_prop_ptr(obj, prop);
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     visit_type_int64(v, name, ptr, errp);
 }
 
@@ -495,16 +453,10 @@ static void get_string(Object *obj, Visitor *v, const char *name,
 static void set_string(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     char **ptr = qdev_get_prop_ptr(obj, prop);
     char *str;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_str(v, name, &str, errp)) {
         return;
     }
@@ -545,16 +497,10 @@ void qdev_propinfo_get_size32(Object *obj, Visitor *v, const char *name,
 static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
                        Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
     uint64_t value;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_size(v, name, &value, errp)) {
         return;
     }
@@ -621,10 +567,6 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
     const char *arrayname;
     int i;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
     if (*alenptr) {
         error_setg(errp, "array size property %s may not be set more than once",
                    name);
@@ -864,15 +806,9 @@ static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
 static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     visit_type_size(v, name, ptr, errp);
 }
 
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 7a44320d12..496e2c5801 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -2372,18 +2372,12 @@ static void get_css_devid(Object *obj, Visitor *v, const char *name,
 static void set_css_devid(Object *obj, Visitor *v, const char *name,
                           void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     CssDevId *dev_id = qdev_get_prop_ptr(obj, prop);
     char *str;
     int num, n1, n2;
     unsigned int cssid, ssid, devid;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_str(v, name, &str, errp)) {
         return;
     }
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index ab27b6e848..54fac3851d 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -1331,16 +1331,10 @@ static void s390_pci_get_fid(Object *obj, Visitor *v, const char *name,
 static void s390_pci_set_fid(Object *obj, Visitor *v, const char *name,
                          void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     S390PCIBusDevice *zpci = S390_PCI_DEVICE(obj);
     Property *prop = opaque;
     uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_uint32(v, name, ptr, errp)) {
         return;
     }
diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
index 53569925a2..802979635c 100644
--- a/hw/vfio/pci-quirks.c
+++ b/hw/vfio/pci-quirks.c
@@ -1498,15 +1498,9 @@ static void set_nv_gpudirect_clique_id(Object *obj, Visitor *v,
                                        const char *name, void *opaque,
                                        Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     uint8_t value, *ptr = qdev_get_prop_ptr(obj, prop);
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_uint8(v, name, &value, errp)) {
         return;
     }
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index f5cff4103b..3375fffb38 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -798,17 +798,11 @@ static void sparc_get_nwindows(Object *obj, Visitor *v, const char *name,
 static void sparc_set_nwindows(Object *obj, Visitor *v, const char *name,
                                void *opaque, Error **errp)
 {
-    DeviceState *dev = DEVICE(obj);
     const int64_t min = MIN_NWINDOWS;
     const int64_t max = MAX_NWINDOWS;
     SPARCCPU *cpu = SPARC_CPU(obj);
     int64_t value;
 
-    if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
-        return;
-    }
-
     if (!visit_type_int(v, name, &value, errp)) {
         return;
     }
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 23/44] qdev: Make PropertyInfo.create return ObjectProperty*
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (21 preceding siblings ...)
  2020-11-04 15:59   ` Eduardo Habkost
@ 2020-11-04 16:00 ` Eduardo Habkost
  2020-11-04 16:00 ` [PATCH v2 24/44] qdev: Make qdev_class_add_property() more flexible Eduardo Habkost
                   ` (22 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 16:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

Returning ObjectProperty* will be useful for new property
registration code that will add additional callbacks
to ObjectProperty after registering it.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Changes v1 -> v2:
* Redone patch on top of additional changes in series v2
* Commit message reword
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 include/hw/qdev-properties.h |  3 ++-
 hw/core/qdev-properties.c    | 12 ++++++------
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index ab9c538ba4..aae882317a 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -34,7 +34,8 @@ struct PropertyInfo {
     const QEnumLookup *enum_table;
     int (*print)(Object *obj, Property *prop, char *dest, size_t len);
     void (*set_default_value)(ObjectProperty *op, const Property *prop);
-    void (*create)(ObjectClass *oc, const char *name, Property *prop);
+    ObjectProperty *(*create)(ObjectClass *oc, const char *name,
+                              Property *prop);
     ObjectPropertyAccessor *get;
     ObjectPropertyAccessor *set;
     ObjectPropertyRelease *release;
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index ff36eb250e..510b3f3fb5 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -821,13 +821,13 @@ const PropertyInfo qdev_prop_size = {
 
 /* --- object link property --- */
 
-static void create_link_property(ObjectClass *oc, const char *name,
-                                 Property *prop)
+static ObjectProperty *create_link_property(ObjectClass *oc, const char *name,
+                                            Property *prop)
 {
-    object_class_property_add_link(oc, name, prop->link_type,
-                                   prop->offset,
-                                   qdev_prop_allow_set_link_before_realize,
-                                   OBJ_PROP_LINK_STRONG);
+    return object_class_property_add_link(oc, name, prop->link_type,
+                                          prop->offset,
+                                          qdev_prop_allow_set_link_before_realize,
+                                          OBJ_PROP_LINK_STRONG);
 }
 
 const PropertyInfo qdev_prop_link = {
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 24/44] qdev: Make qdev_class_add_property() more flexible
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (22 preceding siblings ...)
  2020-11-04 16:00 ` [PATCH v2 23/44] qdev: Make PropertyInfo.create return ObjectProperty* Eduardo Habkost
@ 2020-11-04 16:00 ` Eduardo Habkost
  2020-11-04 16:00 ` [PATCH v2 25/44] qdev: Separate generic and device-specific property registration Eduardo Habkost
                   ` (21 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 16:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

Support Property.set_default and PropertyInfo.description even if
PropertyInfo.create is set.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Changes v1 -> v2:
* Patch redone after changes in the previous patches in the
  series
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 hw/core/qdev-properties.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 510b3f3fb5..a5d5d74f32 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -863,24 +863,25 @@ static void qdev_class_add_property(DeviceClass *klass, const char *name,
                                     Property *prop)
 {
     ObjectClass *oc = OBJECT_CLASS(klass);
+    ObjectProperty *op;
 
     if (prop->info->create) {
-        prop->info->create(oc, name, prop);
+        op = prop->info->create(oc, name, prop);
     } else {
-        ObjectProperty *op;
-
         op = object_class_property_add(oc,
                                        name, prop->info->name,
                                        field_prop_getter(prop->info),
                                        field_prop_setter(prop->info),
                                        prop->info->release,
                                        prop);
-        if (prop->set_default) {
-            prop->info->set_default_value(op, prop);
-        }
     }
-    object_class_property_set_description(oc, name,
-                                          prop->info->description);
+    if (prop->set_default) {
+        prop->info->set_default_value(op, prop);
+    }
+    if (prop->info->description) {
+        object_class_property_set_description(oc, name,
+                                              prop->info->description);
+    }
 }
 
 /**
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 25/44] qdev: Separate generic and device-specific property registration
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (23 preceding siblings ...)
  2020-11-04 16:00 ` [PATCH v2 24/44] qdev: Make qdev_class_add_property() more flexible Eduardo Habkost
@ 2020-11-04 16:00 ` Eduardo Habkost
  2020-11-04 16:00 ` [PATCH v2 26/44] qdev: Rename Property.name to Property.qdev_prop_name Eduardo Habkost
                   ` (20 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 16:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

qdev_class_add_property() and qdev_property_add_static() will
have code that's specific for device types.

object_class_property_add_field() and object_property_add_static()
will be generic and part of the QOM field property API.  Note
that the new functions have a `name` parameter because the plan
is to eventually get rid of the Property.name field.

The declarations for the new functions are being added to
qdev-properties.h, but they will be moved to a QOM header later.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Changes v1 -> v2:
* Patch redone after changes in previous patches in the series
* Rename new functions to object*_property_add_field()
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 hw/core/qdev-prop-internal.h | 13 +++++++++++++
 include/hw/qdev-properties.h | 16 ++++++++++++++++
 hw/core/qdev-properties.c    | 25 +++++++++++++++++--------
 3 files changed, 46 insertions(+), 8 deletions(-)

diff --git a/hw/core/qdev-prop-internal.h b/hw/core/qdev-prop-internal.h
index 9cf5cc1d51..0e16d28171 100644
--- a/hw/core/qdev-prop-internal.h
+++ b/hw/core/qdev-prop-internal.h
@@ -27,4 +27,17 @@ void qdev_propinfo_get_int32(Object *obj, Visitor *v, const char *name,
 void qdev_propinfo_get_size32(Object *obj, Visitor *v, const char *name,
                               void *opaque, Error **errp);
 
+/**
+ * object_property_add_field: Add a field property to an object instance
+ * @obj: object instance
+ * @name: property name
+ * @prop: property definition
+ *
+ * This function should not be used in new code.  Please add class properties
+ * instead, using object_class_add_field().
+ */
+ObjectProperty *
+object_property_add_field(Object *obj, const char *name,
+                          Property *prop);
+
 #endif
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index aae882317a..bbc5244ed0 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -167,6 +167,22 @@ extern const PropertyInfo qdev_prop_link;
 #define DEFINE_PROP_END_OF_LIST()               \
     {}
 
+/**
+ * object_class_property_add_field: Add a field property to object class
+ * @oc: object class
+ * @name: property name
+ * @prop: property definition
+ *
+ * Add a field property to an object class.  A field property is
+ * a property that will change a field at a specific offset of the
+ * object instance struct.
+ *
+ * *@prop must exist for the life time of @oc.
+ */
+ObjectProperty *
+object_class_property_add_field(ObjectClass *oc, const char *name,
+                                Property *prop);
+
 /*
  * Set properties between creation and realization.
  *
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index a5d5d74f32..e9e2a34f3b 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -835,20 +835,20 @@ const PropertyInfo qdev_prop_link = {
     .create = create_link_property,
 };
 
-void qdev_property_add_static(DeviceState *dev, Property *prop)
+ObjectProperty *
+object_property_add_field(Object *obj, const char *name, Property *prop)
 {
-    Object *obj = OBJECT(dev);
     ObjectProperty *op;
 
     assert(!prop->info->create);
 
-    op = object_property_add(obj, prop->name, prop->info->name,
+    op = object_property_add(obj, name, prop->info->name,
                              field_prop_getter(prop->info),
                              field_prop_setter(prop->info),
                              prop->info->release,
                              prop);
 
-    object_property_set_description(obj, prop->name,
+    object_property_set_description(obj, name,
                                     prop->info->description);
 
     if (prop->set_default) {
@@ -857,12 +857,14 @@ void qdev_property_add_static(DeviceState *dev, Property *prop)
             op->init(obj, op);
         }
     }
+
+    return op;
 }
 
-static void qdev_class_add_property(DeviceClass *klass, const char *name,
-                                    Property *prop)
+ObjectProperty *
+object_class_property_add_field(ObjectClass *oc, const char *name,
+                                Property *prop)
 {
-    ObjectClass *oc = OBJECT_CLASS(klass);
     ObjectProperty *op;
 
     if (prop->info->create) {
@@ -882,6 +884,12 @@ static void qdev_class_add_property(DeviceClass *klass, const char *name,
         object_class_property_set_description(oc, name,
                                               prop->info->description);
     }
+    return op;
+}
+
+void qdev_property_add_static(DeviceState *dev, Property *prop)
+{
+    object_property_add_field(OBJECT(dev), prop->name, prop);
 }
 
 /**
@@ -932,12 +940,13 @@ static void qdev_class_add_legacy_property(DeviceClass *dc, Property *prop)
 
 void device_class_set_props(DeviceClass *dc, Property *props)
 {
+    ObjectClass *oc = OBJECT_CLASS(dc);
     Property *prop;
 
     dc->props_ = props;
     for (prop = props; prop && prop->name; prop++) {
         qdev_class_add_legacy_property(dc, prop);
-        qdev_class_add_property(dc, prop->name, prop);
+        object_class_property_add_field(oc, prop->name, prop);
     }
 }
 
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 26/44] qdev: Rename Property.name to Property.qdev_prop_name
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (24 preceding siblings ...)
  2020-11-04 16:00 ` [PATCH v2 25/44] qdev: Separate generic and device-specific property registration Eduardo Habkost
@ 2020-11-04 16:00 ` Eduardo Habkost
  2020-11-04 16:00 ` [PATCH v2 27/44] qdev: Don't set qdev_prop_name for array elements Eduardo Habkost
                   ` (19 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 16:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

The Property.name field won't always be set and we need to be
100% sure its usage will be restricted to qdev/TYPE_DEVICE code.
Renaming the field is a good way to ensure that and make its
purpose more clear.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
This is a new patch added in v2 of the series
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 include/hw/qdev-properties.h | 11 +++++++++--
 hw/core/qdev-properties.c    | 20 ++++++++++----------
 softmmu/qdev-monitor.c       |  8 ++++----
 3 files changed, 23 insertions(+), 16 deletions(-)

diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index bbc5244ed0..b301fe64d7 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -13,7 +13,14 @@
  *     is true.
  */
 struct Property {
-    const char   *name;
+    /**
+     * @qdev_prop_name: qdev property name
+     *
+     * qdev_prop_name is used only by TYPE_DEVICE code
+     * (device_class_set_props(), qdev_class_add_property(), and
+     * others).
+     */
+    const char   *qdev_prop_name;
     const PropertyInfo *info;
     ptrdiff_t    offset;
     uint8_t      bitnr;
@@ -63,7 +70,7 @@ extern const PropertyInfo qdev_prop_arraylen;
 extern const PropertyInfo qdev_prop_link;
 
 #define DEFINE_PROP(_name, _state, _field, _prop, _type, ...) {  \
-        .name      = (_name),                                    \
+        .qdev_prop_name      = (_name),                          \
         .info      = &(_prop),                                   \
         .offset    = offsetof(_state, _field)                    \
             + type_check(_type, typeof_field(_state, _field)),   \
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index e9e2a34f3b..5a4aa87fc9 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -596,7 +596,7 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
         arrayprop->release = prop->arrayinfo->release;
         arrayprop->propname = propname;
         arrayprop->prop.info = prop->arrayinfo;
-        arrayprop->prop.name = propname;
+        arrayprop->prop.qdev_prop_name = propname;
         /* This ugly piece of pointer arithmetic sets up the offset so
          * that when the underlying get/set hooks call qdev_get_prop_ptr
          * they get the right answer despite the array element not actually
@@ -627,8 +627,8 @@ static Property *qdev_prop_walk(Property *props, const char *name)
     if (!props) {
         return NULL;
     }
-    while (props->name) {
-        if (strcmp(props->name, name) == 0) {
+    while (props->qdev_prop_name) {
+        if (strcmp(props->qdev_prop_name, name) == 0) {
             return props;
         }
         props++;
@@ -889,7 +889,7 @@ object_class_property_add_field(ObjectClass *oc, const char *name,
 
 void qdev_property_add_static(DeviceState *dev, Property *prop)
 {
-    object_property_add_field(OBJECT(dev), prop->name, prop);
+    object_property_add_field(OBJECT(dev), prop->qdev_prop_name, prop);
 }
 
 /**
@@ -932,7 +932,7 @@ static void qdev_class_add_legacy_property(DeviceClass *dc, Property *prop)
         return;
     }
 
-    name = g_strdup_printf("legacy-%s", prop->name);
+    name = g_strdup_printf("legacy-%s", prop->qdev_prop_name);
     object_class_property_add(OBJECT_CLASS(dc), name, "str",
         prop->info->print ? qdev_get_legacy_property : prop->info->get,
         NULL, NULL, prop);
@@ -944,9 +944,9 @@ void device_class_set_props(DeviceClass *dc, Property *props)
     Property *prop;
 
     dc->props_ = props;
-    for (prop = props; prop && prop->name; prop++) {
+    for (prop = props; prop && prop->qdev_prop_name; prop++) {
         qdev_class_add_legacy_property(dc, prop);
-        object_class_property_add_field(oc, prop->name, prop);
+        object_class_property_add_field(oc, prop->qdev_prop_name, prop);
     }
 }
 
@@ -959,9 +959,9 @@ void qdev_alias_all_properties(DeviceState *target, Object *source)
     do {
         DeviceClass *dc = DEVICE_CLASS(class);
 
-        for (prop = dc->props_; prop && prop->name; prop++) {
-            object_property_add_alias(source, prop->name,
-                                      OBJECT(target), prop->name);
+        for (prop = dc->props_; prop && prop->qdev_prop_name; prop++) {
+            object_property_add_alias(source, prop->qdev_prop_name,
+                                      OBJECT(target), prop->qdev_prop_name);
         }
         class = object_class_get_parent(class);
     } while (class != object_class_by_name(TYPE_DEVICE));
diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
index 79164e4a3f..786b9ce572 100644
--- a/softmmu/qdev-monitor.c
+++ b/softmmu/qdev-monitor.c
@@ -697,14 +697,14 @@ static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
 {
     if (!props)
         return;
-    for (; props->name; props++) {
+    for (; props->qdev_prop_name; props++) {
         char *value;
-        char *legacy_name = g_strdup_printf("legacy-%s", props->name);
+        char *legacy_name = g_strdup_printf("legacy-%s", props->qdev_prop_name);
 
         if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
             value = object_property_get_str(OBJECT(dev), legacy_name, NULL);
         } else {
-            value = object_property_print(OBJECT(dev), props->name, true,
+            value = object_property_print(OBJECT(dev), props->qdev_prop_name, true,
                                           NULL);
         }
         g_free(legacy_name);
@@ -712,7 +712,7 @@ static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
         if (!value) {
             continue;
         }
-        qdev_printf("%s = %s\n", props->name,
+        qdev_printf("%s = %s\n", props->qdev_prop_name,
                     *value ? value : "<null>");
         g_free(value);
     }
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 27/44] qdev: Don't set qdev_prop_name for array elements
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (25 preceding siblings ...)
  2020-11-04 16:00 ` [PATCH v2 26/44] qdev: Rename Property.name to Property.qdev_prop_name Eduardo Habkost
@ 2020-11-04 16:00 ` Eduardo Habkost
  2020-11-04 16:00 ` [PATCH v2 28/44] qdev: Avoid unnecessary DeviceState* variable at set_prop_arraylen() Eduardo Habkost
                   ` (18 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 16:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

qdev_prop_name is supposed to be used only by qdev property
registration code, we don't need to set it for array element
properties.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
This is a new patch added in v2 of the series
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 hw/core/qdev-properties.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 5a4aa87fc9..f1557f12b9 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -596,7 +596,6 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
         arrayprop->release = prop->arrayinfo->release;
         arrayprop->propname = propname;
         arrayprop->prop.info = prop->arrayinfo;
-        arrayprop->prop.qdev_prop_name = propname;
         /* This ugly piece of pointer arithmetic sets up the offset so
          * that when the underlying get/set hooks call qdev_get_prop_ptr
          * they get the right answer despite the array element not actually
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 28/44] qdev: Avoid unnecessary DeviceState* variable at set_prop_arraylen()
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (26 preceding siblings ...)
  2020-11-04 16:00 ` [PATCH v2 27/44] qdev: Don't set qdev_prop_name for array elements Eduardo Habkost
@ 2020-11-04 16:00 ` Eduardo Habkost
  2020-11-04 16:00 ` [PATCH v2 29/44] qdev: Remove ArrayElementProperty.propname field Eduardo Habkost
                   ` (17 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 16:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

We're just doing pointer math with the device pointer, we can
simply use obj instead.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 hw/core/qdev-properties.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index f1557f12b9..4cbdd34a04 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -559,10 +559,9 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
      * array-length field in the device struct, we have to create the
      * array itself and dynamically add the corresponding properties.
      */
-    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     uint32_t *alenptr = qdev_get_prop_ptr(obj, prop);
-    void **arrayptr = (void *)dev + prop->arrayoffset;
+    void **arrayptr = (void *)obj + prop->arrayoffset;
     void *eltptr;
     const char *arrayname;
     int i;
@@ -601,7 +600,7 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
          * they get the right answer despite the array element not actually
          * being inside the device struct.
          */
-        arrayprop->prop.offset = eltptr - (void *)dev;
+        arrayprop->prop.offset = eltptr - (void *)obj;
         assert(qdev_get_prop_ptr(obj, &arrayprop->prop) == eltptr);
         object_property_add(obj, propname,
                             arrayprop->prop.info->name,
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 29/44] qdev: Remove ArrayElementProperty.propname field
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (27 preceding siblings ...)
  2020-11-04 16:00 ` [PATCH v2 28/44] qdev: Avoid unnecessary DeviceState* variable at set_prop_arraylen() Eduardo Habkost
@ 2020-11-04 16:00 ` Eduardo Habkost
  2020-11-04 16:00 ` [PATCH v2 30/44] qdev: Get rid of ArrayElementProperty struct Eduardo Habkost
                   ` (16 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 16:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

Now that we don't save the property name in Property.name
anymore, we don't need the to keep the property name string alive
after the property was registered.

We can remove the ArrayElementProperty.propname field, and free
the string immediately after registering the property.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
This is a new patch added in v2 of the series
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 hw/core/qdev-properties.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 4cbdd34a04..a0192c3723 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -533,7 +533,6 @@ const PropertyInfo qdev_prop_size32 = {
  */
 typedef struct {
     struct Property prop;
-    char *propname;
     ObjectPropertyRelease *release;
 } ArrayElementProperty;
 
@@ -547,7 +546,6 @@ static void array_element_release(Object *obj, const char *name, void *opaque)
     if (p->release) {
         p->release(obj, name, opaque);
     }
-    g_free(p->propname);
     g_free(p);
 }
 
@@ -590,10 +588,9 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
      */
     *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize);
     for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) {
-        char *propname = g_strdup_printf("%s[%d]", arrayname, i);
+        g_autofree char *propname = g_strdup_printf("%s[%d]", arrayname, i);
         ArrayElementProperty *arrayprop = g_new0(ArrayElementProperty, 1);
         arrayprop->release = prop->arrayinfo->release;
-        arrayprop->propname = propname;
         arrayprop->prop.info = prop->arrayinfo;
         /* This ugly piece of pointer arithmetic sets up the offset so
          * that when the underlying get/set hooks call qdev_get_prop_ptr
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 30/44] qdev: Get rid of ArrayElementProperty struct
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (28 preceding siblings ...)
  2020-11-04 16:00 ` [PATCH v2 29/44] qdev: Remove ArrayElementProperty.propname field Eduardo Habkost
@ 2020-11-04 16:00 ` Eduardo Habkost
  2020-11-04 16:00 ` [PATCH v2 31/44] qdev: Reuse object_property_add_field() when adding array elements Eduardo Habkost
                   ` (15 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 16:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

Now that we don't store any additional data about the property in
AraryElementStruct, we don't need it anymore.  We can just
allocate a Property struct directly.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
This is a new patch added in v2 of the series
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 hw/core/qdev-properties.c | 41 ++++++++-------------------------------
 1 file changed, 8 insertions(+), 33 deletions(-)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index a0192c3723..0aa482b3ab 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -525,30 +525,6 @@ const PropertyInfo qdev_prop_size32 = {
 
 /* --- support for array properties --- */
 
-/* Used as an opaque for the object properties we add for each
- * array element. Note that the struct Property must be first
- * in the struct so that a pointer to this works as the opaque
- * for the underlying element's property hooks as well as for
- * our own release callback.
- */
-typedef struct {
-    struct Property prop;
-    ObjectPropertyRelease *release;
-} ArrayElementProperty;
-
-/* object property release callback for array element properties:
- * we call the underlying element's property release hook, and
- * then free the memory we allocated when we added the property.
- */
-static void array_element_release(Object *obj, const char *name, void *opaque)
-{
-    ArrayElementProperty *p = opaque;
-    if (p->release) {
-        p->release(obj, name, opaque);
-    }
-    g_free(p);
-}
-
 static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
                               void *opaque, Error **errp)
 {
@@ -589,21 +565,20 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
     *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize);
     for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) {
         g_autofree char *propname = g_strdup_printf("%s[%d]", arrayname, i);
-        ArrayElementProperty *arrayprop = g_new0(ArrayElementProperty, 1);
-        arrayprop->release = prop->arrayinfo->release;
-        arrayprop->prop.info = prop->arrayinfo;
+        Property *arrayprop = g_new0(Property, 1);
+        arrayprop->info = prop->arrayinfo;
         /* This ugly piece of pointer arithmetic sets up the offset so
          * that when the underlying get/set hooks call qdev_get_prop_ptr
          * they get the right answer despite the array element not actually
          * being inside the device struct.
          */
-        arrayprop->prop.offset = eltptr - (void *)obj;
-        assert(qdev_get_prop_ptr(obj, &arrayprop->prop) == eltptr);
+        arrayprop->offset = eltptr - (void *)obj;
+        assert(qdev_get_prop_ptr(obj, arrayprop) == eltptr);
         object_property_add(obj, propname,
-                            arrayprop->prop.info->name,
-                            field_prop_getter(arrayprop->prop.info),
-                            field_prop_setter(arrayprop->prop.info),
-                            array_element_release,
+                            arrayprop->info->name,
+                            field_prop_getter(arrayprop->info),
+                            field_prop_setter(arrayprop->info),
+                            arrayprop->info->release,
                             arrayprop);
     }
 }
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 31/44] qdev: Reuse object_property_add_field() when adding array elements
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (29 preceding siblings ...)
  2020-11-04 16:00 ` [PATCH v2 30/44] qdev: Get rid of ArrayElementProperty struct Eduardo Habkost
@ 2020-11-04 16:00 ` Eduardo Habkost
  2020-11-04 16:00 ` [PATCH v2 32/44] qom: Add allow_set callback to ObjectProperty Eduardo Habkost
                   ` (14 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 16:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

Now that we can call object_property_add() with exactly the same
arguments as object_property_add_field(), we can just reuse the
function.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Changes v1 -> v2:
* Now we don't need to hack ObjectProperty.release anymore,
  patch became trivial
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 hw/core/qdev-properties.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 0aa482b3ab..5faf974c4f 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -574,12 +574,7 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
          */
         arrayprop->offset = eltptr - (void *)obj;
         assert(qdev_get_prop_ptr(obj, arrayprop) == eltptr);
-        object_property_add(obj, propname,
-                            arrayprop->info->name,
-                            field_prop_getter(arrayprop->info),
-                            field_prop_setter(arrayprop->info),
-                            arrayprop->info->release,
-                            arrayprop);
+        object_property_add_field(obj, propname, arrayprop);
     }
 }
 
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 32/44] qom: Add allow_set callback to ObjectProperty
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (30 preceding siblings ...)
  2020-11-04 16:00 ` [PATCH v2 31/44] qdev: Reuse object_property_add_field() when adding array elements Eduardo Habkost
@ 2020-11-04 16:00 ` Eduardo Habkost
  2020-11-04 16:00 ` [PATCH v2 33/44] qdev: Make qdev_prop_allow_set() a ObjectProperty.allow_set callback Eduardo Habkost
                   ` (13 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 16:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

Add a ObjectProperty.allow_set callback, that can be set by QOM
property registration functions.

Note that this doesn't replace the check callback at
object*_property_add_link() (yet), because currently the link
property check callback needs to get the property value as
argument (despite this not being necessary in most cases).

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Changes v1 -> v2:
* Redone patch on top of changes in previous patches in the
  series
* Provide prop_allow_set_always() and prop_allow_set_never()
  helpers
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 include/qom/object.h | 38 ++++++++++++++++++++++++++++++++++++++
 qom/object.c         | 16 ++++++++++++++++
 2 files changed, 54 insertions(+)

diff --git a/include/qom/object.h b/include/qom/object.h
index d378f13a11..2ab124b8f0 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -86,6 +86,43 @@ typedef void (ObjectPropertyRelease)(Object *obj,
  */
 typedef void (ObjectPropertyInit)(Object *obj, ObjectProperty *prop);
 
+/**
+ * typedef ObjectPropertyAllowSet:
+ * @obj: the object that owns the property
+ * @prop: the property being set
+ * @errp: pointer to error information
+ *
+ * Called when a property is being set.
+ *
+ * If return value is false, it will prevent the property from
+ * being changed.  Error information should be filled in @errp
+ * if return vlaue is false.
+ */
+typedef bool (ObjectPropertyAllowSet)(Object *obj, ObjectProperty *prop,
+                                      Error **errp);
+
+/**
+ * prop_allow_set_always:
+ * @obj: the object that owns the property
+ * @prop: the property being set
+ * @errp: pointer to error information
+ *
+ * ObjectPropertyAllowSet implementation that always allow the
+ * property to be set.
+ */
+bool prop_allow_set_always(Object *obj, ObjectProperty *prop, Error **errp);
+
+/**
+ * prop_allow_set_never:
+ * @obj: the object that owns the property
+ * @prop: the property being set
+ * @errp: pointer to error information
+ *
+ * ObjectPropertyAllowSet implementation that never allows the
+ * property to be set.
+ */
+bool prop_allow_set_never(Object *obj, ObjectProperty *prop, Error **errp);
+
 struct ObjectProperty
 {
     char *name;
@@ -96,6 +133,7 @@ struct ObjectProperty
     ObjectPropertyResolve *resolve;
     ObjectPropertyRelease *release;
     ObjectPropertyInit *init;
+    ObjectPropertyAllowSet *allow_set;
     void *opaque;
     QObject *defval;
 };
diff --git a/qom/object.c b/qom/object.c
index 1065355233..7c11bcd3b1 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1381,6 +1381,18 @@ bool object_property_get(Object *obj, const char *name, Visitor *v,
     return !err;
 }
 
+bool prop_allow_set_always(Object *obj, ObjectProperty *prop, Error **errp)
+{
+    return true;
+}
+
+bool prop_allow_set_never(Object *obj, ObjectProperty *prop, Error **errp)
+{
+    error_setg(errp, "Property '%s.%s' can't be set",
+               object_get_typename(obj), prop->name);
+    return false;
+}
+
 bool object_property_set(Object *obj, const char *name, Visitor *v,
                          Error **errp)
 {
@@ -1395,6 +1407,10 @@ bool object_property_set(Object *obj, const char *name, Visitor *v,
         error_setg(errp, QERR_PERMISSION_DENIED);
         return false;
     }
+    if (prop->allow_set && !prop->allow_set(obj, prop, errp)) {
+        return false;
+    }
+
     prop->set(obj, v, name, prop->opaque, &err);
     error_propagate(errp, err);
     return !err;
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 33/44] qdev: Make qdev_prop_allow_set() a ObjectProperty.allow_set callback
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (31 preceding siblings ...)
  2020-11-04 16:00 ` [PATCH v2 32/44] qom: Add allow_set callback to ObjectProperty Eduardo Habkost
@ 2020-11-04 16:00 ` Eduardo Habkost
  2020-11-04 16:00 ` [PATCH v2 34/44] qdev: Make qdev_propinfo_get_uint16() static Eduardo Habkost
                   ` (12 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 16:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

Add a new allow_set parameter to object*_property_add_field(),
and pass qdev_prop_allow_set as argument in the qdev registration
code.

This removes the last remaining line of code inside the core
field property code that's specific to TYPE_DEVICE, and will
allow us to make field properties a core QOM feature.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Changes v1 -> v2:
* Redone patch on top of changes in previous patches in the
  series
* Forbid allow_set==NULL to avoid confusion with link property
  semantics (where NULL makes the property read only)
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 hw/core/qdev-prop-internal.h |  4 +++-
 include/hw/qdev-properties.h |  8 +++++++-
 hw/core/qdev-properties.c    | 35 +++++++++++++++++++++++------------
 3 files changed, 33 insertions(+), 14 deletions(-)

diff --git a/hw/core/qdev-prop-internal.h b/hw/core/qdev-prop-internal.h
index 0e16d28171..9fac681e38 100644
--- a/hw/core/qdev-prop-internal.h
+++ b/hw/core/qdev-prop-internal.h
@@ -32,12 +32,14 @@ void qdev_propinfo_get_size32(Object *obj, Visitor *v, const char *name,
  * @obj: object instance
  * @name: property name
  * @prop: property definition
+ * @allow_set: check function called when property is set
  *
  * This function should not be used in new code.  Please add class properties
  * instead, using object_class_add_field().
  */
 ObjectProperty *
 object_property_add_field(Object *obj, const char *name,
-                          Property *prop);
+                          Property *prop,
+                          ObjectPropertyAllowSet allow_set);
 
 #endif
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index b301fe64d7..7f8d5fc206 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -179,16 +179,22 @@ extern const PropertyInfo qdev_prop_link;
  * @oc: object class
  * @name: property name
  * @prop: property definition
+ * @allow_set: check function called when property is set
  *
  * Add a field property to an object class.  A field property is
  * a property that will change a field at a specific offset of the
  * object instance struct.
  *
  * *@prop must exist for the life time of @oc.
+ *
+ * @allow_set should not be NULL.  If the property can always be
+ * set, `prop_allow_set_always` can be used.  If the property can
+ * never be set, `prop_allow_set_never` can be used.
  */
 ObjectProperty *
 object_class_property_add_field(ObjectClass *oc, const char *name,
-                                Property *prop);
+                                Property *prop,
+                                ObjectPropertyAllowSet allow_set);
 
 /*
  * Set properties between creation and realization.
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 5faf974c4f..ec9e456d95 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -25,13 +25,13 @@ void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
 }
 
 /* returns: true if property is allowed to be set, false otherwise */
-static bool qdev_prop_allow_set(Object *obj, const char *name,
+static bool qdev_prop_allow_set(Object *obj, ObjectProperty *op,
                                 Error **errp)
 {
     DeviceState *dev = DEVICE(obj);
 
     if (dev->realized) {
-        qdev_prop_set_after_realize(dev, name, errp);
+        qdev_prop_set_after_realize(dev, op->name, errp);
         return false;
     }
     return true;
@@ -79,10 +79,6 @@ static void field_prop_set(Object *obj, Visitor *v, const char *name,
 {
     Property *prop = opaque;
 
-    if (!qdev_prop_allow_set(obj, name, errp)) {
-        return;
-    }
-
     return prop->info->set(obj, v, name, opaque, errp);
 }
 
@@ -534,6 +530,7 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
      * array itself and dynamically add the corresponding properties.
      */
     Property *prop = opaque;
+    ObjectProperty *op = object_property_find_err(obj, name, &error_abort);
     uint32_t *alenptr = qdev_get_prop_ptr(obj, prop);
     void **arrayptr = (void *)obj + prop->arrayoffset;
     void *eltptr;
@@ -574,7 +571,7 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
          */
         arrayprop->offset = eltptr - (void *)obj;
         assert(qdev_get_prop_ptr(obj, arrayprop) == eltptr);
-        object_property_add_field(obj, propname, arrayprop);
+        object_property_add_field(obj, propname, arrayprop, op->allow_set);
     }
 }
 
@@ -789,9 +786,13 @@ const PropertyInfo qdev_prop_size = {
 static ObjectProperty *create_link_property(ObjectClass *oc, const char *name,
                                             Property *prop)
 {
+    /*
+     * NOTE: object_property_allow_set_link is unconditional, but
+     *       ObjectProperty.allow_set may be set for the property too.
+     */
     return object_class_property_add_link(oc, name, prop->link_type,
                                           prop->offset,
-                                          qdev_prop_allow_set_link_before_realize,
+                                          object_property_allow_set_link,
                                           OBJ_PROP_LINK_STRONG);
 }
 
@@ -801,10 +802,12 @@ const PropertyInfo qdev_prop_link = {
 };
 
 ObjectProperty *
-object_property_add_field(Object *obj, const char *name, Property *prop)
+object_property_add_field(Object *obj, const char *name, Property *prop,
+                          ObjectPropertyAllowSet allow_set)
 {
     ObjectProperty *op;
 
+    assert(allow_set);
     assert(!prop->info->create);
 
     op = object_property_add(obj, name, prop->info->name,
@@ -823,15 +826,19 @@ object_property_add_field(Object *obj, const char *name, Property *prop)
         }
     }
 
+    op->allow_set = allow_set;
     return op;
 }
 
 ObjectProperty *
 object_class_property_add_field(ObjectClass *oc, const char *name,
-                                Property *prop)
+                                Property *prop,
+                                ObjectPropertyAllowSet allow_set)
 {
     ObjectProperty *op;
 
+    assert(allow_set);
+
     if (prop->info->create) {
         op = prop->info->create(oc, name, prop);
     } else {
@@ -849,12 +856,15 @@ object_class_property_add_field(ObjectClass *oc, const char *name,
         object_class_property_set_description(oc, name,
                                               prop->info->description);
     }
+
+    op->allow_set = allow_set;
     return op;
 }
 
 void qdev_property_add_static(DeviceState *dev, Property *prop)
 {
-    object_property_add_field(OBJECT(dev), prop->qdev_prop_name, prop);
+    object_property_add_field(OBJECT(dev), prop->qdev_prop_name, prop,
+                              qdev_prop_allow_set);
 }
 
 /**
@@ -911,7 +921,8 @@ void device_class_set_props(DeviceClass *dc, Property *props)
     dc->props_ = props;
     for (prop = props; prop && prop->qdev_prop_name; prop++) {
         qdev_class_add_legacy_property(dc, prop);
-        object_class_property_add_field(oc, prop->qdev_prop_name, prop);
+        object_class_property_add_field(oc, prop->qdev_prop_name, prop,
+                                        qdev_prop_allow_set);
     }
 }
 
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 34/44] qdev: Make qdev_propinfo_get_uint16() static
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (32 preceding siblings ...)
  2020-11-04 16:00 ` [PATCH v2 33/44] qdev: Make qdev_prop_allow_set() a ObjectProperty.allow_set callback Eduardo Habkost
@ 2020-11-04 16:00 ` Eduardo Habkost
  2020-11-04 16:00 ` [PATCH v2 35/44] qdev: Rename qdev_propinfo_* to field_prop_* Eduardo Habkost
                   ` (11 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 16:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

There are no users of the function outside qdev-properties.c.
Make function static and rename it to get_uint16().

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 hw/core/qdev-prop-internal.h | 2 --
 hw/core/qdev-properties.c    | 6 +++---
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/hw/core/qdev-prop-internal.h b/hw/core/qdev-prop-internal.h
index 9fac681e38..3a1e2bbc27 100644
--- a/hw/core/qdev-prop-internal.h
+++ b/hw/core/qdev-prop-internal.h
@@ -20,8 +20,6 @@ void qdev_propinfo_set_default_value_int(ObjectProperty *op,
 void qdev_propinfo_set_default_value_uint(ObjectProperty *op,
                                           const Property *prop);
 
-void qdev_propinfo_get_uint16(Object *obj, Visitor *v, const char *name,
-                              void *opaque, Error **errp);
 void qdev_propinfo_get_int32(Object *obj, Visitor *v, const char *name,
                              void *opaque, Error **errp);
 void qdev_propinfo_get_size32(Object *obj, Visitor *v, const char *name,
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index ec9e456d95..2a9f62a922 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -295,8 +295,8 @@ const PropertyInfo qdev_prop_uint8 = {
 
 /* --- 16bit integer --- */
 
-void qdev_propinfo_get_uint16(Object *obj, Visitor *v, const char *name,
-                              void *opaque, Error **errp)
+static void get_uint16(Object *obj, Visitor *v, const char *name,
+                       void *opaque, Error **errp)
 {
     Property *prop = opaque;
     uint16_t *ptr = qdev_get_prop_ptr(obj, prop);
@@ -315,7 +315,7 @@ static void set_uint16(Object *obj, Visitor *v, const char *name,
 
 const PropertyInfo qdev_prop_uint16 = {
     .name  = "uint16",
-    .get   = qdev_propinfo_get_uint16,
+    .get   = get_uint16,
     .set   = set_uint16,
     .set_default_value = qdev_propinfo_set_default_value_uint,
 };
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 35/44] qdev: Rename qdev_propinfo_* to field_prop_*
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (33 preceding siblings ...)
  2020-11-04 16:00 ` [PATCH v2 34/44] qdev: Make qdev_propinfo_get_uint16() static Eduardo Habkost
@ 2020-11-04 16:00 ` Eduardo Habkost
  2020-11-04 16:00   ` Eduardo Habkost
                   ` (10 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 16:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

These functions will be moved to be part of QOM, so rename them.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Changes v2:
* Rename to field_prop_* instead of object_propinfo_*
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 hw/core/qdev-prop-internal.h     | 28 +++++++--------
 hw/core/qdev-properties-system.c | 48 ++++++++++++-------------
 hw/core/qdev-properties.c        | 62 ++++++++++++++++----------------
 3 files changed, 69 insertions(+), 69 deletions(-)

diff --git a/hw/core/qdev-prop-internal.h b/hw/core/qdev-prop-internal.h
index 3a1e2bbc27..bdcb37f14f 100644
--- a/hw/core/qdev-prop-internal.h
+++ b/hw/core/qdev-prop-internal.h
@@ -8,22 +8,22 @@
 #ifndef HW_CORE_QDEV_PROP_INTERNAL_H
 #define HW_CORE_QDEV_PROP_INTERNAL_H
 
-void qdev_propinfo_get_enum(Object *obj, Visitor *v, const char *name,
-                            void *opaque, Error **errp);
-void qdev_propinfo_set_enum(Object *obj, Visitor *v, const char *name,
-                            void *opaque, Error **errp);
+void field_prop_get_enum(Object *obj, Visitor *v, const char *name,
+                         void *opaque, Error **errp);
+void field_prop_set_enum(Object *obj, Visitor *v, const char *name,
+                         void *opaque, Error **errp);
 
-void qdev_propinfo_set_default_value_enum(ObjectProperty *op,
-                                          const Property *prop);
-void qdev_propinfo_set_default_value_int(ObjectProperty *op,
-                                         const Property *prop);
-void qdev_propinfo_set_default_value_uint(ObjectProperty *op,
-                                          const Property *prop);
+void field_prop_set_default_value_enum(ObjectProperty *op,
+                                       const Property *prop);
+void field_prop_set_default_value_int(ObjectProperty *op,
+                                      const Property *prop);
+void field_prop_set_default_value_uint(ObjectProperty *op,
+                                       const Property *prop);
 
-void qdev_propinfo_get_int32(Object *obj, Visitor *v, const char *name,
-                             void *opaque, Error **errp);
-void qdev_propinfo_get_size32(Object *obj, Visitor *v, const char *name,
-                              void *opaque, Error **errp);
+void field_prop_get_int32(Object *obj, Visitor *v, const char *name,
+                          void *opaque, Error **errp);
+void field_prop_get_size32(Object *obj, Visitor *v, const char *name,
+                           void *opaque, Error **errp);
 
 /**
  * object_property_add_field: Add a field property to an object instance
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 0d3e57bba0..96a0bc5109 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -537,9 +537,9 @@ QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
 const PropertyInfo qdev_prop_losttickpolicy = {
     .name  = "LostTickPolicy",
     .enum_table  = &LostTickPolicy_lookup,
-    .get   = qdev_propinfo_get_enum,
-    .set   = qdev_propinfo_set_enum,
-    .set_default_value = qdev_propinfo_set_default_value_enum,
+    .get   = field_prop_get_enum,
+    .set   = field_prop_set_enum,
+    .set_default_value = field_prop_set_default_value_enum,
 };
 
 /* --- blocksize --- */
@@ -568,9 +568,9 @@ const PropertyInfo qdev_prop_blocksize = {
     .name  = "size",
     .description = "A power of two between " MIN_BLOCK_SIZE_STR
                    " and " MAX_BLOCK_SIZE_STR,
-    .get   = qdev_propinfo_get_size32,
+    .get   = field_prop_get_size32,
     .set   = set_blocksize,
-    .set_default_value = qdev_propinfo_set_default_value_uint,
+    .set_default_value = field_prop_set_default_value_uint,
 };
 
 /* --- Block device error handling policy --- */
@@ -582,9 +582,9 @@ const PropertyInfo qdev_prop_blockdev_on_error = {
     .description = "Error handling policy, "
                    "report/ignore/enospc/stop/auto",
     .enum_table = &BlockdevOnError_lookup,
-    .get = qdev_propinfo_get_enum,
-    .set = qdev_propinfo_set_enum,
-    .set_default_value = qdev_propinfo_set_default_value_enum,
+    .get = field_prop_get_enum,
+    .set = field_prop_set_enum,
+    .set_default_value = field_prop_set_default_value_enum,
 };
 
 /* --- BIOS CHS translation */
@@ -596,9 +596,9 @@ const PropertyInfo qdev_prop_bios_chs_trans = {
     .description = "Logical CHS translation algorithm, "
                    "auto/none/lba/large/rechs",
     .enum_table = &BiosAtaTranslation_lookup,
-    .get = qdev_propinfo_get_enum,
-    .set = qdev_propinfo_set_enum,
-    .set_default_value = qdev_propinfo_set_default_value_enum,
+    .get = field_prop_get_enum,
+    .set = field_prop_set_enum,
+    .set_default_value = field_prop_set_default_value_enum,
 };
 
 /* --- FDC default drive types */
@@ -608,9 +608,9 @@ const PropertyInfo qdev_prop_fdc_drive_type = {
     .description = "FDC drive type, "
                    "144/288/120/none/auto",
     .enum_table = &FloppyDriveType_lookup,
-    .get = qdev_propinfo_get_enum,
-    .set = qdev_propinfo_set_enum,
-    .set_default_value = qdev_propinfo_set_default_value_enum,
+    .get = field_prop_get_enum,
+    .set = field_prop_set_enum,
+    .set_default_value = field_prop_set_default_value_enum,
 };
 
 /* --- MultiFDCompression --- */
@@ -620,9 +620,9 @@ const PropertyInfo qdev_prop_multifd_compression = {
     .description = "multifd_compression values, "
                    "none/zlib/zstd",
     .enum_table = &MultiFDCompression_lookup,
-    .get = qdev_propinfo_get_enum,
-    .set = qdev_propinfo_set_enum,
-    .set_default_value = qdev_propinfo_set_default_value_enum,
+    .get = field_prop_get_enum,
+    .set = field_prop_set_enum,
+    .set_default_value = field_prop_set_default_value_enum,
 };
 
 /* --- Reserved Region --- */
@@ -766,9 +766,9 @@ const PropertyInfo qdev_prop_pci_devfn = {
     .name  = "int32",
     .description = "Slot and optional function number, example: 06.0 or 06",
     .print = print_pci_devfn,
-    .get   = qdev_propinfo_get_int32,
+    .get   = field_prop_get_int32,
     .set   = set_pci_devfn,
-    .set_default_value = qdev_propinfo_set_default_value_int,
+    .set_default_value = field_prop_set_default_value_int,
 };
 
 /* --- pci host address --- */
@@ -881,9 +881,9 @@ const PropertyInfo qdev_prop_off_auto_pcibar = {
     .name = "OffAutoPCIBAR",
     .description = "off/auto/bar0/bar1/bar2/bar3/bar4/bar5",
     .enum_table = &OffAutoPCIBAR_lookup,
-    .get = qdev_propinfo_get_enum,
-    .set = qdev_propinfo_set_enum,
-    .set_default_value = qdev_propinfo_set_default_value_enum,
+    .get = field_prop_get_enum,
+    .set = field_prop_set_enum,
+    .set_default_value = field_prop_set_default_value_enum,
 };
 
 /* --- PCIELinkSpeed 2_5/5/8/16 -- */
@@ -953,7 +953,7 @@ const PropertyInfo qdev_prop_pcie_link_speed = {
     .enum_table = &PCIELinkSpeed_lookup,
     .get = get_prop_pcielinkspeed,
     .set = set_prop_pcielinkspeed,
-    .set_default_value = qdev_propinfo_set_default_value_enum,
+    .set_default_value = field_prop_set_default_value_enum,
 };
 
 /* --- PCIELinkWidth 1/2/4/8/12/16/32 -- */
@@ -1041,7 +1041,7 @@ const PropertyInfo qdev_prop_pcie_link_width = {
     .enum_table = &PCIELinkWidth_lookup,
     .get = get_prop_pcielinkwidth,
     .set = set_prop_pcielinkwidth,
-    .set_default_value = qdev_propinfo_set_default_value_enum,
+    .set_default_value = field_prop_set_default_value_enum,
 };
 
 /* --- UUID --- */
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 2a9f62a922..aeab4ae9b6 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -92,8 +92,8 @@ static ObjectPropertyAccessor *field_prop_setter(const PropertyInfo *info)
     return info->set ? field_prop_set : NULL;
 }
 
-void qdev_propinfo_get_enum(Object *obj, Visitor *v, const char *name,
-                            void *opaque, Error **errp)
+void field_prop_get_enum(Object *obj, Visitor *v, const char *name,
+                         void *opaque, Error **errp)
 {
     Property *prop = opaque;
     int *ptr = qdev_get_prop_ptr(obj, prop);
@@ -101,8 +101,8 @@ void qdev_propinfo_get_enum(Object *obj, Visitor *v, const char *name,
     visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
 }
 
-void qdev_propinfo_set_enum(Object *obj, Visitor *v, const char *name,
-                            void *opaque, Error **errp)
+void field_prop_set_enum(Object *obj, Visitor *v, const char *name,
+                         void *opaque, Error **errp)
 {
     Property *prop = opaque;
     int *ptr = qdev_get_prop_ptr(obj, prop);
@@ -110,8 +110,8 @@ void qdev_propinfo_set_enum(Object *obj, Visitor *v, const char *name,
     visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
 }
 
-void qdev_propinfo_set_default_value_enum(ObjectProperty *op,
-                                          const Property *prop)
+void field_prop_set_default_value_enum(ObjectProperty *op,
+                                       const Property *prop)
 {
     object_property_set_default_str(op,
         qapi_enum_lookup(prop->info->enum_table, prop->defval.i));
@@ -119,9 +119,9 @@ void qdev_propinfo_set_default_value_enum(ObjectProperty *op,
 
 const PropertyInfo qdev_prop_enum = {
     .name  = "enum",
-    .get   = qdev_propinfo_get_enum,
-    .set   = qdev_propinfo_set_enum,
-    .set_default_value = qdev_propinfo_set_default_value_enum,
+    .get   = field_prop_get_enum,
+    .set   = field_prop_set_enum,
+    .set_default_value = field_prop_set_default_value_enum,
 };
 
 /* Bit */
@@ -274,14 +274,14 @@ static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
     visit_type_uint8(v, name, ptr, errp);
 }
 
-void qdev_propinfo_set_default_value_int(ObjectProperty *op,
-                                         const Property *prop)
+void field_prop_set_default_value_int(ObjectProperty *op,
+                                      const Property *prop)
 {
     object_property_set_default_int(op, prop->defval.i);
 }
 
-void qdev_propinfo_set_default_value_uint(ObjectProperty *op,
-                                          const Property *prop)
+void field_prop_set_default_value_uint(ObjectProperty *op,
+                                       const Property *prop)
 {
     object_property_set_default_uint(op, prop->defval.u);
 }
@@ -290,7 +290,7 @@ const PropertyInfo qdev_prop_uint8 = {
     .name  = "uint8",
     .get   = get_uint8,
     .set   = set_uint8,
-    .set_default_value = qdev_propinfo_set_default_value_uint,
+    .set_default_value = field_prop_set_default_value_uint,
 };
 
 /* --- 16bit integer --- */
@@ -317,7 +317,7 @@ const PropertyInfo qdev_prop_uint16 = {
     .name  = "uint16",
     .get   = get_uint16,
     .set   = set_uint16,
-    .set_default_value = qdev_propinfo_set_default_value_uint,
+    .set_default_value = field_prop_set_default_value_uint,
 };
 
 /* --- 32bit integer --- */
@@ -340,8 +340,8 @@ static void set_uint32(Object *obj, Visitor *v, const char *name,
     visit_type_uint32(v, name, ptr, errp);
 }
 
-void qdev_propinfo_get_int32(Object *obj, Visitor *v, const char *name,
-                             void *opaque, Error **errp)
+void field_prop_get_int32(Object *obj, Visitor *v, const char *name,
+                          void *opaque, Error **errp)
 {
     Property *prop = opaque;
     int32_t *ptr = qdev_get_prop_ptr(obj, prop);
@@ -362,14 +362,14 @@ const PropertyInfo qdev_prop_uint32 = {
     .name  = "uint32",
     .get   = get_uint32,
     .set   = set_uint32,
-    .set_default_value = qdev_propinfo_set_default_value_uint,
+    .set_default_value = field_prop_set_default_value_uint,
 };
 
 const PropertyInfo qdev_prop_int32 = {
     .name  = "int32",
-    .get   = qdev_propinfo_get_int32,
+    .get   = field_prop_get_int32,
     .set   = set_int32,
-    .set_default_value = qdev_propinfo_set_default_value_int,
+    .set_default_value = field_prop_set_default_value_int,
 };
 
 /* --- 64bit integer --- */
@@ -414,14 +414,14 @@ const PropertyInfo qdev_prop_uint64 = {
     .name  = "uint64",
     .get   = get_uint64,
     .set   = set_uint64,
-    .set_default_value = qdev_propinfo_set_default_value_uint,
+    .set_default_value = field_prop_set_default_value_uint,
 };
 
 const PropertyInfo qdev_prop_int64 = {
     .name  = "int64",
     .get   = get_int64,
     .set   = set_int64,
-    .set_default_value = qdev_propinfo_set_default_value_int,
+    .set_default_value = field_prop_set_default_value_int,
 };
 
 /* --- string --- */
@@ -473,15 +473,15 @@ const PropertyInfo qdev_prop_on_off_auto = {
     .name = "OnOffAuto",
     .description = "on/off/auto",
     .enum_table = &OnOffAuto_lookup,
-    .get = qdev_propinfo_get_enum,
-    .set = qdev_propinfo_set_enum,
-    .set_default_value = qdev_propinfo_set_default_value_enum,
+    .get = field_prop_get_enum,
+    .set = field_prop_set_enum,
+    .set_default_value = field_prop_set_default_value_enum,
 };
 
 /* --- 32bit unsigned int 'size' type --- */
 
-void qdev_propinfo_get_size32(Object *obj, Visitor *v, const char *name,
-                              void *opaque, Error **errp)
+void field_prop_get_size32(Object *obj, Visitor *v, const char *name,
+                           void *opaque, Error **errp)
 {
     Property *prop = opaque;
     uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
@@ -514,9 +514,9 @@ static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
 
 const PropertyInfo qdev_prop_size32 = {
     .name  = "size",
-    .get = qdev_propinfo_get_size32,
+    .get = field_prop_get_size32,
     .set = set_size32,
-    .set_default_value = qdev_propinfo_set_default_value_uint,
+    .set_default_value = field_prop_set_default_value_uint,
 };
 
 /* --- support for array properties --- */
@@ -579,7 +579,7 @@ const PropertyInfo qdev_prop_arraylen = {
     .name = "uint32",
     .get = get_uint32,
     .set = set_prop_arraylen,
-    .set_default_value = qdev_propinfo_set_default_value_uint,
+    .set_default_value = field_prop_set_default_value_uint,
 };
 
 /* --- public helpers --- */
@@ -778,7 +778,7 @@ const PropertyInfo qdev_prop_size = {
     .name  = "size",
     .get = get_size,
     .set = set_size,
-    .set_default_value = qdev_propinfo_set_default_value_uint,
+    .set_default_value = field_prop_set_default_value_uint,
 };
 
 /* --- object link property --- */
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 36/44] qdev: Rename qdev_get_prop_ptr() to object_field_prop_ptr()
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
@ 2020-11-04 16:00   ` Eduardo Habkost
  2020-11-04 15:59 ` [PATCH v2 02/44] cpu: Move cpu_common_props to hw/core/cpu.c Eduardo Habkost
                     ` (44 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 16:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Matthew Rosato, Paul Durrant, Stefano Stabellini, xen-devel,
	qemu-block, Stefan Berger, David Hildenbrand, Markus Armbruster,
	Halil Pasic, Christian Borntraeger, Anthony Perard,
	Marc-André Lureau, Philippe Mathieu-Daudé,
	Thomas Huth, Alex Williamson, Paolo Bonzini, John Snow,
	Richard Henderson, Kevin Wolf, Daniel P. Berrange, Cornelia Huck,
	qemu-s390x, Max Reitz, Igor Mammedov, Stefan Berger

The function will be moved to common QOM code, as it is not
specific to TYPE_DEVICE anymore.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Changes v1 -> v2:
* Rename to object_field_prop_ptr() instead of object_static_prop_ptr()
---
Cc: Stefan Berger <stefanb@linux.vnet.ibm.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Paul Durrant <paul@xen.org>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: Cornelia Huck <cohuck@redhat.com>
Cc: Halil Pasic <pasic@linux.ibm.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: David Hildenbrand <david@redhat.com>
Cc: Thomas Huth <thuth@redhat.com>
Cc: Matthew Rosato <mjrosato@linux.ibm.com>
Cc: Alex Williamson <alex.williamson@redhat.com>
Cc: qemu-devel@nongnu.org
Cc: xen-devel@lists.xenproject.org
Cc: qemu-block@nongnu.org
Cc: qemu-s390x@nongnu.org
---
 include/hw/qdev-properties.h     |  2 +-
 backends/tpm/tpm_util.c          |  6 ++--
 hw/block/xen-block.c             |  4 +--
 hw/core/qdev-properties-system.c | 50 +++++++++++++-------------
 hw/core/qdev-properties.c        | 60 ++++++++++++++++----------------
 hw/s390x/css.c                   |  4 +--
 hw/s390x/s390-pci-bus.c          |  4 +--
 hw/vfio/pci-quirks.c             |  4 +--
 8 files changed, 67 insertions(+), 67 deletions(-)

diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 7f8d5fc206..2bec65c8e5 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -223,7 +223,7 @@ void qdev_prop_set_macaddr(DeviceState *dev, const char *name,
                            const uint8_t *value);
 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value);
 
-void *qdev_get_prop_ptr(Object *obj, Property *prop);
+void *object_field_prop_ptr(Object *obj, Property *prop);
 
 void qdev_prop_register_global(GlobalProperty *prop);
 const GlobalProperty *qdev_find_global_prop(Object *obj,
diff --git a/backends/tpm/tpm_util.c b/backends/tpm/tpm_util.c
index 0b07cf55ea..bb1ab34a75 100644
--- a/backends/tpm/tpm_util.c
+++ b/backends/tpm/tpm_util.c
@@ -35,7 +35,7 @@
 static void get_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
 {
-    TPMBackend **be = qdev_get_prop_ptr(obj, opaque);
+    TPMBackend **be = object_field_prop_ptr(obj, opaque);
     char *p;
 
     p = g_strdup(*be ? (*be)->id : "");
@@ -47,7 +47,7 @@ static void set_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
 {
     Property *prop = opaque;
-    TPMBackend *s, **be = qdev_get_prop_ptr(obj, prop);
+    TPMBackend *s, **be = object_field_prop_ptr(obj, prop);
     char *str;
 
     if (!visit_type_str(v, name, &str, errp)) {
@@ -67,7 +67,7 @@ static void set_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
 static void release_tpm(Object *obj, const char *name, void *opaque)
 {
     Property *prop = opaque;
-    TPMBackend **be = qdev_get_prop_ptr(obj, prop);
+    TPMBackend **be = object_field_prop_ptr(obj, prop);
 
     if (*be) {
         tpm_backend_reset(*be);
diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
index bd1aef63a7..718d886e5c 100644
--- a/hw/block/xen-block.c
+++ b/hw/block/xen-block.c
@@ -336,7 +336,7 @@ static void xen_block_get_vdev(Object *obj, Visitor *v, const char *name,
                                void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    XenBlockVdev *vdev = qdev_get_prop_ptr(obj, prop);
+    XenBlockVdev *vdev = object_field_prop_ptr(obj, prop);
     char *str;
 
     switch (vdev->type) {
@@ -396,7 +396,7 @@ static void xen_block_set_vdev(Object *obj, Visitor *v, const char *name,
                                void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    XenBlockVdev *vdev = qdev_get_prop_ptr(obj, prop);
+    XenBlockVdev *vdev = object_field_prop_ptr(obj, prop);
     char *str, *p;
     const char *end;
 
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 96a0bc5109..8781b856d3 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -62,7 +62,7 @@ static void get_drive(Object *obj, Visitor *v, const char *name, void *opaque,
                       Error **errp)
 {
     Property *prop = opaque;
-    void **ptr = qdev_get_prop_ptr(obj, prop);
+    void **ptr = object_field_prop_ptr(obj, prop);
     const char *value;
     char *p;
 
@@ -88,7 +88,7 @@ static void set_drive_helper(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    void **ptr = qdev_get_prop_ptr(obj, prop);
+    void **ptr = object_field_prop_ptr(obj, prop);
     char *str;
     BlockBackend *blk;
     bool blk_created = false;
@@ -181,7 +181,7 @@ static void release_drive(Object *obj, const char *name, void *opaque)
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    BlockBackend **ptr = qdev_get_prop_ptr(obj, prop);
+    BlockBackend **ptr = object_field_prop_ptr(obj, prop);
 
     if (*ptr) {
         AioContext *ctx = blk_get_aio_context(*ptr);
@@ -214,7 +214,7 @@ const PropertyInfo qdev_prop_drive_iothread = {
 static void get_chr(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
 {
-    CharBackend *be = qdev_get_prop_ptr(obj, opaque);
+    CharBackend *be = object_field_prop_ptr(obj, opaque);
     char *p;
 
     p = g_strdup(be->chr && be->chr->label ? be->chr->label : "");
@@ -226,7 +226,7 @@ static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
 {
     Property *prop = opaque;
-    CharBackend *be = qdev_get_prop_ptr(obj, prop);
+    CharBackend *be = object_field_prop_ptr(obj, prop);
     Chardev *s;
     char *str;
 
@@ -262,7 +262,7 @@ static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
 static void release_chr(Object *obj, const char *name, void *opaque)
 {
     Property *prop = opaque;
-    CharBackend *be = qdev_get_prop_ptr(obj, prop);
+    CharBackend *be = object_field_prop_ptr(obj, prop);
 
     qemu_chr_fe_deinit(be, false);
 }
@@ -286,7 +286,7 @@ static void get_mac(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
 {
     Property *prop = opaque;
-    MACAddr *mac = qdev_get_prop_ptr(obj, prop);
+    MACAddr *mac = object_field_prop_ptr(obj, prop);
     char buffer[2 * 6 + 5 + 1];
     char *p = buffer;
 
@@ -301,7 +301,7 @@ static void set_mac(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
 {
     Property *prop = opaque;
-    MACAddr *mac = qdev_get_prop_ptr(obj, prop);
+    MACAddr *mac = object_field_prop_ptr(obj, prop);
     int i, pos;
     char *str;
     const char *p;
@@ -363,7 +363,7 @@ static void get_netdev(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    NICPeers *peers_ptr = qdev_get_prop_ptr(obj, prop);
+    NICPeers *peers_ptr = object_field_prop_ptr(obj, prop);
     char *p = g_strdup(peers_ptr->ncs[0] ? peers_ptr->ncs[0]->name : "");
 
     visit_type_str(v, name, &p, errp);
@@ -374,7 +374,7 @@ static void set_netdev(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    NICPeers *peers_ptr = qdev_get_prop_ptr(obj, prop);
+    NICPeers *peers_ptr = object_field_prop_ptr(obj, prop);
     NetClientState **ncs = peers_ptr->ncs;
     NetClientState *peers[MAX_QUEUE_NUM];
     int queues, err = 0, i = 0;
@@ -436,7 +436,7 @@ static void get_audiodev(Object *obj, Visitor *v, const char* name,
                          void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    QEMUSoundCard *card = qdev_get_prop_ptr(obj, prop);
+    QEMUSoundCard *card = object_field_prop_ptr(obj, prop);
     char *p = g_strdup(audio_get_id(card));
 
     visit_type_str(v, name, &p, errp);
@@ -447,7 +447,7 @@ static void set_audiodev(Object *obj, Visitor *v, const char* name,
                          void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    QEMUSoundCard *card = qdev_get_prop_ptr(obj, prop);
+    QEMUSoundCard *card = object_field_prop_ptr(obj, prop);
     AudioState *state;
     int err = 0;
     char *str;
@@ -549,7 +549,7 @@ static void set_blocksize(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint32_t *ptr = object_field_prop_ptr(obj, prop);
     uint64_t value;
     Error *local_err = NULL;
 
@@ -637,7 +637,7 @@ static void get_reserved_region(Object *obj, Visitor *v, const char *name,
                                 void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    ReservedRegion *rr = qdev_get_prop_ptr(obj, prop);
+    ReservedRegion *rr = object_field_prop_ptr(obj, prop);
     char buffer[64];
     char *p = buffer;
     int rc;
@@ -653,7 +653,7 @@ static void set_reserved_region(Object *obj, Visitor *v, const char *name,
                                 void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    ReservedRegion *rr = qdev_get_prop_ptr(obj, prop);
+    ReservedRegion *rr = object_field_prop_ptr(obj, prop);
     Error *local_err = NULL;
     const char *endptr;
     char *str;
@@ -715,7 +715,7 @@ static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
                           void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    int32_t value, *ptr = qdev_get_prop_ptr(obj, prop);
+    int32_t value, *ptr = object_field_prop_ptr(obj, prop);
     unsigned int slot, fn, n;
     char *str;
 
@@ -753,7 +753,7 @@ invalid:
 static int print_pci_devfn(Object *obj, Property *prop, char *dest,
                            size_t len)
 {
-    int32_t *ptr = qdev_get_prop_ptr(obj, prop);
+    int32_t *ptr = object_field_prop_ptr(obj, prop);
 
     if (*ptr == -1) {
         return snprintf(dest, len, "<unset>");
@@ -777,7 +777,7 @@ static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
                                  void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(obj, prop);
+    PCIHostDeviceAddress *addr = object_field_prop_ptr(obj, prop);
     char buffer[] = "ffff:ff:ff.f";
     char *p = buffer;
     int rc = 0;
@@ -803,7 +803,7 @@ static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
                                  void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(obj, prop);
+    PCIHostDeviceAddress *addr = object_field_prop_ptr(obj, prop);
     char *str, *p;
     const char *e;
     unsigned long val;
@@ -892,7 +892,7 @@ static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
                                    void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    PCIExpLinkSpeed *p = qdev_get_prop_ptr(obj, prop);
+    PCIExpLinkSpeed *p = object_field_prop_ptr(obj, prop);
     int speed;
 
     switch (*p) {
@@ -920,7 +920,7 @@ static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
                                    void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    PCIExpLinkSpeed *p = qdev_get_prop_ptr(obj, prop);
+    PCIExpLinkSpeed *p = object_field_prop_ptr(obj, prop);
     int speed;
 
     if (!visit_type_enum(v, name, &speed, prop->info->enum_table,
@@ -962,7 +962,7 @@ static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
                                    void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    PCIExpLinkWidth *p = qdev_get_prop_ptr(obj, prop);
+    PCIExpLinkWidth *p = object_field_prop_ptr(obj, prop);
     int width;
 
     switch (*p) {
@@ -999,7 +999,7 @@ static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
                                    void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    PCIExpLinkWidth *p = qdev_get_prop_ptr(obj, prop);
+    PCIExpLinkWidth *p = object_field_prop_ptr(obj, prop);
     int width;
 
     if (!visit_type_enum(v, name, &width, prop->info->enum_table,
@@ -1050,7 +1050,7 @@ static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
 {
     Property *prop = opaque;
-    QemuUUID *uuid = qdev_get_prop_ptr(obj, prop);
+    QemuUUID *uuid = object_field_prop_ptr(obj, prop);
     char buffer[UUID_FMT_LEN + 1];
     char *p = buffer;
 
@@ -1065,7 +1065,7 @@ static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
 {
     Property *prop = opaque;
-    QemuUUID *uuid = qdev_get_prop_ptr(obj, prop);
+    QemuUUID *uuid = object_field_prop_ptr(obj, prop);
     char *str;
 
     if (!visit_type_str(v, name, &str, errp)) {
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index aeab4ae9b6..9aebd7b8a9 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -50,7 +50,7 @@ void qdev_prop_allow_set_link_before_realize(const Object *obj,
     }
 }
 
-void *qdev_get_prop_ptr(Object *obj, Property *prop)
+void *object_field_prop_ptr(Object *obj, Property *prop)
 {
     void *ptr = obj;
     ptr += prop->offset;
@@ -96,7 +96,7 @@ void field_prop_get_enum(Object *obj, Visitor *v, const char *name,
                          void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    int *ptr = qdev_get_prop_ptr(obj, prop);
+    int *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
 }
@@ -105,7 +105,7 @@ void field_prop_set_enum(Object *obj, Visitor *v, const char *name,
                          void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    int *ptr = qdev_get_prop_ptr(obj, prop);
+    int *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
 }
@@ -134,7 +134,7 @@ static uint32_t qdev_get_prop_mask(Property *prop)
 
 static void bit_prop_set(Object *obj, Property *props, bool val)
 {
-    uint32_t *p = qdev_get_prop_ptr(obj, props);
+    uint32_t *p = object_field_prop_ptr(obj, props);
     uint32_t mask = qdev_get_prop_mask(props);
     if (val) {
         *p |= mask;
@@ -147,7 +147,7 @@ static void prop_get_bit(Object *obj, Visitor *v, const char *name,
                          void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    uint32_t *p = qdev_get_prop_ptr(obj, prop);
+    uint32_t *p = object_field_prop_ptr(obj, prop);
     bool value = (*p & qdev_get_prop_mask(prop)) != 0;
 
     visit_type_bool(v, name, &value, errp);
@@ -188,7 +188,7 @@ static uint64_t qdev_get_prop_mask64(Property *prop)
 
 static void bit64_prop_set(Object *obj, Property *props, bool val)
 {
-    uint64_t *p = qdev_get_prop_ptr(obj, props);
+    uint64_t *p = object_field_prop_ptr(obj, props);
     uint64_t mask = qdev_get_prop_mask64(props);
     if (val) {
         *p |= mask;
@@ -201,7 +201,7 @@ static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
                            void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    uint64_t *p = qdev_get_prop_ptr(obj, prop);
+    uint64_t *p = object_field_prop_ptr(obj, prop);
     bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
 
     visit_type_bool(v, name, &value, errp);
@@ -233,7 +233,7 @@ static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
 {
     Property *prop = opaque;
-    bool *ptr = qdev_get_prop_ptr(obj, prop);
+    bool *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_bool(v, name, ptr, errp);
 }
@@ -242,7 +242,7 @@ static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
 {
     Property *prop = opaque;
-    bool *ptr = qdev_get_prop_ptr(obj, prop);
+    bool *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_bool(v, name, ptr, errp);
 }
@@ -260,7 +260,7 @@ static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
                       Error **errp)
 {
     Property *prop = opaque;
-    uint8_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint8_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_uint8(v, name, ptr, errp);
 }
@@ -269,7 +269,7 @@ static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
                       Error **errp)
 {
     Property *prop = opaque;
-    uint8_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint8_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_uint8(v, name, ptr, errp);
 }
@@ -299,7 +299,7 @@ static void get_uint16(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    uint16_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint16_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_uint16(v, name, ptr, errp);
 }
@@ -308,7 +308,7 @@ static void set_uint16(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    uint16_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint16_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_uint16(v, name, ptr, errp);
 }
@@ -326,7 +326,7 @@ static void get_uint32(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint32_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_uint32(v, name, ptr, errp);
 }
@@ -335,7 +335,7 @@ static void set_uint32(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint32_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_uint32(v, name, ptr, errp);
 }
@@ -344,7 +344,7 @@ void field_prop_get_int32(Object *obj, Visitor *v, const char *name,
                           void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    int32_t *ptr = qdev_get_prop_ptr(obj, prop);
+    int32_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_int32(v, name, ptr, errp);
 }
@@ -353,7 +353,7 @@ static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
                       Error **errp)
 {
     Property *prop = opaque;
-    int32_t *ptr = qdev_get_prop_ptr(obj, prop);
+    int32_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_int32(v, name, ptr, errp);
 }
@@ -378,7 +378,7 @@ static void get_uint64(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint64_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_uint64(v, name, ptr, errp);
 }
@@ -387,7 +387,7 @@ static void set_uint64(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint64_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_uint64(v, name, ptr, errp);
 }
@@ -396,7 +396,7 @@ static void get_int64(Object *obj, Visitor *v, const char *name,
                       void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    int64_t *ptr = qdev_get_prop_ptr(obj, prop);
+    int64_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_int64(v, name, ptr, errp);
 }
@@ -405,7 +405,7 @@ static void set_int64(Object *obj, Visitor *v, const char *name,
                       void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    int64_t *ptr = qdev_get_prop_ptr(obj, prop);
+    int64_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_int64(v, name, ptr, errp);
 }
@@ -429,14 +429,14 @@ const PropertyInfo qdev_prop_int64 = {
 static void release_string(Object *obj, const char *name, void *opaque)
 {
     Property *prop = opaque;
-    g_free(*(char **)qdev_get_prop_ptr(obj, prop));
+    g_free(*(char **)object_field_prop_ptr(obj, prop));
 }
 
 static void get_string(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    char **ptr = qdev_get_prop_ptr(obj, prop);
+    char **ptr = object_field_prop_ptr(obj, prop);
 
     if (!*ptr) {
         char *str = (char *)"";
@@ -450,7 +450,7 @@ static void set_string(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    char **ptr = qdev_get_prop_ptr(obj, prop);
+    char **ptr = object_field_prop_ptr(obj, prop);
     char *str;
 
     if (!visit_type_str(v, name, &str, errp)) {
@@ -484,7 +484,7 @@ void field_prop_get_size32(Object *obj, Visitor *v, const char *name,
                            void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint32_t *ptr = object_field_prop_ptr(obj, prop);
     uint64_t value = *ptr;
 
     visit_type_size(v, name, &value, errp);
@@ -494,7 +494,7 @@ static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
                        Error **errp)
 {
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint32_t *ptr = object_field_prop_ptr(obj, prop);
     uint64_t value;
 
     if (!visit_type_size(v, name, &value, errp)) {
@@ -531,7 +531,7 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
      */
     Property *prop = opaque;
     ObjectProperty *op = object_property_find_err(obj, name, &error_abort);
-    uint32_t *alenptr = qdev_get_prop_ptr(obj, prop);
+    uint32_t *alenptr = object_field_prop_ptr(obj, prop);
     void **arrayptr = (void *)obj + prop->arrayoffset;
     void *eltptr;
     const char *arrayname;
@@ -570,7 +570,7 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
          * being inside the device struct.
          */
         arrayprop->offset = eltptr - (void *)obj;
-        assert(qdev_get_prop_ptr(obj, arrayprop) == eltptr);
+        assert(object_field_prop_ptr(obj, arrayprop) == eltptr);
         object_property_add_field(obj, propname, arrayprop, op->allow_set);
     }
 }
@@ -760,7 +760,7 @@ static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
 {
     Property *prop = opaque;
-    uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint64_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_size(v, name, ptr, errp);
 }
@@ -769,7 +769,7 @@ static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
 {
     Property *prop = opaque;
-    uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint64_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_size(v, name, ptr, errp);
 }
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 496e2c5801..fe47751df4 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -2344,7 +2344,7 @@ static void get_css_devid(Object *obj, Visitor *v, const char *name,
                           void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    CssDevId *dev_id = qdev_get_prop_ptr(obj, prop);
+    CssDevId *dev_id = object_field_prop_ptr(obj, prop);
     char buffer[] = "xx.x.xxxx";
     char *p = buffer;
     int r;
@@ -2373,7 +2373,7 @@ static void set_css_devid(Object *obj, Visitor *v, const char *name,
                           void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    CssDevId *dev_id = qdev_get_prop_ptr(obj, prop);
+    CssDevId *dev_id = object_field_prop_ptr(obj, prop);
     char *str;
     int num, n1, n2;
     unsigned int cssid, ssid, devid;
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 54fac3851d..99b18d56ba 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -1323,7 +1323,7 @@ static void s390_pci_get_fid(Object *obj, Visitor *v, const char *name,
                          void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint32_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_uint32(v, name, ptr, errp);
 }
@@ -1333,7 +1333,7 @@ static void s390_pci_set_fid(Object *obj, Visitor *v, const char *name,
 {
     S390PCIBusDevice *zpci = S390_PCI_DEVICE(obj);
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint32_t *ptr = object_field_prop_ptr(obj, prop);
 
     if (!visit_type_uint32(v, name, ptr, errp)) {
         return;
diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
index 802979635c..fc8d63c850 100644
--- a/hw/vfio/pci-quirks.c
+++ b/hw/vfio/pci-quirks.c
@@ -1489,7 +1489,7 @@ static void get_nv_gpudirect_clique_id(Object *obj, Visitor *v,
                                        Error **errp)
 {
     Property *prop = opaque;
-    uint8_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint8_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_uint8(v, name, ptr, errp);
 }
@@ -1499,7 +1499,7 @@ static void set_nv_gpudirect_clique_id(Object *obj, Visitor *v,
                                        Error **errp)
 {
     Property *prop = opaque;
-    uint8_t value, *ptr = qdev_get_prop_ptr(obj, prop);
+    uint8_t value, *ptr = object_field_prop_ptr(obj, prop);
 
     if (!visit_type_uint8(v, name, &value, errp)) {
         return;
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 36/44] qdev: Rename qdev_get_prop_ptr() to object_field_prop_ptr()
@ 2020-11-04 16:00   ` Eduardo Habkost
  0 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 16:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, Paolo Bonzini, Igor Mammedov, Eric Blake,
	Stefan Berger, Markus Armbruster, Marc-André Lureau,
	John Snow, Philippe Mathieu-Daudé,
	Stefan Berger, Stefano Stabellini, Anthony Perard, Paul Durrant,
	Kevin Wolf, Max Reitz, Cornelia Huck, Halil Pasic,
	Christian Borntraeger, Richard Henderson, David Hildenbrand,
	Thomas Huth, Matthew Rosato, Alex Williamson, xen-devel,
	qemu-block, qemu-s390x

The function will be moved to common QOM code, as it is not
specific to TYPE_DEVICE anymore.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Changes v1 -> v2:
* Rename to object_field_prop_ptr() instead of object_static_prop_ptr()
---
Cc: Stefan Berger <stefanb@linux.vnet.ibm.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Paul Durrant <paul@xen.org>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: Cornelia Huck <cohuck@redhat.com>
Cc: Halil Pasic <pasic@linux.ibm.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: David Hildenbrand <david@redhat.com>
Cc: Thomas Huth <thuth@redhat.com>
Cc: Matthew Rosato <mjrosato@linux.ibm.com>
Cc: Alex Williamson <alex.williamson@redhat.com>
Cc: qemu-devel@nongnu.org
Cc: xen-devel@lists.xenproject.org
Cc: qemu-block@nongnu.org
Cc: qemu-s390x@nongnu.org
---
 include/hw/qdev-properties.h     |  2 +-
 backends/tpm/tpm_util.c          |  6 ++--
 hw/block/xen-block.c             |  4 +--
 hw/core/qdev-properties-system.c | 50 +++++++++++++-------------
 hw/core/qdev-properties.c        | 60 ++++++++++++++++----------------
 hw/s390x/css.c                   |  4 +--
 hw/s390x/s390-pci-bus.c          |  4 +--
 hw/vfio/pci-quirks.c             |  4 +--
 8 files changed, 67 insertions(+), 67 deletions(-)

diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 7f8d5fc206..2bec65c8e5 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -223,7 +223,7 @@ void qdev_prop_set_macaddr(DeviceState *dev, const char *name,
                            const uint8_t *value);
 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value);
 
-void *qdev_get_prop_ptr(Object *obj, Property *prop);
+void *object_field_prop_ptr(Object *obj, Property *prop);
 
 void qdev_prop_register_global(GlobalProperty *prop);
 const GlobalProperty *qdev_find_global_prop(Object *obj,
diff --git a/backends/tpm/tpm_util.c b/backends/tpm/tpm_util.c
index 0b07cf55ea..bb1ab34a75 100644
--- a/backends/tpm/tpm_util.c
+++ b/backends/tpm/tpm_util.c
@@ -35,7 +35,7 @@
 static void get_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
 {
-    TPMBackend **be = qdev_get_prop_ptr(obj, opaque);
+    TPMBackend **be = object_field_prop_ptr(obj, opaque);
     char *p;
 
     p = g_strdup(*be ? (*be)->id : "");
@@ -47,7 +47,7 @@ static void set_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
 {
     Property *prop = opaque;
-    TPMBackend *s, **be = qdev_get_prop_ptr(obj, prop);
+    TPMBackend *s, **be = object_field_prop_ptr(obj, prop);
     char *str;
 
     if (!visit_type_str(v, name, &str, errp)) {
@@ -67,7 +67,7 @@ static void set_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
 static void release_tpm(Object *obj, const char *name, void *opaque)
 {
     Property *prop = opaque;
-    TPMBackend **be = qdev_get_prop_ptr(obj, prop);
+    TPMBackend **be = object_field_prop_ptr(obj, prop);
 
     if (*be) {
         tpm_backend_reset(*be);
diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
index bd1aef63a7..718d886e5c 100644
--- a/hw/block/xen-block.c
+++ b/hw/block/xen-block.c
@@ -336,7 +336,7 @@ static void xen_block_get_vdev(Object *obj, Visitor *v, const char *name,
                                void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    XenBlockVdev *vdev = qdev_get_prop_ptr(obj, prop);
+    XenBlockVdev *vdev = object_field_prop_ptr(obj, prop);
     char *str;
 
     switch (vdev->type) {
@@ -396,7 +396,7 @@ static void xen_block_set_vdev(Object *obj, Visitor *v, const char *name,
                                void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    XenBlockVdev *vdev = qdev_get_prop_ptr(obj, prop);
+    XenBlockVdev *vdev = object_field_prop_ptr(obj, prop);
     char *str, *p;
     const char *end;
 
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 96a0bc5109..8781b856d3 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -62,7 +62,7 @@ static void get_drive(Object *obj, Visitor *v, const char *name, void *opaque,
                       Error **errp)
 {
     Property *prop = opaque;
-    void **ptr = qdev_get_prop_ptr(obj, prop);
+    void **ptr = object_field_prop_ptr(obj, prop);
     const char *value;
     char *p;
 
@@ -88,7 +88,7 @@ static void set_drive_helper(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    void **ptr = qdev_get_prop_ptr(obj, prop);
+    void **ptr = object_field_prop_ptr(obj, prop);
     char *str;
     BlockBackend *blk;
     bool blk_created = false;
@@ -181,7 +181,7 @@ static void release_drive(Object *obj, const char *name, void *opaque)
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    BlockBackend **ptr = qdev_get_prop_ptr(obj, prop);
+    BlockBackend **ptr = object_field_prop_ptr(obj, prop);
 
     if (*ptr) {
         AioContext *ctx = blk_get_aio_context(*ptr);
@@ -214,7 +214,7 @@ const PropertyInfo qdev_prop_drive_iothread = {
 static void get_chr(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
 {
-    CharBackend *be = qdev_get_prop_ptr(obj, opaque);
+    CharBackend *be = object_field_prop_ptr(obj, opaque);
     char *p;
 
     p = g_strdup(be->chr && be->chr->label ? be->chr->label : "");
@@ -226,7 +226,7 @@ static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
 {
     Property *prop = opaque;
-    CharBackend *be = qdev_get_prop_ptr(obj, prop);
+    CharBackend *be = object_field_prop_ptr(obj, prop);
     Chardev *s;
     char *str;
 
@@ -262,7 +262,7 @@ static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
 static void release_chr(Object *obj, const char *name, void *opaque)
 {
     Property *prop = opaque;
-    CharBackend *be = qdev_get_prop_ptr(obj, prop);
+    CharBackend *be = object_field_prop_ptr(obj, prop);
 
     qemu_chr_fe_deinit(be, false);
 }
@@ -286,7 +286,7 @@ static void get_mac(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
 {
     Property *prop = opaque;
-    MACAddr *mac = qdev_get_prop_ptr(obj, prop);
+    MACAddr *mac = object_field_prop_ptr(obj, prop);
     char buffer[2 * 6 + 5 + 1];
     char *p = buffer;
 
@@ -301,7 +301,7 @@ static void set_mac(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
 {
     Property *prop = opaque;
-    MACAddr *mac = qdev_get_prop_ptr(obj, prop);
+    MACAddr *mac = object_field_prop_ptr(obj, prop);
     int i, pos;
     char *str;
     const char *p;
@@ -363,7 +363,7 @@ static void get_netdev(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    NICPeers *peers_ptr = qdev_get_prop_ptr(obj, prop);
+    NICPeers *peers_ptr = object_field_prop_ptr(obj, prop);
     char *p = g_strdup(peers_ptr->ncs[0] ? peers_ptr->ncs[0]->name : "");
 
     visit_type_str(v, name, &p, errp);
@@ -374,7 +374,7 @@ static void set_netdev(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    NICPeers *peers_ptr = qdev_get_prop_ptr(obj, prop);
+    NICPeers *peers_ptr = object_field_prop_ptr(obj, prop);
     NetClientState **ncs = peers_ptr->ncs;
     NetClientState *peers[MAX_QUEUE_NUM];
     int queues, err = 0, i = 0;
@@ -436,7 +436,7 @@ static void get_audiodev(Object *obj, Visitor *v, const char* name,
                          void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    QEMUSoundCard *card = qdev_get_prop_ptr(obj, prop);
+    QEMUSoundCard *card = object_field_prop_ptr(obj, prop);
     char *p = g_strdup(audio_get_id(card));
 
     visit_type_str(v, name, &p, errp);
@@ -447,7 +447,7 @@ static void set_audiodev(Object *obj, Visitor *v, const char* name,
                          void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    QEMUSoundCard *card = qdev_get_prop_ptr(obj, prop);
+    QEMUSoundCard *card = object_field_prop_ptr(obj, prop);
     AudioState *state;
     int err = 0;
     char *str;
@@ -549,7 +549,7 @@ static void set_blocksize(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint32_t *ptr = object_field_prop_ptr(obj, prop);
     uint64_t value;
     Error *local_err = NULL;
 
@@ -637,7 +637,7 @@ static void get_reserved_region(Object *obj, Visitor *v, const char *name,
                                 void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    ReservedRegion *rr = qdev_get_prop_ptr(obj, prop);
+    ReservedRegion *rr = object_field_prop_ptr(obj, prop);
     char buffer[64];
     char *p = buffer;
     int rc;
@@ -653,7 +653,7 @@ static void set_reserved_region(Object *obj, Visitor *v, const char *name,
                                 void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    ReservedRegion *rr = qdev_get_prop_ptr(obj, prop);
+    ReservedRegion *rr = object_field_prop_ptr(obj, prop);
     Error *local_err = NULL;
     const char *endptr;
     char *str;
@@ -715,7 +715,7 @@ static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
                           void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    int32_t value, *ptr = qdev_get_prop_ptr(obj, prop);
+    int32_t value, *ptr = object_field_prop_ptr(obj, prop);
     unsigned int slot, fn, n;
     char *str;
 
@@ -753,7 +753,7 @@ invalid:
 static int print_pci_devfn(Object *obj, Property *prop, char *dest,
                            size_t len)
 {
-    int32_t *ptr = qdev_get_prop_ptr(obj, prop);
+    int32_t *ptr = object_field_prop_ptr(obj, prop);
 
     if (*ptr == -1) {
         return snprintf(dest, len, "<unset>");
@@ -777,7 +777,7 @@ static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
                                  void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(obj, prop);
+    PCIHostDeviceAddress *addr = object_field_prop_ptr(obj, prop);
     char buffer[] = "ffff:ff:ff.f";
     char *p = buffer;
     int rc = 0;
@@ -803,7 +803,7 @@ static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
                                  void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(obj, prop);
+    PCIHostDeviceAddress *addr = object_field_prop_ptr(obj, prop);
     char *str, *p;
     const char *e;
     unsigned long val;
@@ -892,7 +892,7 @@ static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
                                    void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    PCIExpLinkSpeed *p = qdev_get_prop_ptr(obj, prop);
+    PCIExpLinkSpeed *p = object_field_prop_ptr(obj, prop);
     int speed;
 
     switch (*p) {
@@ -920,7 +920,7 @@ static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
                                    void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    PCIExpLinkSpeed *p = qdev_get_prop_ptr(obj, prop);
+    PCIExpLinkSpeed *p = object_field_prop_ptr(obj, prop);
     int speed;
 
     if (!visit_type_enum(v, name, &speed, prop->info->enum_table,
@@ -962,7 +962,7 @@ static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
                                    void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    PCIExpLinkWidth *p = qdev_get_prop_ptr(obj, prop);
+    PCIExpLinkWidth *p = object_field_prop_ptr(obj, prop);
     int width;
 
     switch (*p) {
@@ -999,7 +999,7 @@ static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
                                    void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    PCIExpLinkWidth *p = qdev_get_prop_ptr(obj, prop);
+    PCIExpLinkWidth *p = object_field_prop_ptr(obj, prop);
     int width;
 
     if (!visit_type_enum(v, name, &width, prop->info->enum_table,
@@ -1050,7 +1050,7 @@ static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
 {
     Property *prop = opaque;
-    QemuUUID *uuid = qdev_get_prop_ptr(obj, prop);
+    QemuUUID *uuid = object_field_prop_ptr(obj, prop);
     char buffer[UUID_FMT_LEN + 1];
     char *p = buffer;
 
@@ -1065,7 +1065,7 @@ static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
                     Error **errp)
 {
     Property *prop = opaque;
-    QemuUUID *uuid = qdev_get_prop_ptr(obj, prop);
+    QemuUUID *uuid = object_field_prop_ptr(obj, prop);
     char *str;
 
     if (!visit_type_str(v, name, &str, errp)) {
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index aeab4ae9b6..9aebd7b8a9 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -50,7 +50,7 @@ void qdev_prop_allow_set_link_before_realize(const Object *obj,
     }
 }
 
-void *qdev_get_prop_ptr(Object *obj, Property *prop)
+void *object_field_prop_ptr(Object *obj, Property *prop)
 {
     void *ptr = obj;
     ptr += prop->offset;
@@ -96,7 +96,7 @@ void field_prop_get_enum(Object *obj, Visitor *v, const char *name,
                          void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    int *ptr = qdev_get_prop_ptr(obj, prop);
+    int *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
 }
@@ -105,7 +105,7 @@ void field_prop_set_enum(Object *obj, Visitor *v, const char *name,
                          void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    int *ptr = qdev_get_prop_ptr(obj, prop);
+    int *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
 }
@@ -134,7 +134,7 @@ static uint32_t qdev_get_prop_mask(Property *prop)
 
 static void bit_prop_set(Object *obj, Property *props, bool val)
 {
-    uint32_t *p = qdev_get_prop_ptr(obj, props);
+    uint32_t *p = object_field_prop_ptr(obj, props);
     uint32_t mask = qdev_get_prop_mask(props);
     if (val) {
         *p |= mask;
@@ -147,7 +147,7 @@ static void prop_get_bit(Object *obj, Visitor *v, const char *name,
                          void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    uint32_t *p = qdev_get_prop_ptr(obj, prop);
+    uint32_t *p = object_field_prop_ptr(obj, prop);
     bool value = (*p & qdev_get_prop_mask(prop)) != 0;
 
     visit_type_bool(v, name, &value, errp);
@@ -188,7 +188,7 @@ static uint64_t qdev_get_prop_mask64(Property *prop)
 
 static void bit64_prop_set(Object *obj, Property *props, bool val)
 {
-    uint64_t *p = qdev_get_prop_ptr(obj, props);
+    uint64_t *p = object_field_prop_ptr(obj, props);
     uint64_t mask = qdev_get_prop_mask64(props);
     if (val) {
         *p |= mask;
@@ -201,7 +201,7 @@ static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
                            void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    uint64_t *p = qdev_get_prop_ptr(obj, prop);
+    uint64_t *p = object_field_prop_ptr(obj, prop);
     bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
 
     visit_type_bool(v, name, &value, errp);
@@ -233,7 +233,7 @@ static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
 {
     Property *prop = opaque;
-    bool *ptr = qdev_get_prop_ptr(obj, prop);
+    bool *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_bool(v, name, ptr, errp);
 }
@@ -242,7 +242,7 @@ static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
 {
     Property *prop = opaque;
-    bool *ptr = qdev_get_prop_ptr(obj, prop);
+    bool *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_bool(v, name, ptr, errp);
 }
@@ -260,7 +260,7 @@ static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
                       Error **errp)
 {
     Property *prop = opaque;
-    uint8_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint8_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_uint8(v, name, ptr, errp);
 }
@@ -269,7 +269,7 @@ static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
                       Error **errp)
 {
     Property *prop = opaque;
-    uint8_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint8_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_uint8(v, name, ptr, errp);
 }
@@ -299,7 +299,7 @@ static void get_uint16(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    uint16_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint16_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_uint16(v, name, ptr, errp);
 }
@@ -308,7 +308,7 @@ static void set_uint16(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    uint16_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint16_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_uint16(v, name, ptr, errp);
 }
@@ -326,7 +326,7 @@ static void get_uint32(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint32_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_uint32(v, name, ptr, errp);
 }
@@ -335,7 +335,7 @@ static void set_uint32(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint32_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_uint32(v, name, ptr, errp);
 }
@@ -344,7 +344,7 @@ void field_prop_get_int32(Object *obj, Visitor *v, const char *name,
                           void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    int32_t *ptr = qdev_get_prop_ptr(obj, prop);
+    int32_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_int32(v, name, ptr, errp);
 }
@@ -353,7 +353,7 @@ static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
                       Error **errp)
 {
     Property *prop = opaque;
-    int32_t *ptr = qdev_get_prop_ptr(obj, prop);
+    int32_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_int32(v, name, ptr, errp);
 }
@@ -378,7 +378,7 @@ static void get_uint64(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint64_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_uint64(v, name, ptr, errp);
 }
@@ -387,7 +387,7 @@ static void set_uint64(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint64_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_uint64(v, name, ptr, errp);
 }
@@ -396,7 +396,7 @@ static void get_int64(Object *obj, Visitor *v, const char *name,
                       void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    int64_t *ptr = qdev_get_prop_ptr(obj, prop);
+    int64_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_int64(v, name, ptr, errp);
 }
@@ -405,7 +405,7 @@ static void set_int64(Object *obj, Visitor *v, const char *name,
                       void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    int64_t *ptr = qdev_get_prop_ptr(obj, prop);
+    int64_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_int64(v, name, ptr, errp);
 }
@@ -429,14 +429,14 @@ const PropertyInfo qdev_prop_int64 = {
 static void release_string(Object *obj, const char *name, void *opaque)
 {
     Property *prop = opaque;
-    g_free(*(char **)qdev_get_prop_ptr(obj, prop));
+    g_free(*(char **)object_field_prop_ptr(obj, prop));
 }
 
 static void get_string(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    char **ptr = qdev_get_prop_ptr(obj, prop);
+    char **ptr = object_field_prop_ptr(obj, prop);
 
     if (!*ptr) {
         char *str = (char *)"";
@@ -450,7 +450,7 @@ static void set_string(Object *obj, Visitor *v, const char *name,
                        void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    char **ptr = qdev_get_prop_ptr(obj, prop);
+    char **ptr = object_field_prop_ptr(obj, prop);
     char *str;
 
     if (!visit_type_str(v, name, &str, errp)) {
@@ -484,7 +484,7 @@ void field_prop_get_size32(Object *obj, Visitor *v, const char *name,
                            void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint32_t *ptr = object_field_prop_ptr(obj, prop);
     uint64_t value = *ptr;
 
     visit_type_size(v, name, &value, errp);
@@ -494,7 +494,7 @@ static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
                        Error **errp)
 {
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint32_t *ptr = object_field_prop_ptr(obj, prop);
     uint64_t value;
 
     if (!visit_type_size(v, name, &value, errp)) {
@@ -531,7 +531,7 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
      */
     Property *prop = opaque;
     ObjectProperty *op = object_property_find_err(obj, name, &error_abort);
-    uint32_t *alenptr = qdev_get_prop_ptr(obj, prop);
+    uint32_t *alenptr = object_field_prop_ptr(obj, prop);
     void **arrayptr = (void *)obj + prop->arrayoffset;
     void *eltptr;
     const char *arrayname;
@@ -570,7 +570,7 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
          * being inside the device struct.
          */
         arrayprop->offset = eltptr - (void *)obj;
-        assert(qdev_get_prop_ptr(obj, arrayprop) == eltptr);
+        assert(object_field_prop_ptr(obj, arrayprop) == eltptr);
         object_property_add_field(obj, propname, arrayprop, op->allow_set);
     }
 }
@@ -760,7 +760,7 @@ static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
 {
     Property *prop = opaque;
-    uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint64_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_size(v, name, ptr, errp);
 }
@@ -769,7 +769,7 @@ static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
                      Error **errp)
 {
     Property *prop = opaque;
-    uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint64_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_size(v, name, ptr, errp);
 }
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 496e2c5801..fe47751df4 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -2344,7 +2344,7 @@ static void get_css_devid(Object *obj, Visitor *v, const char *name,
                           void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    CssDevId *dev_id = qdev_get_prop_ptr(obj, prop);
+    CssDevId *dev_id = object_field_prop_ptr(obj, prop);
     char buffer[] = "xx.x.xxxx";
     char *p = buffer;
     int r;
@@ -2373,7 +2373,7 @@ static void set_css_devid(Object *obj, Visitor *v, const char *name,
                           void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    CssDevId *dev_id = qdev_get_prop_ptr(obj, prop);
+    CssDevId *dev_id = object_field_prop_ptr(obj, prop);
     char *str;
     int num, n1, n2;
     unsigned int cssid, ssid, devid;
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 54fac3851d..99b18d56ba 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -1323,7 +1323,7 @@ static void s390_pci_get_fid(Object *obj, Visitor *v, const char *name,
                          void *opaque, Error **errp)
 {
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint32_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_uint32(v, name, ptr, errp);
 }
@@ -1333,7 +1333,7 @@ static void s390_pci_set_fid(Object *obj, Visitor *v, const char *name,
 {
     S390PCIBusDevice *zpci = S390_PCI_DEVICE(obj);
     Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint32_t *ptr = object_field_prop_ptr(obj, prop);
 
     if (!visit_type_uint32(v, name, ptr, errp)) {
         return;
diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
index 802979635c..fc8d63c850 100644
--- a/hw/vfio/pci-quirks.c
+++ b/hw/vfio/pci-quirks.c
@@ -1489,7 +1489,7 @@ static void get_nv_gpudirect_clique_id(Object *obj, Visitor *v,
                                        Error **errp)
 {
     Property *prop = opaque;
-    uint8_t *ptr = qdev_get_prop_ptr(obj, prop);
+    uint8_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_uint8(v, name, ptr, errp);
 }
@@ -1499,7 +1499,7 @@ static void set_nv_gpudirect_clique_id(Object *obj, Visitor *v,
                                        Error **errp)
 {
     Property *prop = opaque;
-    uint8_t value, *ptr = qdev_get_prop_ptr(obj, prop);
+    uint8_t value, *ptr = object_field_prop_ptr(obj, prop);
 
     if (!visit_type_uint8(v, name, &value, errp)) {
         return;
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 37/44] qdev: Move qdev_prop_tpm declaration to tpm_prop.h
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (35 preceding siblings ...)
  2020-11-04 16:00   ` Eduardo Habkost
@ 2020-11-04 16:00 ` Eduardo Habkost
  2020-11-05 18:50   ` Stefan Berger
  2020-11-04 16:00 ` [PATCH v2 38/44] qdev: Rename qdev_prop_* to prop_info_* Eduardo Habkost
                   ` (8 subsequent siblings)
  45 siblings, 1 reply; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 16:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, Stefan Berger, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

Move the variable declaration close to the macro that uses it.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Cc: Stefan Berger <stefanb@linux.vnet.ibm.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 hw/tpm/tpm_prop.h            | 2 ++
 include/hw/qdev-properties.h | 1 -
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/tpm/tpm_prop.h b/hw/tpm/tpm_prop.h
index 85e1ae5718..871af584b7 100644
--- a/hw/tpm/tpm_prop.h
+++ b/hw/tpm/tpm_prop.h
@@ -25,6 +25,8 @@
 #include "sysemu/tpm_backend.h"
 #include "hw/qdev-properties.h"
 
+extern const PropertyInfo qdev_prop_tpm;
+
 #define DEFINE_PROP_TPMBE(_n, _s, _f)                     \
     DEFINE_PROP(_n, _s, _f, qdev_prop_tpm, TPMBackend *)
 
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 2bec65c8e5..c3eaf5e3c5 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -63,7 +63,6 @@ extern const PropertyInfo qdev_prop_uint64;
 extern const PropertyInfo qdev_prop_int64;
 extern const PropertyInfo qdev_prop_size;
 extern const PropertyInfo qdev_prop_string;
-extern const PropertyInfo qdev_prop_tpm;
 extern const PropertyInfo qdev_prop_on_off_auto;
 extern const PropertyInfo qdev_prop_size32;
 extern const PropertyInfo qdev_prop_arraylen;
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 38/44] qdev: Rename qdev_prop_* to prop_info_*
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (36 preceding siblings ...)
  2020-11-04 16:00 ` [PATCH v2 37/44] qdev: Move qdev_prop_tpm declaration to tpm_prop.h Eduardo Habkost
@ 2020-11-04 16:00 ` Eduardo Habkost
  2020-11-04 16:00 ` [PATCH v2 39/44] qdev: PROP_* macros Eduardo Habkost
                   ` (7 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 16:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Dmitry Fleytman, Daniel P. Berrange,
	Yoshinori Sato, John Snow, Jason Wang, Mark Cave-Ayland,
	Markus Armbruster, Philippe Mathieu-Daudé,
	Marc-André Lureau, qemu-arm, Igor Mammedov, Paolo Bonzini,
	Artyom Tarasenko, Stefan Berger

The basic property types in qdev-properties.c are not going to be
qdev-specific anymore.  Rename the variables to prop_info_*.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Changes v1 -> v2:
* Redone patch after moving UUID property to qdev-properties-system.c
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc: Dmitry Fleytman <dmitry.fleytman@gmail.com>
Cc: Jason Wang <jasowang@redhat.com>
Cc: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Cc: Artyom Tarasenko <atar4qemu@gmail.com>
Cc: qemu-devel@nongnu.org
Cc: qemu-arm@nongnu.org
---
 include/hw/qdev-properties.h | 62 ++++++++++++++++++------------------
 hw/core/qdev-properties.c    | 36 ++++++++++-----------
 hw/intc/arm_gicv3_common.c   |  2 +-
 hw/intc/rx_icu.c             |  4 +--
 hw/misc/arm_sysctl.c         |  4 +--
 hw/net/e1000e.c              |  6 ++--
 target/arm/cpu.c             |  2 +-
 target/sparc/cpu.c           |  2 +-
 8 files changed, 59 insertions(+), 59 deletions(-)

diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index c3eaf5e3c5..0a44a91e6e 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -51,22 +51,22 @@ struct PropertyInfo {
 
 /*** qdev-properties.c ***/
 
-extern const PropertyInfo qdev_prop_bit;
-extern const PropertyInfo qdev_prop_bit64;
-extern const PropertyInfo qdev_prop_bool;
-extern const PropertyInfo qdev_prop_enum;
-extern const PropertyInfo qdev_prop_uint8;
-extern const PropertyInfo qdev_prop_uint16;
-extern const PropertyInfo qdev_prop_uint32;
-extern const PropertyInfo qdev_prop_int32;
-extern const PropertyInfo qdev_prop_uint64;
-extern const PropertyInfo qdev_prop_int64;
-extern const PropertyInfo qdev_prop_size;
-extern const PropertyInfo qdev_prop_string;
-extern const PropertyInfo qdev_prop_on_off_auto;
-extern const PropertyInfo qdev_prop_size32;
-extern const PropertyInfo qdev_prop_arraylen;
-extern const PropertyInfo qdev_prop_link;
+extern const PropertyInfo prop_info_bit;
+extern const PropertyInfo prop_info_bit64;
+extern const PropertyInfo prop_info_bool;
+extern const PropertyInfo prop_info_enum;
+extern const PropertyInfo prop_info_uint8;
+extern const PropertyInfo prop_info_uint16;
+extern const PropertyInfo prop_info_uint32;
+extern const PropertyInfo prop_info_int32;
+extern const PropertyInfo prop_info_uint64;
+extern const PropertyInfo prop_info_int64;
+extern const PropertyInfo prop_info_size;
+extern const PropertyInfo prop_info_string;
+extern const PropertyInfo prop_info_on_off_auto;
+extern const PropertyInfo prop_info_size32;
+extern const PropertyInfo prop_info_arraylen;
+extern const PropertyInfo prop_info_link;
 
 #define DEFINE_PROP(_name, _state, _field, _prop, _type, ...) {  \
         .qdev_prop_name      = (_name),                          \
@@ -85,7 +85,7 @@ extern const PropertyInfo qdev_prop_link;
     DEFINE_PROP(_name, _state, _field, _prop, _type)
 
 #define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval)   \
-    DEFINE_PROP(_name, _state, _field, qdev_prop_bit, uint32_t, \
+    DEFINE_PROP(_name, _state, _field, prop_info_bit, uint32_t, \
                 .bitnr       = (_bit),                          \
                 .set_default = true,                            \
                 .defval.u    = (bool)_defval)
@@ -99,13 +99,13 @@ extern const PropertyInfo qdev_prop_link;
     DEFINE_PROP(_name, _state, _field, _prop, _type)
 
 #define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval)   \
-    DEFINE_PROP(_name, _state, _field, qdev_prop_bit64, uint64_t, \
+    DEFINE_PROP(_name, _state, _field, prop_info_bit64, uint64_t, \
                 .bitnr    = (_bit),                               \
                 .set_default = true,                              \
                 .defval.u  = (bool)_defval)
 
 #define DEFINE_PROP_BOOL(_name, _state, _field, _defval)     \
-    DEFINE_PROP(_name, _state, _field, qdev_prop_bool, bool, \
+    DEFINE_PROP(_name, _state, _field, prop_info_bool, bool, \
                 .set_default = true,                         \
                 .defval.u    = (bool)_defval)
 
@@ -138,7 +138,7 @@ extern const PropertyInfo qdev_prop_link;
 #define DEFINE_PROP_ARRAY(_name, _state, _field,               \
                           _arrayfield, _arrayprop, _arraytype) \
     DEFINE_PROP((PROP_ARRAY_LEN_PREFIX _name),                 \
-                _state, _field, qdev_prop_arraylen, uint32_t,  \
+                _state, _field, prop_info_arraylen, uint32_t,  \
                 .set_default = true,                           \
                 .defval.u = 0,                                 \
                 .arrayinfo = &(_arrayprop),                    \
@@ -146,29 +146,29 @@ extern const PropertyInfo qdev_prop_link;
                 .arrayoffset = offsetof(_state, _arrayfield))
 
 #define DEFINE_PROP_LINK(_name, _state, _field, _type, _ptr_type)     \
-    DEFINE_PROP(_name, _state, _field, qdev_prop_link, _ptr_type,     \
+    DEFINE_PROP(_name, _state, _field, prop_info_link, _ptr_type,     \
                 .link_type  = _type)
 
 #define DEFINE_PROP_UINT8(_n, _s, _f, _d)                       \
-    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, qdev_prop_uint8, uint8_t)
+    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint8, uint8_t)
 #define DEFINE_PROP_UINT16(_n, _s, _f, _d)                      \
-    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, qdev_prop_uint16, uint16_t)
+    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint16, uint16_t)
 #define DEFINE_PROP_UINT32(_n, _s, _f, _d)                      \
-    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, qdev_prop_uint32, uint32_t)
+    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint32, uint32_t)
 #define DEFINE_PROP_INT32(_n, _s, _f, _d)                      \
-    DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_int32, int32_t)
+    DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_int32, int32_t)
 #define DEFINE_PROP_UINT64(_n, _s, _f, _d)                      \
-    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, qdev_prop_uint64, uint64_t)
+    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint64, uint64_t)
 #define DEFINE_PROP_INT64(_n, _s, _f, _d)                      \
-    DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_int64, int64_t)
+    DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_int64, int64_t)
 #define DEFINE_PROP_SIZE(_n, _s, _f, _d)                       \
-    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, qdev_prop_size, uint64_t)
+    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_size, uint64_t)
 #define DEFINE_PROP_STRING(_n, _s, _f)             \
-    DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*)
+    DEFINE_PROP(_n, _s, _f, prop_info_string, char*)
 #define DEFINE_PROP_ON_OFF_AUTO(_n, _s, _f, _d) \
-    DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_on_off_auto, OnOffAuto)
+    DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_on_off_auto, OnOffAuto)
 #define DEFINE_PROP_SIZE32(_n, _s, _f, _d)                       \
-    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, qdev_prop_size32, uint32_t)
+    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_size32, uint32_t)
 
 #define DEFINE_PROP_END_OF_LIST()               \
     {}
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 9aebd7b8a9..64b803a200 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -117,7 +117,7 @@ void field_prop_set_default_value_enum(ObjectProperty *op,
         qapi_enum_lookup(prop->info->enum_table, prop->defval.i));
 }
 
-const PropertyInfo qdev_prop_enum = {
+const PropertyInfo prop_info_enum = {
     .name  = "enum",
     .get   = field_prop_get_enum,
     .set   = field_prop_set_enum,
@@ -128,7 +128,7 @@ const PropertyInfo qdev_prop_enum = {
 
 static uint32_t qdev_get_prop_mask(Property *prop)
 {
-    assert(prop->info == &qdev_prop_bit);
+    assert(prop->info == &prop_info_bit);
     return 0x1 << prop->bitnr;
 }
 
@@ -170,7 +170,7 @@ static void set_default_value_bool(ObjectProperty *op, const Property *prop)
     object_property_set_default_bool(op, prop->defval.u);
 }
 
-const PropertyInfo qdev_prop_bit = {
+const PropertyInfo prop_info_bit = {
     .name  = "bool",
     .description = "on/off",
     .get   = prop_get_bit,
@@ -182,7 +182,7 @@ const PropertyInfo qdev_prop_bit = {
 
 static uint64_t qdev_get_prop_mask64(Property *prop)
 {
-    assert(prop->info == &qdev_prop_bit64);
+    assert(prop->info == &prop_info_bit64);
     return 0x1ull << prop->bitnr;
 }
 
@@ -219,7 +219,7 @@ static void prop_set_bit64(Object *obj, Visitor *v, const char *name,
     bit64_prop_set(obj, prop, value);
 }
 
-const PropertyInfo qdev_prop_bit64 = {
+const PropertyInfo prop_info_bit64 = {
     .name  = "bool",
     .description = "on/off",
     .get   = prop_get_bit64,
@@ -247,7 +247,7 @@ static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
     visit_type_bool(v, name, ptr, errp);
 }
 
-const PropertyInfo qdev_prop_bool = {
+const PropertyInfo prop_info_bool = {
     .name  = "bool",
     .get   = get_bool,
     .set   = set_bool,
@@ -286,7 +286,7 @@ void field_prop_set_default_value_uint(ObjectProperty *op,
     object_property_set_default_uint(op, prop->defval.u);
 }
 
-const PropertyInfo qdev_prop_uint8 = {
+const PropertyInfo prop_info_uint8 = {
     .name  = "uint8",
     .get   = get_uint8,
     .set   = set_uint8,
@@ -313,7 +313,7 @@ static void set_uint16(Object *obj, Visitor *v, const char *name,
     visit_type_uint16(v, name, ptr, errp);
 }
 
-const PropertyInfo qdev_prop_uint16 = {
+const PropertyInfo prop_info_uint16 = {
     .name  = "uint16",
     .get   = get_uint16,
     .set   = set_uint16,
@@ -358,14 +358,14 @@ static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
     visit_type_int32(v, name, ptr, errp);
 }
 
-const PropertyInfo qdev_prop_uint32 = {
+const PropertyInfo prop_info_uint32 = {
     .name  = "uint32",
     .get   = get_uint32,
     .set   = set_uint32,
     .set_default_value = field_prop_set_default_value_uint,
 };
 
-const PropertyInfo qdev_prop_int32 = {
+const PropertyInfo prop_info_int32 = {
     .name  = "int32",
     .get   = field_prop_get_int32,
     .set   = set_int32,
@@ -410,14 +410,14 @@ static void set_int64(Object *obj, Visitor *v, const char *name,
     visit_type_int64(v, name, ptr, errp);
 }
 
-const PropertyInfo qdev_prop_uint64 = {
+const PropertyInfo prop_info_uint64 = {
     .name  = "uint64",
     .get   = get_uint64,
     .set   = set_uint64,
     .set_default_value = field_prop_set_default_value_uint,
 };
 
-const PropertyInfo qdev_prop_int64 = {
+const PropertyInfo prop_info_int64 = {
     .name  = "int64",
     .get   = get_int64,
     .set   = set_int64,
@@ -460,7 +460,7 @@ static void set_string(Object *obj, Visitor *v, const char *name,
     *ptr = str;
 }
 
-const PropertyInfo qdev_prop_string = {
+const PropertyInfo prop_info_string = {
     .name  = "str",
     .release = release_string,
     .get   = get_string,
@@ -469,7 +469,7 @@ const PropertyInfo qdev_prop_string = {
 
 /* --- on/off/auto --- */
 
-const PropertyInfo qdev_prop_on_off_auto = {
+const PropertyInfo prop_info_on_off_auto = {
     .name = "OnOffAuto",
     .description = "on/off/auto",
     .enum_table = &OnOffAuto_lookup,
@@ -512,7 +512,7 @@ static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
     *ptr = value;
 }
 
-const PropertyInfo qdev_prop_size32 = {
+const PropertyInfo prop_info_size32 = {
     .name  = "size",
     .get = field_prop_get_size32,
     .set = set_size32,
@@ -575,7 +575,7 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
     }
 }
 
-const PropertyInfo qdev_prop_arraylen = {
+const PropertyInfo prop_info_arraylen = {
     .name = "uint32",
     .get = get_uint32,
     .set = set_prop_arraylen,
@@ -774,7 +774,7 @@ static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
     visit_type_size(v, name, ptr, errp);
 }
 
-const PropertyInfo qdev_prop_size = {
+const PropertyInfo prop_info_size = {
     .name  = "size",
     .get = get_size,
     .set = set_size,
@@ -796,7 +796,7 @@ static ObjectProperty *create_link_property(ObjectClass *oc, const char *name,
                                           OBJ_PROP_LINK_STRONG);
 }
 
-const PropertyInfo qdev_prop_link = {
+const PropertyInfo prop_info_link = {
     .name = "link",
     .create = create_link_property,
 };
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
index 58ef65f589..6d06b4d4c5 100644
--- a/hw/intc/arm_gicv3_common.c
+++ b/hw/intc/arm_gicv3_common.c
@@ -496,7 +496,7 @@ static Property arm_gicv3_common_properties[] = {
     DEFINE_PROP_UINT32("revision", GICv3State, revision, 3),
     DEFINE_PROP_BOOL("has-security-extensions", GICv3State, security_extn, 0),
     DEFINE_PROP_ARRAY("redist-region-count", GICv3State, nb_redist_regions,
-                      redist_region_count, qdev_prop_uint32, uint32_t),
+                      redist_region_count, prop_info_uint32, uint32_t),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/intc/rx_icu.c b/hw/intc/rx_icu.c
index 94e17a9dea..823160d9a8 100644
--- a/hw/intc/rx_icu.c
+++ b/hw/intc/rx_icu.c
@@ -365,9 +365,9 @@ static const VMStateDescription vmstate_rxicu = {
 
 static Property rxicu_properties[] = {
     DEFINE_PROP_ARRAY("ipr-map", RXICUState, nr_irqs, map,
-                      qdev_prop_uint8, uint8_t),
+                      prop_info_uint8, uint8_t),
     DEFINE_PROP_ARRAY("trigger-level", RXICUState, nr_sense, init_sense,
-                      qdev_prop_uint8, uint8_t),
+                      prop_info_uint8, uint8_t),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/misc/arm_sysctl.c b/hw/misc/arm_sysctl.c
index 42d4693854..634f3d916f 100644
--- a/hw/misc/arm_sysctl.c
+++ b/hw/misc/arm_sysctl.c
@@ -628,10 +628,10 @@ static Property arm_sysctl_properties[] = {
     DEFINE_PROP_UINT32("proc_id", arm_sysctl_state, proc_id, 0),
     /* Daughterboard power supply voltages (as reported via SYS_CFG) */
     DEFINE_PROP_ARRAY("db-voltage", arm_sysctl_state, db_num_vsensors,
-                      db_voltage, qdev_prop_uint32, uint32_t),
+                      db_voltage, prop_info_uint32, uint32_t),
     /* Daughterboard clock reset values (as reported via SYS_CFG) */
     DEFINE_PROP_ARRAY("db-clock", arm_sysctl_state, db_num_clocks,
-                      db_clock_reset, qdev_prop_uint32, uint32_t),
+                      db_clock_reset, prop_info_uint32, uint32_t),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
index b6f1ae3c8f..7928939ae2 100644
--- a/hw/net/e1000e.c
+++ b/hw/net/e1000e.c
@@ -686,15 +686,15 @@ static void e1000e_class_init(ObjectClass *class, void *data)
     dc->reset = e1000e_qdev_reset;
     dc->vmsd = &e1000e_vmstate;
 
-    e1000e_prop_disable_vnet = qdev_prop_uint8;
+    e1000e_prop_disable_vnet = prop_info_uint8;
     e1000e_prop_disable_vnet.description = "Do not use virtio headers, "
                                            "perform SW offloads emulation "
                                            "instead";
 
-    e1000e_prop_subsys_ven = qdev_prop_uint16;
+    e1000e_prop_subsys_ven = prop_info_uint16;
     e1000e_prop_subsys_ven.description = "PCI device Subsystem Vendor ID";
 
-    e1000e_prop_subsys = qdev_prop_uint16;
+    e1000e_prop_subsys = prop_info_uint16;
     e1000e_prop_subsys.description = "PCI device Subsystem ID";
 
     device_class_set_props(dc, e1000e_properties);
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 07492e9f9a..cef92879b0 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1108,7 +1108,7 @@ static Property arm_cpu_has_mpu_property =
 static Property arm_cpu_pmsav7_dregion_property =
             DEFINE_PROP_UNSIGNED_NODEFAULT("pmsav7-dregion", ARMCPU,
                                            pmsav7_dregion,
-                                           qdev_prop_uint32, uint32_t);
+                                           prop_info_uint32, uint32_t);
 
 static bool arm_get_pmu(Object *obj, Error **errp)
 {
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 3375fffb38..ec59a13eb8 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -839,7 +839,7 @@ static Property sparc_cpu_properties[] = {
     DEFINE_PROP_BIT("cmt",      SPARCCPU, env.def.features, 12, false),
     DEFINE_PROP_BIT("gl",       SPARCCPU, env.def.features, 13, false),
     DEFINE_PROP_UNSIGNED("iu-version", SPARCCPU, env.def.iu_version, 0,
-                         qdev_prop_uint64, target_ulong),
+                         prop_info_uint64, target_ulong),
     DEFINE_PROP_UINT32("fpu-version", SPARCCPU, env.def.fpu_version, 0),
     DEFINE_PROP_UINT32("mmu-version", SPARCCPU, env.def.mmu_version, 0),
     DEFINE_PROP("nwindows",     SPARCCPU, env.def.nwindows,
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 39/44] qdev: PROP_* macros
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (37 preceding siblings ...)
  2020-11-04 16:00 ` [PATCH v2 38/44] qdev: Rename qdev_prop_* to prop_info_* Eduardo Habkost
@ 2020-11-04 16:00 ` Eduardo Habkost
  2020-11-04 16:00 ` [PATCH v2 40/44] qdev: Move core field property code to QOM Eduardo Habkost
                   ` (6 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 16:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

The new helper macros are just wrappers to DEFINE_PROP_* that can
be used directly as arguments to object_class_property_add_field().

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
This is a new patch added in v2 of the series
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 include/hw/qdev-properties.h | 54 ++++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 0a44a91e6e..89c820eeb7 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -173,6 +173,60 @@ extern const PropertyInfo prop_info_link;
 #define DEFINE_PROP_END_OF_LIST()               \
     {}
 
+/*
+ * The PROP_* macros can be used as arguments for
+ * object_class_property_add_field().  They will evaluate to a
+ * pointer to a static variable.
+ */
+
+#define FIELD_PROP(def) \
+    ({ static Property _p = def; &p; })
+
+#define PROP_SIGNED(...) \
+    FIELD_PROP(DEFINE_PROP_SIGNED(NULL, __VA_ARGS__))
+#define PROP_SIGNED_NODEFAULT(...) \
+    FIELD_PROP(DEFINE_PROP_SIGNED_NODEFAULT(NULL, __VA_ARGS__))
+#define PROP_BIT(...) \
+    FIELD_PROP(DEFINE_PROP_BIT(NULL, __VA_ARGS__))
+#define PROP_UNSIGNED(...) \
+    FIELD_PROP(DEFINE_PROP_UNSIGNED(NULL, __VA_ARGS__))
+#define PROP_UNSIGNED_NODEFAULT(...) \
+    FIELD_PROP(DEFINE_PROP_UNSIGNED_NODEFAULT(NULL, __VA_ARGS__))
+#define PROP_BIT64(...) \
+    FIELD_PROP(DEFINE_PROP_BIT64(NULL, __VA_ARGS__))
+#define PROP_BOOL(...) \
+    FIELD_PROP(DEFINE_PROP_BOOL(NULL, __VA_ARGS__))
+#define PROP_ARRAY(...) \
+    FIELD_PROP(DEFINE_PROP_ARRAY(NULL, __VA_ARGS__))
+#define PROP_LINK(...) \
+    FIELD_PROP(DEFINE_PROP_LINK(NULL, __VA_ARGS__))
+#define PROP_UINT8(...) \
+    FIELD_PROP(DEFINE_PROP_UINT8(NULL, __VA_ARGS__))
+#define PROP_UINT16(...) \
+    FIELD_PROP(DEFINE_PROP_UINT16(NULL, __VA_ARGS__))
+#define PROP_UINT32(...) \
+    FIELD_PROP(DEFINE_PROP_UINT32(NULL, __VA_ARGS__))
+#define PROP_INT32(...) \
+    FIELD_PROP(DEFINE_PROP_INT32(NULL, __VA_ARGS__))
+#define PROP_UINT64(...) \
+    FIELD_PROP(DEFINE_PROP_UINT64(NULL, __VA_ARGS__))
+#define PROP_INT64(...) \
+    FIELD_PROP(DEFINE_PROP_INT64(NULL, __VA_ARGS__))
+#define PROP_SIZE(...) \
+    FIELD_PROP(DEFINE_PROP_SIZE(NULL, __VA_ARGS__))
+#define PROP_STRING(...) \
+    FIELD_PROP(DEFINE_PROP_STRING(NULL, __VA_ARGS__))
+#define PROP_ON_OFF_AUTO(...) \
+    FIELD_PROP(DEFINE_PROP_ON_OFF_AUTO(NULL, __VA_ARGS__))
+#define PROP_SIZE32(...) \
+    FIELD_PROP(DEFINE_PROP_SIZE32(NULL, __VA_ARGS__))
+#define PROP_UUID(...) \
+    FIELD_PROP(DEFINE_PROP_UUID(NULL, __VA_ARGS__))
+#define PROP_UUID_NODEFAULT(...) \
+    FIELD_PROP(DEFINE_PROP_UUID_NODEFAULT(NULL, __VA_ARGS__))
+#define PROP_END_OF_LIST(...) \
+    FIELD_PROP(DEFINE_PROP_END_OF_LIST(NULL, __VA_ARGS__))
+
 /**
  * object_class_property_add_field: Add a field property to object class
  * @oc: object class
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 40/44] qdev: Move core field property code to QOM
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (38 preceding siblings ...)
  2020-11-04 16:00 ` [PATCH v2 39/44] qdev: PROP_* macros Eduardo Habkost
@ 2020-11-04 16:00 ` Eduardo Habkost
  2020-11-04 16:00 ` [PATCH v2 41/44] qdev: Move base property types to qom/property-types.c Eduardo Habkost
                   ` (5 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 16:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

Move the core of the static property code to qom/field-property.c.

The actual property type implementations are still in
qdev-properties.c, they will be moved later.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Changes v1 -> v2:
* Rename static-property.* to field-property.*
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 include/hw/qdev-properties.h                  |  71 +-----------
 .../qom/field-property-internal.h             |   6 +-
 include/qom/field-property.h                  |  79 +++++++++++++
 hw/core/qdev-properties-system.c              |   2 +-
 hw/core/qdev-properties.c                     | 104 +----------------
 qom/field-property.c                          | 108 ++++++++++++++++++
 qom/meson.build                               |   1 +
 7 files changed, 194 insertions(+), 177 deletions(-)
 rename hw/core/qdev-prop-internal.h => include/qom/field-property-internal.h (91%)
 create mode 100644 include/qom/field-property.h
 create mode 100644 qom/field-property.c

diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 89c820eeb7..bee26d0319 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -2,52 +2,7 @@
 #define QEMU_QDEV_PROPERTIES_H
 
 #include "hw/qdev-core.h"
-
-/**
- * Property:
- * @set_default: true if the default value should be set from @defval,
- *    in which case @info->set_default_value must not be NULL
- *    (if false then no default value is set by the property system
- *     and the field retains whatever value it was given by instance_init).
- * @defval: default value for the property. This is used only if @set_default
- *     is true.
- */
-struct Property {
-    /**
-     * @qdev_prop_name: qdev property name
-     *
-     * qdev_prop_name is used only by TYPE_DEVICE code
-     * (device_class_set_props(), qdev_class_add_property(), and
-     * others).
-     */
-    const char   *qdev_prop_name;
-    const PropertyInfo *info;
-    ptrdiff_t    offset;
-    uint8_t      bitnr;
-    bool         set_default;
-    union {
-        int64_t i;
-        uint64_t u;
-    } defval;
-    int          arrayoffset;
-    const PropertyInfo *arrayinfo;
-    int          arrayfieldsize;
-    const char   *link_type;
-};
-
-struct PropertyInfo {
-    const char *name;
-    const char *description;
-    const QEnumLookup *enum_table;
-    int (*print)(Object *obj, Property *prop, char *dest, size_t len);
-    void (*set_default_value)(ObjectProperty *op, const Property *prop);
-    ObjectProperty *(*create)(ObjectClass *oc, const char *name,
-                              Property *prop);
-    ObjectPropertyAccessor *get;
-    ObjectPropertyAccessor *set;
-    ObjectPropertyRelease *release;
-};
-
+#include "qom/field-property.h"
 
 /*** qdev-properties.c ***/
 
@@ -227,28 +182,6 @@ extern const PropertyInfo prop_info_link;
 #define PROP_END_OF_LIST(...) \
     FIELD_PROP(DEFINE_PROP_END_OF_LIST(NULL, __VA_ARGS__))
 
-/**
- * object_class_property_add_field: Add a field property to object class
- * @oc: object class
- * @name: property name
- * @prop: property definition
- * @allow_set: check function called when property is set
- *
- * Add a field property to an object class.  A field property is
- * a property that will change a field at a specific offset of the
- * object instance struct.
- *
- * *@prop must exist for the life time of @oc.
- *
- * @allow_set should not be NULL.  If the property can always be
- * set, `prop_allow_set_always` can be used.  If the property can
- * never be set, `prop_allow_set_never` can be used.
- */
-ObjectProperty *
-object_class_property_add_field(ObjectClass *oc, const char *name,
-                                Property *prop,
-                                ObjectPropertyAllowSet allow_set);
-
 /*
  * Set properties between creation and realization.
  *
@@ -276,8 +209,6 @@ void qdev_prop_set_macaddr(DeviceState *dev, const char *name,
                            const uint8_t *value);
 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value);
 
-void *object_field_prop_ptr(Object *obj, Property *prop);
-
 void qdev_prop_register_global(GlobalProperty *prop);
 const GlobalProperty *qdev_find_global_prop(Object *obj,
                                             const char *name);
diff --git a/hw/core/qdev-prop-internal.h b/include/qom/field-property-internal.h
similarity index 91%
rename from hw/core/qdev-prop-internal.h
rename to include/qom/field-property-internal.h
index bdcb37f14f..7aa27ce836 100644
--- a/hw/core/qdev-prop-internal.h
+++ b/include/qom/field-property-internal.h
@@ -1,12 +1,12 @@
 /*
- * qdev property parsing
+ * QOM field property internal API (for implementing custom types)
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
  */
 
-#ifndef HW_CORE_QDEV_PROP_INTERNAL_H
-#define HW_CORE_QDEV_PROP_INTERNAL_H
+#ifndef QOM_STATIC_PROPERTY_INTERNAL_H
+#define QOM_STATIC_PROPERTY_INTERNAL_H
 
 void field_prop_get_enum(Object *obj, Visitor *v, const char *name,
                          void *opaque, Error **errp);
diff --git a/include/qom/field-property.h b/include/qom/field-property.h
new file mode 100644
index 0000000000..bdc89b38a6
--- /dev/null
+++ b/include/qom/field-property.h
@@ -0,0 +1,79 @@
+/*
+ * QOM field property API
+ */
+#ifndef QOM_FIELD_PROPERTY_H
+#define QOM_FIELD_PROPERTY_H
+
+#include "qom/object.h"
+#include "qapi/util.h"
+
+/**
+ * Property:
+ * @set_default: true if the default value should be set from @defval,
+ *    in which case @info->set_default_value must not be NULL
+ *    (if false then no default value is set by the property system
+ *     and the field retains whatever value it was given by instance_init).
+ * @defval: default value for the property. This is used only if @set_default
+ *     is true.
+ */
+struct Property {
+    /**
+     * @qdev_prop_name: qdev property name
+     *
+     * qdev_prop_name is used only by TYPE_DEVICE code
+     * (device_class_set_props(), qdev_class_add_property(), and
+     * others).
+     */
+    const char   *qdev_prop_name;
+    const PropertyInfo *info;
+    ptrdiff_t    offset;
+    uint8_t      bitnr;
+    bool         set_default;
+    union {
+        int64_t i;
+        uint64_t u;
+    } defval;
+    int          arrayoffset;
+    const PropertyInfo *arrayinfo;
+    int          arrayfieldsize;
+    const char   *link_type;
+};
+
+struct PropertyInfo {
+    const char *name;
+    const char *description;
+    const QEnumLookup *enum_table;
+    int (*print)(Object *obj, Property *prop, char *dest, size_t len);
+    void (*set_default_value)(ObjectProperty *op, const Property *prop);
+    ObjectProperty *(*create)(ObjectClass *oc, const char *name,
+                              Property *prop);
+    ObjectPropertyAccessor *get;
+    ObjectPropertyAccessor *set;
+    ObjectPropertyRelease *release;
+};
+
+/**
+ * object_class_property_add_field: Add a field property to object class
+ * @oc: object class
+ * @name: property name
+ * @prop: property definition
+ * @allow_set: check function called when property is set
+ *
+ * Add a field property to an object class.  A field property is
+ * a property that will change a field at a specific offset of the
+ * object instance struct.
+ *
+ * *@prop must exist for the life time of @oc.
+ *
+ * @allow_set should not be NULL.  If the property can always be
+ * set, `prop_allow_set_always` can be used.  If the property can
+ * never be set, `prop_allow_set_never` can be used.
+ */
+ObjectProperty *
+object_class_property_add_field(ObjectClass *oc, const char *name,
+                                Property *prop,
+                                ObjectPropertyAllowSet allow_set);
+
+void *object_field_prop_ptr(Object *obj, Property *prop);
+
+#endif
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 8781b856d3..8da68f076c 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -24,7 +24,7 @@
 #include "qemu/units.h"
 #include "qemu/uuid.h"
 #include "qemu/error-report.h"
-#include "qdev-prop-internal.h"
+#include "qom/field-property-internal.h"
 
 #include "audio/audio.h"
 #include "chardev/char-fe.h"
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 64b803a200..b75730f15c 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -8,7 +8,7 @@
 #include "qapi/visitor.h"
 #include "qemu/units.h"
 #include "qemu/cutils.h"
-#include "qdev-prop-internal.h"
+#include "qom/field-property-internal.h"
 
 void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
                                   Error **errp)
@@ -50,48 +50,6 @@ void qdev_prop_allow_set_link_before_realize(const Object *obj,
     }
 }
 
-void *object_field_prop_ptr(Object *obj, Property *prop)
-{
-    void *ptr = obj;
-    ptr += prop->offset;
-    return ptr;
-}
-
-static void field_prop_get(Object *obj, Visitor *v, const char *name,
-                           void *opaque, Error **errp)
-{
-    Property *prop = opaque;
-    return prop->info->get(obj, v, name, opaque, errp);
-}
-
-/**
- * field_prop_getter: Return getter function to be used for property
- *
- * Return value can be NULL if @info has no getter function.
- */
-static ObjectPropertyAccessor *field_prop_getter(const PropertyInfo *info)
-{
-    return info->get ? field_prop_get : NULL;
-}
-
-static void field_prop_set(Object *obj, Visitor *v, const char *name,
-                           void *opaque, Error **errp)
-{
-    Property *prop = opaque;
-
-    return prop->info->set(obj, v, name, opaque, errp);
-}
-
-/**
- * field_prop_setter: Return setter function to be used for property
- *
- * Return value can be NULL if @info has not setter function.
- */
-static ObjectPropertyAccessor *field_prop_setter(const PropertyInfo *info)
-{
-    return info->set ? field_prop_set : NULL;
-}
-
 void field_prop_get_enum(Object *obj, Visitor *v, const char *name,
                          void *opaque, Error **errp)
 {
@@ -801,66 +759,6 @@ const PropertyInfo prop_info_link = {
     .create = create_link_property,
 };
 
-ObjectProperty *
-object_property_add_field(Object *obj, const char *name, Property *prop,
-                          ObjectPropertyAllowSet allow_set)
-{
-    ObjectProperty *op;
-
-    assert(allow_set);
-    assert(!prop->info->create);
-
-    op = object_property_add(obj, name, prop->info->name,
-                             field_prop_getter(prop->info),
-                             field_prop_setter(prop->info),
-                             prop->info->release,
-                             prop);
-
-    object_property_set_description(obj, name,
-                                    prop->info->description);
-
-    if (prop->set_default) {
-        prop->info->set_default_value(op, prop);
-        if (op->init) {
-            op->init(obj, op);
-        }
-    }
-
-    op->allow_set = allow_set;
-    return op;
-}
-
-ObjectProperty *
-object_class_property_add_field(ObjectClass *oc, const char *name,
-                                Property *prop,
-                                ObjectPropertyAllowSet allow_set)
-{
-    ObjectProperty *op;
-
-    assert(allow_set);
-
-    if (prop->info->create) {
-        op = prop->info->create(oc, name, prop);
-    } else {
-        op = object_class_property_add(oc,
-                                       name, prop->info->name,
-                                       field_prop_getter(prop->info),
-                                       field_prop_setter(prop->info),
-                                       prop->info->release,
-                                       prop);
-    }
-    if (prop->set_default) {
-        prop->info->set_default_value(op, prop);
-    }
-    if (prop->info->description) {
-        object_class_property_set_description(oc, name,
-                                              prop->info->description);
-    }
-
-    op->allow_set = allow_set;
-    return op;
-}
-
 void qdev_property_add_static(DeviceState *dev, Property *prop)
 {
     object_property_add_field(OBJECT(dev), prop->qdev_prop_name, prop,
diff --git a/qom/field-property.c b/qom/field-property.c
new file mode 100644
index 0000000000..25a818bb69
--- /dev/null
+++ b/qom/field-property.c
@@ -0,0 +1,108 @@
+/*
+ * QOM field property API implementation
+ */
+#include "qemu/osdep.h"
+#include "qom/field-property.h"
+#include "qom/field-property-internal.h"
+
+void *object_field_prop_ptr(Object *obj, Property *prop)
+{
+    void *ptr = obj;
+    ptr += prop->offset;
+    return ptr;
+}
+
+static void field_prop_get(Object *obj, Visitor *v, const char *name,
+                           void *opaque, Error **errp)
+{
+    Property *prop = opaque;
+    return prop->info->get(obj, v, name, opaque, errp);
+}
+
+/**
+ * field_prop_getter: Return getter function to be used for property
+ *
+ * Return value can be NULL if @info has no getter function.
+ */
+static ObjectPropertyAccessor *field_prop_getter(const PropertyInfo *info)
+{
+    return info->get ? field_prop_get : NULL;
+}
+
+static void field_prop_set(Object *obj, Visitor *v, const char *name,
+                           void *opaque, Error **errp)
+{
+    Property *prop = opaque;
+
+    return prop->info->set(obj, v, name, opaque, errp);
+}
+
+/**
+ * field_prop_setter: Return setter function to be used for property
+ *
+ * Return value can be NULL if @info has not setter function.
+ */
+static ObjectPropertyAccessor *field_prop_setter(const PropertyInfo *info)
+{
+    return info->set ? field_prop_set : NULL;
+}
+
+ObjectProperty *
+object_property_add_field(Object *obj, const char *name, Property *prop,
+                          ObjectPropertyAllowSet allow_set)
+{
+    ObjectProperty *op;
+
+    assert(allow_set);
+    assert(!prop->info->create);
+
+    op = object_property_add(obj, name, prop->info->name,
+                             field_prop_getter(prop->info),
+                             field_prop_setter(prop->info),
+                             prop->info->release,
+                             prop);
+
+    object_property_set_description(obj, name,
+                                    prop->info->description);
+
+    if (prop->set_default) {
+        prop->info->set_default_value(op, prop);
+        if (op->init) {
+            op->init(obj, op);
+        }
+    }
+
+    op->allow_set = allow_set;
+    return op;
+}
+
+ObjectProperty *
+object_class_property_add_field(ObjectClass *oc, const char *name,
+                                Property *prop,
+                                ObjectPropertyAllowSet allow_set)
+{
+    ObjectProperty *op;
+
+    assert(allow_set);
+
+    if (prop->info->create) {
+        op = prop->info->create(oc, name, prop);
+    } else {
+        op = object_class_property_add(oc,
+                                       name, prop->info->name,
+                                       field_prop_getter(prop->info),
+                                       field_prop_setter(prop->info),
+                                       prop->info->release,
+                                       prop);
+    }
+    if (prop->set_default) {
+        prop->info->set_default_value(op, prop);
+    }
+    if (prop->info->description) {
+        object_class_property_set_description(oc, name,
+                                              prop->info->description);
+    }
+
+    op->allow_set = allow_set;
+    return op;
+}
diff --git a/qom/meson.build b/qom/meson.build
index 062a3789d8..e83794454d 100644
--- a/qom/meson.build
+++ b/qom/meson.build
@@ -4,6 +4,7 @@ qom_ss.add(files(
   'object.c',
   'object_interfaces.c',
   'qom-qobject.c',
+  'field-property.c',
 ))
 
 qmp_ss.add(files('qom-qmp-cmds.c'))
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 41/44] qdev: Move base property types to qom/property-types.c
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (39 preceding siblings ...)
  2020-11-04 16:00 ` [PATCH v2 40/44] qdev: Move core field property code to QOM Eduardo Habkost
@ 2020-11-04 16:00 ` Eduardo Habkost
  2020-11-04 16:36   ` Paolo Bonzini
  2020-11-04 16:00 ` [PATCH v2 42/44] qom: Include static property API reference in documentation Eduardo Habkost
                   ` (4 subsequent siblings)
  45 siblings, 1 reply; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 16:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

Move all property types from qdev-properties.c to
qom/property-types.c.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Changes v1 -> v2:
* Rebased after changes in previous patches in the series
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 include/hw/qdev-properties.h | 179 +-----------
 include/qom/property-types.h | 185 ++++++++++++
 hw/core/qdev-properties.c    | 537 ----------------------------------
 qom/property-types.c         | 545 +++++++++++++++++++++++++++++++++++
 qom/meson.build              |   1 +
 5 files changed, 732 insertions(+), 715 deletions(-)
 create mode 100644 include/qom/property-types.h
 create mode 100644 qom/property-types.c

diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index bee26d0319..939b6dbf4e 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -3,184 +3,7 @@
 
 #include "hw/qdev-core.h"
 #include "qom/field-property.h"
-
-/*** qdev-properties.c ***/
-
-extern const PropertyInfo prop_info_bit;
-extern const PropertyInfo prop_info_bit64;
-extern const PropertyInfo prop_info_bool;
-extern const PropertyInfo prop_info_enum;
-extern const PropertyInfo prop_info_uint8;
-extern const PropertyInfo prop_info_uint16;
-extern const PropertyInfo prop_info_uint32;
-extern const PropertyInfo prop_info_int32;
-extern const PropertyInfo prop_info_uint64;
-extern const PropertyInfo prop_info_int64;
-extern const PropertyInfo prop_info_size;
-extern const PropertyInfo prop_info_string;
-extern const PropertyInfo prop_info_on_off_auto;
-extern const PropertyInfo prop_info_size32;
-extern const PropertyInfo prop_info_arraylen;
-extern const PropertyInfo prop_info_link;
-
-#define DEFINE_PROP(_name, _state, _field, _prop, _type, ...) {  \
-        .qdev_prop_name      = (_name),                          \
-        .info      = &(_prop),                                   \
-        .offset    = offsetof(_state, _field)                    \
-            + type_check(_type, typeof_field(_state, _field)),   \
-        __VA_ARGS__                                              \
-        }
-
-#define DEFINE_PROP_SIGNED(_name, _state, _field, _defval, _prop, _type) \
-    DEFINE_PROP(_name, _state, _field, _prop, _type,                     \
-                .set_default = true,                                     \
-                .defval.i    = (_type)_defval)
-
-#define DEFINE_PROP_SIGNED_NODEFAULT(_name, _state, _field, _prop, _type) \
-    DEFINE_PROP(_name, _state, _field, _prop, _type)
-
-#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval)   \
-    DEFINE_PROP(_name, _state, _field, prop_info_bit, uint32_t, \
-                .bitnr       = (_bit),                          \
-                .set_default = true,                            \
-                .defval.u    = (bool)_defval)
-
-#define DEFINE_PROP_UNSIGNED(_name, _state, _field, _defval, _prop, _type) \
-    DEFINE_PROP(_name, _state, _field, _prop, _type,                       \
-                .set_default = true,                                       \
-                .defval.u  = (_type)_defval)
-
-#define DEFINE_PROP_UNSIGNED_NODEFAULT(_name, _state, _field, _prop, _type) \
-    DEFINE_PROP(_name, _state, _field, _prop, _type)
-
-#define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval)   \
-    DEFINE_PROP(_name, _state, _field, prop_info_bit64, uint64_t, \
-                .bitnr    = (_bit),                               \
-                .set_default = true,                              \
-                .defval.u  = (bool)_defval)
-
-#define DEFINE_PROP_BOOL(_name, _state, _field, _defval)     \
-    DEFINE_PROP(_name, _state, _field, prop_info_bool, bool, \
-                .set_default = true,                         \
-                .defval.u    = (bool)_defval)
-
-#define PROP_ARRAY_LEN_PREFIX "len-"
-
-/**
- * DEFINE_PROP_ARRAY:
- * @_name: name of the array
- * @_state: name of the device state structure type
- * @_field: uint32_t field in @_state to hold the array length
- * @_arrayfield: field in @_state (of type '@_arraytype *') which
- *               will point to the array
- * @_arrayprop: PropertyInfo defining what property the array elements have
- * @_arraytype: C type of the array elements
- *
- * Define device properties for a variable-length array _name.  A
- * static property "len-arrayname" is defined. When the device creator
- * sets this property to the desired length of array, further dynamic
- * properties "arrayname[0]", "arrayname[1]", ...  are defined so the
- * device creator can set the array element values. Setting the
- * "len-arrayname" property more than once is an error.
- *
- * When the array length is set, the @_field member of the device
- * struct is set to the array length, and @_arrayfield is set to point
- * to (zero-initialised) memory allocated for the array.  For a zero
- * length array, @_field will be set to 0 and @_arrayfield to NULL.
- * It is the responsibility of the device deinit code to free the
- * @_arrayfield memory.
- */
-#define DEFINE_PROP_ARRAY(_name, _state, _field,               \
-                          _arrayfield, _arrayprop, _arraytype) \
-    DEFINE_PROP((PROP_ARRAY_LEN_PREFIX _name),                 \
-                _state, _field, prop_info_arraylen, uint32_t,  \
-                .set_default = true,                           \
-                .defval.u = 0,                                 \
-                .arrayinfo = &(_arrayprop),                    \
-                .arrayfieldsize = sizeof(_arraytype),          \
-                .arrayoffset = offsetof(_state, _arrayfield))
-
-#define DEFINE_PROP_LINK(_name, _state, _field, _type, _ptr_type)     \
-    DEFINE_PROP(_name, _state, _field, prop_info_link, _ptr_type,     \
-                .link_type  = _type)
-
-#define DEFINE_PROP_UINT8(_n, _s, _f, _d)                       \
-    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint8, uint8_t)
-#define DEFINE_PROP_UINT16(_n, _s, _f, _d)                      \
-    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint16, uint16_t)
-#define DEFINE_PROP_UINT32(_n, _s, _f, _d)                      \
-    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint32, uint32_t)
-#define DEFINE_PROP_INT32(_n, _s, _f, _d)                      \
-    DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_int32, int32_t)
-#define DEFINE_PROP_UINT64(_n, _s, _f, _d)                      \
-    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint64, uint64_t)
-#define DEFINE_PROP_INT64(_n, _s, _f, _d)                      \
-    DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_int64, int64_t)
-#define DEFINE_PROP_SIZE(_n, _s, _f, _d)                       \
-    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_size, uint64_t)
-#define DEFINE_PROP_STRING(_n, _s, _f)             \
-    DEFINE_PROP(_n, _s, _f, prop_info_string, char*)
-#define DEFINE_PROP_ON_OFF_AUTO(_n, _s, _f, _d) \
-    DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_on_off_auto, OnOffAuto)
-#define DEFINE_PROP_SIZE32(_n, _s, _f, _d)                       \
-    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_size32, uint32_t)
-
-#define DEFINE_PROP_END_OF_LIST()               \
-    {}
-
-/*
- * The PROP_* macros can be used as arguments for
- * object_class_property_add_field().  They will evaluate to a
- * pointer to a static variable.
- */
-
-#define FIELD_PROP(def) \
-    ({ static Property _p = def; &p; })
-
-#define PROP_SIGNED(...) \
-    FIELD_PROP(DEFINE_PROP_SIGNED(NULL, __VA_ARGS__))
-#define PROP_SIGNED_NODEFAULT(...) \
-    FIELD_PROP(DEFINE_PROP_SIGNED_NODEFAULT(NULL, __VA_ARGS__))
-#define PROP_BIT(...) \
-    FIELD_PROP(DEFINE_PROP_BIT(NULL, __VA_ARGS__))
-#define PROP_UNSIGNED(...) \
-    FIELD_PROP(DEFINE_PROP_UNSIGNED(NULL, __VA_ARGS__))
-#define PROP_UNSIGNED_NODEFAULT(...) \
-    FIELD_PROP(DEFINE_PROP_UNSIGNED_NODEFAULT(NULL, __VA_ARGS__))
-#define PROP_BIT64(...) \
-    FIELD_PROP(DEFINE_PROP_BIT64(NULL, __VA_ARGS__))
-#define PROP_BOOL(...) \
-    FIELD_PROP(DEFINE_PROP_BOOL(NULL, __VA_ARGS__))
-#define PROP_ARRAY(...) \
-    FIELD_PROP(DEFINE_PROP_ARRAY(NULL, __VA_ARGS__))
-#define PROP_LINK(...) \
-    FIELD_PROP(DEFINE_PROP_LINK(NULL, __VA_ARGS__))
-#define PROP_UINT8(...) \
-    FIELD_PROP(DEFINE_PROP_UINT8(NULL, __VA_ARGS__))
-#define PROP_UINT16(...) \
-    FIELD_PROP(DEFINE_PROP_UINT16(NULL, __VA_ARGS__))
-#define PROP_UINT32(...) \
-    FIELD_PROP(DEFINE_PROP_UINT32(NULL, __VA_ARGS__))
-#define PROP_INT32(...) \
-    FIELD_PROP(DEFINE_PROP_INT32(NULL, __VA_ARGS__))
-#define PROP_UINT64(...) \
-    FIELD_PROP(DEFINE_PROP_UINT64(NULL, __VA_ARGS__))
-#define PROP_INT64(...) \
-    FIELD_PROP(DEFINE_PROP_INT64(NULL, __VA_ARGS__))
-#define PROP_SIZE(...) \
-    FIELD_PROP(DEFINE_PROP_SIZE(NULL, __VA_ARGS__))
-#define PROP_STRING(...) \
-    FIELD_PROP(DEFINE_PROP_STRING(NULL, __VA_ARGS__))
-#define PROP_ON_OFF_AUTO(...) \
-    FIELD_PROP(DEFINE_PROP_ON_OFF_AUTO(NULL, __VA_ARGS__))
-#define PROP_SIZE32(...) \
-    FIELD_PROP(DEFINE_PROP_SIZE32(NULL, __VA_ARGS__))
-#define PROP_UUID(...) \
-    FIELD_PROP(DEFINE_PROP_UUID(NULL, __VA_ARGS__))
-#define PROP_UUID_NODEFAULT(...) \
-    FIELD_PROP(DEFINE_PROP_UUID_NODEFAULT(NULL, __VA_ARGS__))
-#define PROP_END_OF_LIST(...) \
-    FIELD_PROP(DEFINE_PROP_END_OF_LIST(NULL, __VA_ARGS__))
+#include "qom/property-types.h"
 
 /*
  * Set properties between creation and realization.
diff --git a/include/qom/property-types.h b/include/qom/property-types.h
new file mode 100644
index 0000000000..75f758e835
--- /dev/null
+++ b/include/qom/property-types.h
@@ -0,0 +1,185 @@
+/*
+ * QOM field property types
+ */
+#ifndef QOM_PROPERTY_TYPES_H
+#define QOM_PROPERTY_TYPES_H
+
+#include "qom/field-property.h"
+
+extern const PropertyInfo prop_info_bit;
+extern const PropertyInfo prop_info_bit64;
+extern const PropertyInfo prop_info_bool;
+extern const PropertyInfo prop_info_enum;
+extern const PropertyInfo prop_info_uint8;
+extern const PropertyInfo prop_info_uint16;
+extern const PropertyInfo prop_info_uint32;
+extern const PropertyInfo prop_info_int32;
+extern const PropertyInfo prop_info_uint64;
+extern const PropertyInfo prop_info_int64;
+extern const PropertyInfo prop_info_size;
+extern const PropertyInfo prop_info_string;
+extern const PropertyInfo prop_info_on_off_auto;
+extern const PropertyInfo prop_info_size32;
+extern const PropertyInfo prop_info_arraylen;
+extern const PropertyInfo prop_info_link;
+
+#define DEFINE_PROP(_name, _state, _field, _prop, _type, ...) {  \
+        .qdev_prop_name      = (_name),                          \
+        .info      = &(_prop),                                   \
+        .offset    = offsetof(_state, _field)                    \
+            + type_check(_type, typeof_field(_state, _field)),   \
+        __VA_ARGS__                                              \
+        }
+
+#define DEFINE_PROP_SIGNED(_name, _state, _field, _defval, _prop, _type) \
+    DEFINE_PROP(_name, _state, _field, _prop, _type,                     \
+                .set_default = true,                                     \
+                .defval.i    = (_type)_defval)
+
+#define DEFINE_PROP_SIGNED_NODEFAULT(_name, _state, _field, _prop, _type) \
+    DEFINE_PROP(_name, _state, _field, _prop, _type)
+
+#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval)   \
+    DEFINE_PROP(_name, _state, _field, prop_info_bit, uint32_t, \
+                .bitnr       = (_bit),                          \
+                .set_default = true,                            \
+                .defval.u    = (bool)_defval)
+
+#define DEFINE_PROP_UNSIGNED(_name, _state, _field, _defval, _prop, _type) \
+    DEFINE_PROP(_name, _state, _field, _prop, _type,                       \
+                .set_default = true,                                       \
+                .defval.u  = (_type)_defval)
+
+#define DEFINE_PROP_UNSIGNED_NODEFAULT(_name, _state, _field, _prop, _type) \
+    DEFINE_PROP(_name, _state, _field, _prop, _type)
+
+#define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval)   \
+    DEFINE_PROP(_name, _state, _field, prop_info_bit64, uint64_t, \
+                .bitnr    = (_bit),                               \
+                .set_default = true,                              \
+                .defval.u  = (bool)_defval)
+
+#define DEFINE_PROP_BOOL(_name, _state, _field, _defval)     \
+    DEFINE_PROP(_name, _state, _field, prop_info_bool, bool, \
+                .set_default = true,                         \
+                .defval.u    = (bool)_defval)
+
+#define PROP_ARRAY_LEN_PREFIX "len-"
+
+/**
+ * DEFINE_PROP_ARRAY:
+ * @_name: name of the array
+ * @_state: name of the device state structure type
+ * @_field: uint32_t field in @_state to hold the array length
+ * @_arrayfield: field in @_state (of type '@_arraytype *') which
+ *               will point to the array
+ * @_arrayprop: PropertyInfo defining what property the array elements have
+ * @_arraytype: C type of the array elements
+ *
+ * Define device properties for a variable-length array _name.  A
+ * static property "len-arrayname" is defined. When the device creator
+ * sets this property to the desired length of array, further dynamic
+ * properties "arrayname[0]", "arrayname[1]", ...  are defined so the
+ * device creator can set the array element values. Setting the
+ * "len-arrayname" property more than once is an error.
+ *
+ * When the array length is set, the @_field member of the device
+ * struct is set to the array length, and @_arrayfield is set to point
+ * to (zero-initialised) memory allocated for the array.  For a zero
+ * length array, @_field will be set to 0 and @_arrayfield to NULL.
+ * It is the responsibility of the device deinit code to free the
+ * @_arrayfield memory.
+ */
+#define DEFINE_PROP_ARRAY(_name, _state, _field,               \
+                          _arrayfield, _arrayprop, _arraytype) \
+    DEFINE_PROP((PROP_ARRAY_LEN_PREFIX _name),                 \
+                _state, _field, prop_info_arraylen, uint32_t,  \
+                .set_default = true,                           \
+                .defval.u = 0,                                 \
+                .arrayinfo = &(_arrayprop),                    \
+                .arrayfieldsize = sizeof(_arraytype),          \
+                .arrayoffset = offsetof(_state, _arrayfield))
+
+#define DEFINE_PROP_LINK(_name, _state, _field, _type, _ptr_type)     \
+    DEFINE_PROP(_name, _state, _field, prop_info_link, _ptr_type,     \
+                .link_type  = _type)
+
+#define DEFINE_PROP_UINT8(_n, _s, _f, _d)                       \
+    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint8, uint8_t)
+#define DEFINE_PROP_UINT16(_n, _s, _f, _d)                      \
+    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint16, uint16_t)
+#define DEFINE_PROP_UINT32(_n, _s, _f, _d)                      \
+    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint32, uint32_t)
+#define DEFINE_PROP_INT32(_n, _s, _f, _d)                      \
+    DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_int32, int32_t)
+#define DEFINE_PROP_UINT64(_n, _s, _f, _d)                      \
+    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint64, uint64_t)
+#define DEFINE_PROP_INT64(_n, _s, _f, _d)                      \
+    DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_int64, int64_t)
+#define DEFINE_PROP_SIZE(_n, _s, _f, _d)                       \
+    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_size, uint64_t)
+#define DEFINE_PROP_STRING(_n, _s, _f)             \
+    DEFINE_PROP(_n, _s, _f, prop_info_string, char*)
+#define DEFINE_PROP_ON_OFF_AUTO(_n, _s, _f, _d) \
+    DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_on_off_auto, OnOffAuto)
+#define DEFINE_PROP_SIZE32(_n, _s, _f, _d)                       \
+    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_size32, uint32_t)
+
+#define DEFINE_PROP_END_OF_LIST()               \
+    {}
+
+/*
+ * The PROP_* macros can be used as arguments for
+ * object_class_property_add_field().  They will evaluate to a
+ * pointer to a static variable.
+ */
+
+#define FIELD_PROP(def) \
+    ({ static Property _p = def; &p; })
+
+#define PROP_SIGNED(...) \
+    FIELD_PROP(DEFINE_PROP_SIGNED(NULL, __VA_ARGS__))
+#define PROP_SIGNED_NODEFAULT(...) \
+    FIELD_PROP(DEFINE_PROP_SIGNED_NODEFAULT(NULL, __VA_ARGS__))
+#define PROP_BIT(...) \
+    FIELD_PROP(DEFINE_PROP_BIT(NULL, __VA_ARGS__))
+#define PROP_UNSIGNED(...) \
+    FIELD_PROP(DEFINE_PROP_UNSIGNED(NULL, __VA_ARGS__))
+#define PROP_UNSIGNED_NODEFAULT(...) \
+    FIELD_PROP(DEFINE_PROP_UNSIGNED_NODEFAULT(NULL, __VA_ARGS__))
+#define PROP_BIT64(...) \
+    FIELD_PROP(DEFINE_PROP_BIT64(NULL, __VA_ARGS__))
+#define PROP_BOOL(...) \
+    FIELD_PROP(DEFINE_PROP_BOOL(NULL, __VA_ARGS__))
+#define PROP_ARRAY(...) \
+    FIELD_PROP(DEFINE_PROP_ARRAY(NULL, __VA_ARGS__))
+#define PROP_LINK(...) \
+    FIELD_PROP(DEFINE_PROP_LINK(NULL, __VA_ARGS__))
+#define PROP_UINT8(...) \
+    FIELD_PROP(DEFINE_PROP_UINT8(NULL, __VA_ARGS__))
+#define PROP_UINT16(...) \
+    FIELD_PROP(DEFINE_PROP_UINT16(NULL, __VA_ARGS__))
+#define PROP_UINT32(...) \
+    FIELD_PROP(DEFINE_PROP_UINT32(NULL, __VA_ARGS__))
+#define PROP_INT32(...) \
+    FIELD_PROP(DEFINE_PROP_INT32(NULL, __VA_ARGS__))
+#define PROP_UINT64(...) \
+    FIELD_PROP(DEFINE_PROP_UINT64(NULL, __VA_ARGS__))
+#define PROP_INT64(...) \
+    FIELD_PROP(DEFINE_PROP_INT64(NULL, __VA_ARGS__))
+#define PROP_SIZE(...) \
+    FIELD_PROP(DEFINE_PROP_SIZE(NULL, __VA_ARGS__))
+#define PROP_STRING(...) \
+    FIELD_PROP(DEFINE_PROP_STRING(NULL, __VA_ARGS__))
+#define PROP_ON_OFF_AUTO(...) \
+    FIELD_PROP(DEFINE_PROP_ON_OFF_AUTO(NULL, __VA_ARGS__))
+#define PROP_SIZE32(...) \
+    FIELD_PROP(DEFINE_PROP_SIZE32(NULL, __VA_ARGS__))
+#define PROP_UUID(...) \
+    FIELD_PROP(DEFINE_PROP_UUID(NULL, __VA_ARGS__))
+#define PROP_UUID_NODEFAULT(...) \
+    FIELD_PROP(DEFINE_PROP_UUID_NODEFAULT(NULL, __VA_ARGS__))
+#define PROP_END_OF_LIST(...) \
+    FIELD_PROP(DEFINE_PROP_END_OF_LIST(NULL, __VA_ARGS__))
+
+#endif
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index b75730f15c..5bb4ff5f46 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -50,496 +50,6 @@ void qdev_prop_allow_set_link_before_realize(const Object *obj,
     }
 }
 
-void field_prop_get_enum(Object *obj, Visitor *v, const char *name,
-                         void *opaque, Error **errp)
-{
-    Property *prop = opaque;
-    int *ptr = object_field_prop_ptr(obj, prop);
-
-    visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
-}
-
-void field_prop_set_enum(Object *obj, Visitor *v, const char *name,
-                         void *opaque, Error **errp)
-{
-    Property *prop = opaque;
-    int *ptr = object_field_prop_ptr(obj, prop);
-
-    visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
-}
-
-void field_prop_set_default_value_enum(ObjectProperty *op,
-                                       const Property *prop)
-{
-    object_property_set_default_str(op,
-        qapi_enum_lookup(prop->info->enum_table, prop->defval.i));
-}
-
-const PropertyInfo prop_info_enum = {
-    .name  = "enum",
-    .get   = field_prop_get_enum,
-    .set   = field_prop_set_enum,
-    .set_default_value = field_prop_set_default_value_enum,
-};
-
-/* Bit */
-
-static uint32_t qdev_get_prop_mask(Property *prop)
-{
-    assert(prop->info == &prop_info_bit);
-    return 0x1 << prop->bitnr;
-}
-
-static void bit_prop_set(Object *obj, Property *props, bool val)
-{
-    uint32_t *p = object_field_prop_ptr(obj, props);
-    uint32_t mask = qdev_get_prop_mask(props);
-    if (val) {
-        *p |= mask;
-    } else {
-        *p &= ~mask;
-    }
-}
-
-static void prop_get_bit(Object *obj, Visitor *v, const char *name,
-                         void *opaque, Error **errp)
-{
-    Property *prop = opaque;
-    uint32_t *p = object_field_prop_ptr(obj, prop);
-    bool value = (*p & qdev_get_prop_mask(prop)) != 0;
-
-    visit_type_bool(v, name, &value, errp);
-}
-
-static void prop_set_bit(Object *obj, Visitor *v, const char *name,
-                         void *opaque, Error **errp)
-{
-    Property *prop = opaque;
-    bool value;
-
-    if (!visit_type_bool(v, name, &value, errp)) {
-        return;
-    }
-    bit_prop_set(obj, prop, value);
-}
-
-static void set_default_value_bool(ObjectProperty *op, const Property *prop)
-{
-    object_property_set_default_bool(op, prop->defval.u);
-}
-
-const PropertyInfo prop_info_bit = {
-    .name  = "bool",
-    .description = "on/off",
-    .get   = prop_get_bit,
-    .set   = prop_set_bit,
-    .set_default_value = set_default_value_bool,
-};
-
-/* Bit64 */
-
-static uint64_t qdev_get_prop_mask64(Property *prop)
-{
-    assert(prop->info == &prop_info_bit64);
-    return 0x1ull << prop->bitnr;
-}
-
-static void bit64_prop_set(Object *obj, Property *props, bool val)
-{
-    uint64_t *p = object_field_prop_ptr(obj, props);
-    uint64_t mask = qdev_get_prop_mask64(props);
-    if (val) {
-        *p |= mask;
-    } else {
-        *p &= ~mask;
-    }
-}
-
-static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
-                           void *opaque, Error **errp)
-{
-    Property *prop = opaque;
-    uint64_t *p = object_field_prop_ptr(obj, prop);
-    bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
-
-    visit_type_bool(v, name, &value, errp);
-}
-
-static void prop_set_bit64(Object *obj, Visitor *v, const char *name,
-                           void *opaque, Error **errp)
-{
-    Property *prop = opaque;
-    bool value;
-
-    if (!visit_type_bool(v, name, &value, errp)) {
-        return;
-    }
-    bit64_prop_set(obj, prop, value);
-}
-
-const PropertyInfo prop_info_bit64 = {
-    .name  = "bool",
-    .description = "on/off",
-    .get   = prop_get_bit64,
-    .set   = prop_set_bit64,
-    .set_default_value = set_default_value_bool,
-};
-
-/* --- bool --- */
-
-static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
-                     Error **errp)
-{
-    Property *prop = opaque;
-    bool *ptr = object_field_prop_ptr(obj, prop);
-
-    visit_type_bool(v, name, ptr, errp);
-}
-
-static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
-                     Error **errp)
-{
-    Property *prop = opaque;
-    bool *ptr = object_field_prop_ptr(obj, prop);
-
-    visit_type_bool(v, name, ptr, errp);
-}
-
-const PropertyInfo prop_info_bool = {
-    .name  = "bool",
-    .get   = get_bool,
-    .set   = set_bool,
-    .set_default_value = set_default_value_bool,
-};
-
-/* --- 8bit integer --- */
-
-static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
-                      Error **errp)
-{
-    Property *prop = opaque;
-    uint8_t *ptr = object_field_prop_ptr(obj, prop);
-
-    visit_type_uint8(v, name, ptr, errp);
-}
-
-static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
-                      Error **errp)
-{
-    Property *prop = opaque;
-    uint8_t *ptr = object_field_prop_ptr(obj, prop);
-
-    visit_type_uint8(v, name, ptr, errp);
-}
-
-void field_prop_set_default_value_int(ObjectProperty *op,
-                                      const Property *prop)
-{
-    object_property_set_default_int(op, prop->defval.i);
-}
-
-void field_prop_set_default_value_uint(ObjectProperty *op,
-                                       const Property *prop)
-{
-    object_property_set_default_uint(op, prop->defval.u);
-}
-
-const PropertyInfo prop_info_uint8 = {
-    .name  = "uint8",
-    .get   = get_uint8,
-    .set   = set_uint8,
-    .set_default_value = field_prop_set_default_value_uint,
-};
-
-/* --- 16bit integer --- */
-
-static void get_uint16(Object *obj, Visitor *v, const char *name,
-                       void *opaque, Error **errp)
-{
-    Property *prop = opaque;
-    uint16_t *ptr = object_field_prop_ptr(obj, prop);
-
-    visit_type_uint16(v, name, ptr, errp);
-}
-
-static void set_uint16(Object *obj, Visitor *v, const char *name,
-                       void *opaque, Error **errp)
-{
-    Property *prop = opaque;
-    uint16_t *ptr = object_field_prop_ptr(obj, prop);
-
-    visit_type_uint16(v, name, ptr, errp);
-}
-
-const PropertyInfo prop_info_uint16 = {
-    .name  = "uint16",
-    .get   = get_uint16,
-    .set   = set_uint16,
-    .set_default_value = field_prop_set_default_value_uint,
-};
-
-/* --- 32bit integer --- */
-
-static void get_uint32(Object *obj, Visitor *v, const char *name,
-                       void *opaque, Error **errp)
-{
-    Property *prop = opaque;
-    uint32_t *ptr = object_field_prop_ptr(obj, prop);
-
-    visit_type_uint32(v, name, ptr, errp);
-}
-
-static void set_uint32(Object *obj, Visitor *v, const char *name,
-                       void *opaque, Error **errp)
-{
-    Property *prop = opaque;
-    uint32_t *ptr = object_field_prop_ptr(obj, prop);
-
-    visit_type_uint32(v, name, ptr, errp);
-}
-
-void field_prop_get_int32(Object *obj, Visitor *v, const char *name,
-                          void *opaque, Error **errp)
-{
-    Property *prop = opaque;
-    int32_t *ptr = object_field_prop_ptr(obj, prop);
-
-    visit_type_int32(v, name, ptr, errp);
-}
-
-static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
-                      Error **errp)
-{
-    Property *prop = opaque;
-    int32_t *ptr = object_field_prop_ptr(obj, prop);
-
-    visit_type_int32(v, name, ptr, errp);
-}
-
-const PropertyInfo prop_info_uint32 = {
-    .name  = "uint32",
-    .get   = get_uint32,
-    .set   = set_uint32,
-    .set_default_value = field_prop_set_default_value_uint,
-};
-
-const PropertyInfo prop_info_int32 = {
-    .name  = "int32",
-    .get   = field_prop_get_int32,
-    .set   = set_int32,
-    .set_default_value = field_prop_set_default_value_int,
-};
-
-/* --- 64bit integer --- */
-
-static void get_uint64(Object *obj, Visitor *v, const char *name,
-                       void *opaque, Error **errp)
-{
-    Property *prop = opaque;
-    uint64_t *ptr = object_field_prop_ptr(obj, prop);
-
-    visit_type_uint64(v, name, ptr, errp);
-}
-
-static void set_uint64(Object *obj, Visitor *v, const char *name,
-                       void *opaque, Error **errp)
-{
-    Property *prop = opaque;
-    uint64_t *ptr = object_field_prop_ptr(obj, prop);
-
-    visit_type_uint64(v, name, ptr, errp);
-}
-
-static void get_int64(Object *obj, Visitor *v, const char *name,
-                      void *opaque, Error **errp)
-{
-    Property *prop = opaque;
-    int64_t *ptr = object_field_prop_ptr(obj, prop);
-
-    visit_type_int64(v, name, ptr, errp);
-}
-
-static void set_int64(Object *obj, Visitor *v, const char *name,
-                      void *opaque, Error **errp)
-{
-    Property *prop = opaque;
-    int64_t *ptr = object_field_prop_ptr(obj, prop);
-
-    visit_type_int64(v, name, ptr, errp);
-}
-
-const PropertyInfo prop_info_uint64 = {
-    .name  = "uint64",
-    .get   = get_uint64,
-    .set   = set_uint64,
-    .set_default_value = field_prop_set_default_value_uint,
-};
-
-const PropertyInfo prop_info_int64 = {
-    .name  = "int64",
-    .get   = get_int64,
-    .set   = set_int64,
-    .set_default_value = field_prop_set_default_value_int,
-};
-
-/* --- string --- */
-
-static void release_string(Object *obj, const char *name, void *opaque)
-{
-    Property *prop = opaque;
-    g_free(*(char **)object_field_prop_ptr(obj, prop));
-}
-
-static void get_string(Object *obj, Visitor *v, const char *name,
-                       void *opaque, Error **errp)
-{
-    Property *prop = opaque;
-    char **ptr = object_field_prop_ptr(obj, prop);
-
-    if (!*ptr) {
-        char *str = (char *)"";
-        visit_type_str(v, name, &str, errp);
-    } else {
-        visit_type_str(v, name, ptr, errp);
-    }
-}
-
-static void set_string(Object *obj, Visitor *v, const char *name,
-                       void *opaque, Error **errp)
-{
-    Property *prop = opaque;
-    char **ptr = object_field_prop_ptr(obj, prop);
-    char *str;
-
-    if (!visit_type_str(v, name, &str, errp)) {
-        return;
-    }
-    g_free(*ptr);
-    *ptr = str;
-}
-
-const PropertyInfo prop_info_string = {
-    .name  = "str",
-    .release = release_string,
-    .get   = get_string,
-    .set   = set_string,
-};
-
-/* --- on/off/auto --- */
-
-const PropertyInfo prop_info_on_off_auto = {
-    .name = "OnOffAuto",
-    .description = "on/off/auto",
-    .enum_table = &OnOffAuto_lookup,
-    .get = field_prop_get_enum,
-    .set = field_prop_set_enum,
-    .set_default_value = field_prop_set_default_value_enum,
-};
-
-/* --- 32bit unsigned int 'size' type --- */
-
-void field_prop_get_size32(Object *obj, Visitor *v, const char *name,
-                           void *opaque, Error **errp)
-{
-    Property *prop = opaque;
-    uint32_t *ptr = object_field_prop_ptr(obj, prop);
-    uint64_t value = *ptr;
-
-    visit_type_size(v, name, &value, errp);
-}
-
-static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
-                       Error **errp)
-{
-    Property *prop = opaque;
-    uint32_t *ptr = object_field_prop_ptr(obj, prop);
-    uint64_t value;
-
-    if (!visit_type_size(v, name, &value, errp)) {
-        return;
-    }
-
-    if (value > UINT32_MAX) {
-        error_setg(errp,
-                   "Property %s.%s doesn't take value %" PRIu64
-                   " (maximum: %u)",
-                   object_get_typename(obj), name, value, UINT32_MAX);
-        return;
-    }
-
-    *ptr = value;
-}
-
-const PropertyInfo prop_info_size32 = {
-    .name  = "size",
-    .get = field_prop_get_size32,
-    .set = set_size32,
-    .set_default_value = field_prop_set_default_value_uint,
-};
-
-/* --- support for array properties --- */
-
-static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
-                              void *opaque, Error **errp)
-{
-    /* Setter for the property which defines the length of a
-     * variable-sized property array. As well as actually setting the
-     * array-length field in the device struct, we have to create the
-     * array itself and dynamically add the corresponding properties.
-     */
-    Property *prop = opaque;
-    ObjectProperty *op = object_property_find_err(obj, name, &error_abort);
-    uint32_t *alenptr = object_field_prop_ptr(obj, prop);
-    void **arrayptr = (void *)obj + prop->arrayoffset;
-    void *eltptr;
-    const char *arrayname;
-    int i;
-
-    if (*alenptr) {
-        error_setg(errp, "array size property %s may not be set more than once",
-                   name);
-        return;
-    }
-    if (!visit_type_uint32(v, name, alenptr, errp)) {
-        return;
-    }
-    if (!*alenptr) {
-        return;
-    }
-
-    /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix;
-     * strip it off so we can get the name of the array itself.
-     */
-    assert(strncmp(name, PROP_ARRAY_LEN_PREFIX,
-                   strlen(PROP_ARRAY_LEN_PREFIX)) == 0);
-    arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX);
-
-    /* Note that it is the responsibility of the individual device's deinit
-     * to free the array proper.
-     */
-    *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize);
-    for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) {
-        g_autofree char *propname = g_strdup_printf("%s[%d]", arrayname, i);
-        Property *arrayprop = g_new0(Property, 1);
-        arrayprop->info = prop->arrayinfo;
-        /* This ugly piece of pointer arithmetic sets up the offset so
-         * that when the underlying get/set hooks call qdev_get_prop_ptr
-         * they get the right answer despite the array element not actually
-         * being inside the device struct.
-         */
-        arrayprop->offset = eltptr - (void *)obj;
-        assert(object_field_prop_ptr(obj, arrayprop) == eltptr);
-        object_property_add_field(obj, propname, arrayprop, op->allow_set);
-    }
-}
-
-const PropertyInfo prop_info_arraylen = {
-    .name = "uint32",
-    .get = get_uint32,
-    .set = set_prop_arraylen,
-    .set_default_value = field_prop_set_default_value_uint,
-};
-
 /* --- public helpers --- */
 
 static Property *qdev_prop_walk(Property *props, const char *name)
@@ -712,53 +222,6 @@ void qdev_prop_set_globals(DeviceState *dev)
                               dev->hotplugged ? NULL : &error_fatal);
 }
 
-/* --- 64bit unsigned int 'size' type --- */
-
-static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
-                     Error **errp)
-{
-    Property *prop = opaque;
-    uint64_t *ptr = object_field_prop_ptr(obj, prop);
-
-    visit_type_size(v, name, ptr, errp);
-}
-
-static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
-                     Error **errp)
-{
-    Property *prop = opaque;
-    uint64_t *ptr = object_field_prop_ptr(obj, prop);
-
-    visit_type_size(v, name, ptr, errp);
-}
-
-const PropertyInfo prop_info_size = {
-    .name  = "size",
-    .get = get_size,
-    .set = set_size,
-    .set_default_value = field_prop_set_default_value_uint,
-};
-
-/* --- object link property --- */
-
-static ObjectProperty *create_link_property(ObjectClass *oc, const char *name,
-                                            Property *prop)
-{
-    /*
-     * NOTE: object_property_allow_set_link is unconditional, but
-     *       ObjectProperty.allow_set may be set for the property too.
-     */
-    return object_class_property_add_link(oc, name, prop->link_type,
-                                          prop->offset,
-                                          object_property_allow_set_link,
-                                          OBJ_PROP_LINK_STRONG);
-}
-
-const PropertyInfo prop_info_link = {
-    .name = "link",
-    .create = create_link_property,
-};
-
 void qdev_property_add_static(DeviceState *dev, Property *prop)
 {
     object_property_add_field(OBJECT(dev), prop->qdev_prop_name, prop,
diff --git a/qom/property-types.c b/qom/property-types.c
new file mode 100644
index 0000000000..f566c05ec2
--- /dev/null
+++ b/qom/property-types.c
@@ -0,0 +1,545 @@
+#include "qemu/osdep.h"
+#include "qom/field-property.h"
+#include "qom/property-types.h"
+#include "qom/field-property-internal.h"
+#include "qapi/qapi-types-common.h"
+#include "qapi/visitor.h"
+#include "qapi/error.h"
+#include "qemu/uuid.h"
+
+void field_prop_get_enum(Object *obj, Visitor *v, const char *name,
+                         void *opaque, Error **errp)
+{
+    Property *prop = opaque;
+    int *ptr = object_field_prop_ptr(obj, prop);
+
+    visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
+}
+
+void field_prop_set_enum(Object *obj, Visitor *v, const char *name,
+                         void *opaque, Error **errp)
+{
+    Property *prop = opaque;
+    int *ptr = object_field_prop_ptr(obj, prop);
+
+    visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
+}
+
+void field_prop_set_default_value_enum(ObjectProperty *op,
+                                       const Property *prop)
+{
+    object_property_set_default_str(op,
+        qapi_enum_lookup(prop->info->enum_table, prop->defval.i));
+}
+
+const PropertyInfo prop_info_enum = {
+    .name  = "enum",
+    .get   = field_prop_get_enum,
+    .set   = field_prop_set_enum,
+    .set_default_value = field_prop_set_default_value_enum,
+};
+
+/* Bit */
+
+static uint32_t qdev_get_prop_mask(Property *prop)
+{
+    assert(prop->info == &prop_info_bit);
+    return 0x1 << prop->bitnr;
+}
+
+static void bit_prop_set(Object *obj, Property *props, bool val)
+{
+    uint32_t *p = object_field_prop_ptr(obj, props);
+    uint32_t mask = qdev_get_prop_mask(props);
+    if (val) {
+        *p |= mask;
+    } else {
+        *p &= ~mask;
+    }
+}
+
+static void prop_get_bit(Object *obj, Visitor *v, const char *name,
+                         void *opaque, Error **errp)
+{
+    Property *prop = opaque;
+    uint32_t *p = object_field_prop_ptr(obj, prop);
+    bool value = (*p & qdev_get_prop_mask(prop)) != 0;
+
+    visit_type_bool(v, name, &value, errp);
+}
+
+static void prop_set_bit(Object *obj, Visitor *v, const char *name,
+                         void *opaque, Error **errp)
+{
+    Property *prop = opaque;
+    bool value;
+
+    if (!visit_type_bool(v, name, &value, errp)) {
+        return;
+    }
+    bit_prop_set(obj, prop, value);
+}
+
+static void set_default_value_bool(ObjectProperty *op, const Property *prop)
+{
+    object_property_set_default_bool(op, prop->defval.u);
+}
+
+const PropertyInfo prop_info_bit = {
+    .name  = "bool",
+    .description = "on/off",
+    .get   = prop_get_bit,
+    .set   = prop_set_bit,
+    .set_default_value = set_default_value_bool,
+};
+
+/* Bit64 */
+
+static uint64_t qdev_get_prop_mask64(Property *prop)
+{
+    assert(prop->info == &prop_info_bit64);
+    return 0x1ull << prop->bitnr;
+}
+
+static void bit64_prop_set(Object *obj, Property *props, bool val)
+{
+    uint64_t *p = object_field_prop_ptr(obj, props);
+    uint64_t mask = qdev_get_prop_mask64(props);
+    if (val) {
+        *p |= mask;
+    } else {
+        *p &= ~mask;
+    }
+}
+
+static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
+                           void *opaque, Error **errp)
+{
+    Property *prop = opaque;
+    uint64_t *p = object_field_prop_ptr(obj, prop);
+    bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
+
+    visit_type_bool(v, name, &value, errp);
+}
+
+static void prop_set_bit64(Object *obj, Visitor *v, const char *name,
+                           void *opaque, Error **errp)
+{
+    Property *prop = opaque;
+    bool value;
+
+    if (!visit_type_bool(v, name, &value, errp)) {
+        return;
+    }
+    bit64_prop_set(obj, prop, value);
+}
+
+const PropertyInfo prop_info_bit64 = {
+    .name  = "bool",
+    .description = "on/off",
+    .get   = prop_get_bit64,
+    .set   = prop_set_bit64,
+    .set_default_value = set_default_value_bool,
+};
+
+/* --- bool --- */
+
+static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
+                     Error **errp)
+{
+    Property *prop = opaque;
+    bool *ptr = object_field_prop_ptr(obj, prop);
+
+    visit_type_bool(v, name, ptr, errp);
+}
+
+static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
+                     Error **errp)
+{
+    Property *prop = opaque;
+    bool *ptr = object_field_prop_ptr(obj, prop);
+
+    visit_type_bool(v, name, ptr, errp);
+}
+
+const PropertyInfo prop_info_bool = {
+    .name  = "bool",
+    .get   = get_bool,
+    .set   = set_bool,
+    .set_default_value = set_default_value_bool,
+};
+
+/* --- 8bit integer --- */
+
+static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
+                      Error **errp)
+{
+    Property *prop = opaque;
+    uint8_t *ptr = object_field_prop_ptr(obj, prop);
+
+    visit_type_uint8(v, name, ptr, errp);
+}
+
+static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
+                      Error **errp)
+{
+    Property *prop = opaque;
+    uint8_t *ptr = object_field_prop_ptr(obj, prop);
+
+    visit_type_uint8(v, name, ptr, errp);
+}
+
+void field_prop_set_default_value_int(ObjectProperty *op,
+                                      const Property *prop)
+{
+    object_property_set_default_int(op, prop->defval.i);
+}
+
+void field_prop_set_default_value_uint(ObjectProperty *op,
+                                       const Property *prop)
+{
+    object_property_set_default_uint(op, prop->defval.u);
+}
+
+const PropertyInfo prop_info_uint8 = {
+    .name  = "uint8",
+    .get   = get_uint8,
+    .set   = set_uint8,
+    .set_default_value = field_prop_set_default_value_uint,
+};
+
+/* --- 16bit integer --- */
+
+static void get_uint16(Object *obj, Visitor *v, const char *name,
+                       void *opaque, Error **errp)
+{
+    Property *prop = opaque;
+    uint16_t *ptr = object_field_prop_ptr(obj, prop);
+
+    visit_type_uint16(v, name, ptr, errp);
+}
+
+static void set_uint16(Object *obj, Visitor *v, const char *name,
+                       void *opaque, Error **errp)
+{
+    Property *prop = opaque;
+    uint16_t *ptr = object_field_prop_ptr(obj, prop);
+
+    visit_type_uint16(v, name, ptr, errp);
+}
+
+const PropertyInfo prop_info_uint16 = {
+    .name  = "uint16",
+    .get   = get_uint16,
+    .set   = set_uint16,
+    .set_default_value = field_prop_set_default_value_uint,
+};
+
+/* --- 32bit integer --- */
+
+static void get_uint32(Object *obj, Visitor *v, const char *name,
+                       void *opaque, Error **errp)
+{
+    Property *prop = opaque;
+    uint32_t *ptr = object_field_prop_ptr(obj, prop);
+
+    visit_type_uint32(v, name, ptr, errp);
+}
+
+static void set_uint32(Object *obj, Visitor *v, const char *name,
+                       void *opaque, Error **errp)
+{
+    Property *prop = opaque;
+    uint32_t *ptr = object_field_prop_ptr(obj, prop);
+
+    visit_type_uint32(v, name, ptr, errp);
+}
+
+void field_prop_get_int32(Object *obj, Visitor *v, const char *name,
+                          void *opaque, Error **errp)
+{
+    Property *prop = opaque;
+    int32_t *ptr = object_field_prop_ptr(obj, prop);
+
+    visit_type_int32(v, name, ptr, errp);
+}
+
+static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
+                      Error **errp)
+{
+    Property *prop = opaque;
+    int32_t *ptr = object_field_prop_ptr(obj, prop);
+
+    visit_type_int32(v, name, ptr, errp);
+}
+
+const PropertyInfo prop_info_uint32 = {
+    .name  = "uint32",
+    .get   = get_uint32,
+    .set   = set_uint32,
+    .set_default_value = field_prop_set_default_value_uint,
+};
+
+const PropertyInfo prop_info_int32 = {
+    .name  = "int32",
+    .get   = field_prop_get_int32,
+    .set   = set_int32,
+    .set_default_value = field_prop_set_default_value_int,
+};
+
+/* --- 64bit integer --- */
+
+static void get_uint64(Object *obj, Visitor *v, const char *name,
+                       void *opaque, Error **errp)
+{
+    Property *prop = opaque;
+    uint64_t *ptr = object_field_prop_ptr(obj, prop);
+
+    visit_type_uint64(v, name, ptr, errp);
+}
+
+static void set_uint64(Object *obj, Visitor *v, const char *name,
+                       void *opaque, Error **errp)
+{
+    Property *prop = opaque;
+    uint64_t *ptr = object_field_prop_ptr(obj, prop);
+
+    visit_type_uint64(v, name, ptr, errp);
+}
+
+static void get_int64(Object *obj, Visitor *v, const char *name,
+                      void *opaque, Error **errp)
+{
+    Property *prop = opaque;
+    int64_t *ptr = object_field_prop_ptr(obj, prop);
+
+    visit_type_int64(v, name, ptr, errp);
+}
+
+static void set_int64(Object *obj, Visitor *v, const char *name,
+                      void *opaque, Error **errp)
+{
+    Property *prop = opaque;
+    int64_t *ptr = object_field_prop_ptr(obj, prop);
+
+    visit_type_int64(v, name, ptr, errp);
+}
+
+const PropertyInfo prop_info_uint64 = {
+    .name  = "uint64",
+    .get   = get_uint64,
+    .set   = set_uint64,
+    .set_default_value = field_prop_set_default_value_uint,
+};
+
+const PropertyInfo prop_info_int64 = {
+    .name  = "int64",
+    .get   = get_int64,
+    .set   = set_int64,
+    .set_default_value = field_prop_set_default_value_int,
+};
+
+/* --- string --- */
+
+static void release_string(Object *obj, const char *name, void *opaque)
+{
+    Property *prop = opaque;
+    g_free(*(char **)object_field_prop_ptr(obj, prop));
+}
+
+static void get_string(Object *obj, Visitor *v, const char *name,
+                       void *opaque, Error **errp)
+{
+    Property *prop = opaque;
+    char **ptr = object_field_prop_ptr(obj, prop);
+
+    if (!*ptr) {
+        char *str = (char *)"";
+        visit_type_str(v, name, &str, errp);
+    } else {
+        visit_type_str(v, name, ptr, errp);
+    }
+}
+
+static void set_string(Object *obj, Visitor *v, const char *name,
+                       void *opaque, Error **errp)
+{
+    Property *prop = opaque;
+    char **ptr = object_field_prop_ptr(obj, prop);
+    char *str;
+
+    if (!visit_type_str(v, name, &str, errp)) {
+        return;
+    }
+    g_free(*ptr);
+    *ptr = str;
+}
+
+const PropertyInfo prop_info_string = {
+    .name  = "str",
+    .release = release_string,
+    .get   = get_string,
+    .set   = set_string,
+};
+
+/* --- on/off/auto --- */
+
+const PropertyInfo prop_info_on_off_auto = {
+    .name = "OnOffAuto",
+    .description = "on/off/auto",
+    .enum_table = &OnOffAuto_lookup,
+    .get = field_prop_get_enum,
+    .set = field_prop_set_enum,
+    .set_default_value = field_prop_set_default_value_enum,
+};
+
+/* --- 32bit unsigned int 'size' type --- */
+
+void field_prop_get_size32(Object *obj, Visitor *v, const char *name,
+                           void *opaque, Error **errp)
+{
+    Property *prop = opaque;
+    uint32_t *ptr = object_field_prop_ptr(obj, prop);
+    uint64_t value = *ptr;
+
+    visit_type_size(v, name, &value, errp);
+}
+
+static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
+                       Error **errp)
+{
+    Property *prop = opaque;
+    uint32_t *ptr = object_field_prop_ptr(obj, prop);
+    uint64_t value;
+
+    if (!visit_type_size(v, name, &value, errp)) {
+        return;
+    }
+
+    if (value > UINT32_MAX) {
+        error_setg(errp,
+                   "Property %s.%s doesn't take value %" PRIu64
+                   " (maximum: %u)",
+                   object_get_typename(obj), name, value, UINT32_MAX);
+        return;
+    }
+
+    *ptr = value;
+}
+
+const PropertyInfo prop_info_size32 = {
+    .name  = "size",
+    .get = field_prop_get_size32,
+    .set = set_size32,
+    .set_default_value = field_prop_set_default_value_uint,
+};
+
+/* --- support for array properties --- */
+
+static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
+                              void *opaque, Error **errp)
+{
+    /* Setter for the property which defines the length of a
+     * variable-sized property array. As well as actually setting the
+     * array-length field in the device struct, we have to create the
+     * array itself and dynamically add the corresponding properties.
+     */
+    Property *prop = opaque;
+    ObjectProperty *op = object_property_find_err(obj, name, &error_abort);
+    uint32_t *alenptr = object_field_prop_ptr(obj, prop);
+    void **arrayptr = (void *)obj + prop->arrayoffset;
+    void *eltptr;
+    const char *arrayname;
+    int i;
+
+    if (*alenptr) {
+        error_setg(errp, "array size property %s may not be set more than once",
+                   name);
+        return;
+    }
+    if (!visit_type_uint32(v, name, alenptr, errp)) {
+        return;
+    }
+    if (!*alenptr) {
+        return;
+    }
+
+    /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix;
+     * strip it off so we can get the name of the array itself.
+     */
+    assert(strncmp(name, PROP_ARRAY_LEN_PREFIX,
+                   strlen(PROP_ARRAY_LEN_PREFIX)) == 0);
+    arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX);
+
+    /* Note that it is the responsibility of the individual device's deinit
+     * to free the array proper.
+     */
+    *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize);
+    for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) {
+        g_autofree char *propname = g_strdup_printf("%s[%d]", arrayname, i);
+        Property *arrayprop = g_new0(Property, 1);
+        arrayprop->info = prop->arrayinfo;
+        /* This ugly piece of pointer arithmetic sets up the offset so
+         * that when the underlying get/set hooks call qdev_get_prop_ptr
+         * they get the right answer despite the array element not actually
+         * being inside the device struct.
+         */
+        arrayprop->offset = eltptr - (void *)obj;
+        assert(object_field_prop_ptr(obj, arrayprop) == eltptr);
+        object_property_add_field(obj, propname, arrayprop, op->allow_set);
+    }
+}
+
+const PropertyInfo prop_info_arraylen = {
+    .name = "uint32",
+    .get = get_uint32,
+    .set = set_prop_arraylen,
+    .set_default_value = field_prop_set_default_value_uint,
+};
+
+/* --- 64bit unsigned int 'size' type --- */
+
+static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
+                     Error **errp)
+{
+    Property *prop = opaque;
+    uint64_t *ptr = object_field_prop_ptr(obj, prop);
+
+    visit_type_size(v, name, ptr, errp);
+}
+
+static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
+                     Error **errp)
+{
+    Property *prop = opaque;
+    uint64_t *ptr = object_field_prop_ptr(obj, prop);
+
+    visit_type_size(v, name, ptr, errp);
+}
+
+const PropertyInfo prop_info_size = {
+    .name  = "size",
+    .get = get_size,
+    .set = set_size,
+    .set_default_value = field_prop_set_default_value_uint,
+};
+
+/* --- object link property --- */
+
+static ObjectProperty *create_link_property(ObjectClass *oc, const char *name,
+                                            Property *prop)
+{
+    /*
+     * NOTE: object_property_allow_set_link is unconditional, but
+     *       ObjectProperty.allow_set may be set for the property too.
+     */
+    return object_class_property_add_link(oc, name, prop->link_type,
+                                          prop->offset,
+                                          object_property_allow_set_link,
+                                          OBJ_PROP_LINK_STRONG);
+}
+
+const PropertyInfo prop_info_link = {
+    .name = "link",
+    .create = create_link_property,
+};
diff --git a/qom/meson.build b/qom/meson.build
index e83794454d..7fdfd6fe7b 100644
--- a/qom/meson.build
+++ b/qom/meson.build
@@ -5,6 +5,7 @@ qom_ss.add(files(
   'object_interfaces.c',
   'qom-qobject.c',
   'field-property.c',
+  'property-types.c',
 ))
 
 qmp_ss.add(files('qom-qmp-cmds.c'))
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 42/44] qom: Include static property API reference in documentation
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (40 preceding siblings ...)
  2020-11-04 16:00 ` [PATCH v2 41/44] qdev: Move base property types to qom/property-types.c Eduardo Habkost
@ 2020-11-04 16:00 ` Eduardo Habkost
  2020-11-04 16:00 ` [PATCH v2 43/44] tests: Use field properties at check-qom-proplist test case Eduardo Habkost
                   ` (3 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 16:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

Add new doc comments and reformat the existing ones,
and include the static-properties.h API reference in
docs/devel/qom.rst.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Changes v1 -> v2:
* Redone patch after changes in previous patches in the series
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 docs/devel/qom.rst           |  17 +++++-
 include/qom/field-property.h |  47 ++++++++++++---
 include/qom/property-types.h | 111 ++++++++++++++++++++++++++++++++++-
 3 files changed, 165 insertions(+), 10 deletions(-)

diff --git a/docs/devel/qom.rst b/docs/devel/qom.rst
index 42d0dc4f4d..9e43aa46f2 100644
--- a/docs/devel/qom.rst
+++ b/docs/devel/qom.rst
@@ -376,6 +376,21 @@ the OBJECT_DEFINE_ABSTRACT_TYPE() macro can be used instead:
 
 
 API Reference
--------------
+=============
+
+Core QOM API Reference
+----------------------
 
 .. kernel-doc:: include/qom/object.h
+
+
+Field Property API Reference
+----------------------------
+
+.. kernel-doc:: include/qom/field-property.h
+
+
+Property Types Reference
+------------------------
+
+.. kernel-doc:: include/qom/property-types.h
diff --git a/include/qom/field-property.h b/include/qom/field-property.h
index bdc89b38a6..bc866e1c93 100644
--- a/include/qom/field-property.h
+++ b/include/qom/field-property.h
@@ -8,15 +8,16 @@
 #include "qapi/util.h"
 
 /**
- * Property:
- * @set_default: true if the default value should be set from @defval,
- *    in which case @info->set_default_value must not be NULL
- *    (if false then no default value is set by the property system
- *     and the field retains whatever value it was given by instance_init).
- * @defval: default value for the property. This is used only if @set_default
- *     is true.
+ * struct Property: definition of a field property
+ *
+ * Field properties are used to read and write fields in object
+ * instance structs.  Field properties are declared using
+ * ``DEFINE_PROP_<type>`` (for property arrays registered using
+ * device_class_set_props()), or using ``PROP_<type>`` (for
+ * object_class_property_add_field() calls).
  */
 struct Property {
+    /* private: */
     /**
      * @qdev_prop_name: qdev property name
      *
@@ -28,27 +29,59 @@ struct Property {
     const PropertyInfo *info;
     ptrdiff_t    offset;
     uint8_t      bitnr;
+    /**
+     * @set_default: true if the default value should be set from @defval,
+     *    in which case @info->set_default_value must not be NULL
+     *    (if false then no default value is set by the property system
+     *     and the field retains whatever value it was given by instance_init).
+     */
     bool         set_default;
+    /**
+     * @defval: default value for the property. This is used only if @set_default
+     *     is true.
+     */
     union {
         int64_t i;
         uint64_t u;
     } defval;
+    /* private: */
     int          arrayoffset;
     const PropertyInfo *arrayinfo;
     int          arrayfieldsize;
     const char   *link_type;
 };
 
+/**
+ * struct PropertyInfo: information on a specific QOM property type
+ */
 struct PropertyInfo {
+    /** @name: property type name */
     const char *name;
+    /** @description: Description for help text */
     const char *description;
+    /** @enum_table: Used by field_prop_get_enum() and field_prop_set_enum() */
     const QEnumLookup *enum_table;
+    /** @print: String formatting function, for the human monitor */
     int (*print)(Object *obj, Property *prop, char *dest, size_t len);
+    /** @set_default_value: Callback for initializing the default value */
     void (*set_default_value)(ObjectProperty *op, const Property *prop);
+    /** @create: Optional callback for creation of property */
     ObjectProperty *(*create)(ObjectClass *oc, const char *name,
                               Property *prop);
+    /**
+     * @get: Property getter.  The opaque parameter will point to
+     *        the &Property struct for the property.
+     */
     ObjectPropertyAccessor *get;
+    /**
+     * @set: Property setter.  The opaque parameter will point to
+     *        the &Property struct for the property.
+     */
     ObjectPropertyAccessor *set;
+    /**
+     * @release: Optional release function, called when the object
+     * is destroyed
+     */
     ObjectPropertyRelease *release;
 };
 
diff --git a/include/qom/property-types.h b/include/qom/property-types.h
index 75f758e835..a891dffb6e 100644
--- a/include/qom/property-types.h
+++ b/include/qom/property-types.h
@@ -39,6 +39,14 @@ extern const PropertyInfo prop_info_link;
 #define DEFINE_PROP_SIGNED_NODEFAULT(_name, _state, _field, _prop, _type) \
     DEFINE_PROP(_name, _state, _field, _prop, _type)
 
+/**
+ * DEFINE_PROP_BIT: Define bit property in uint32_t field
+ * @_name: name of the property
+ * @_state: name of the object state structure type
+ * @_field: name of ``uint32_t`` field in @_state
+ * @_bit: bit offset in @_field
+ * @_defval: default value for bit
+ */
 #define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval)   \
     DEFINE_PROP(_name, _state, _field, prop_info_bit, uint32_t, \
                 .bitnr       = (_bit),                          \
@@ -53,12 +61,27 @@ extern const PropertyInfo prop_info_link;
 #define DEFINE_PROP_UNSIGNED_NODEFAULT(_name, _state, _field, _prop, _type) \
     DEFINE_PROP(_name, _state, _field, _prop, _type)
 
+/**
+ * DEFINE_PROP_BIT64: Define bit property in uint64_t field
+ * @_name: name of the property
+ * @_state: name of the object state structure type
+ * @_field: name of ``uint64_t`` field in @_state
+ * @_bit: bit offset in @_field
+ * @_defval: default value for bit
+ */
 #define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval)   \
     DEFINE_PROP(_name, _state, _field, prop_info_bit64, uint64_t, \
                 .bitnr    = (_bit),                               \
                 .set_default = true,                              \
                 .defval.u  = (bool)_defval)
 
+/**
+ * DEFINE_PROP_BOOL:
+ * @_name: name of the property
+ * @_state: name of the object state structure type
+ * @_field: name of ``bool`` field in @_state
+ * @_defval: default value of property
+ */
 #define DEFINE_PROP_BOOL(_name, _state, _field, _defval)     \
     DEFINE_PROP(_name, _state, _field, prop_info_bool, bool, \
                 .set_default = true,                         \
@@ -71,9 +94,10 @@ extern const PropertyInfo prop_info_link;
  * @_name: name of the array
  * @_state: name of the device state structure type
  * @_field: uint32_t field in @_state to hold the array length
- * @_arrayfield: field in @_state (of type '@_arraytype *') which
+ * @_arrayfield: field in @_state (of type ``_arraytype *``) which
  *               will point to the array
- * @_arrayprop: PropertyInfo defining what property the array elements have
+ * @_arrayprop: #PropertyInfo variable defining property type of
+ *              array elements
  * @_arraytype: C type of the array elements
  *
  * Define device properties for a variable-length array _name.  A
@@ -100,31 +124,114 @@ extern const PropertyInfo prop_info_link;
                 .arrayfieldsize = sizeof(_arraytype),          \
                 .arrayoffset = offsetof(_state, _arrayfield))
 
+/**
+ * DEFINE_PROP_LINK: Define object link property
+ * @_name: name of the property
+ * @_state: name of the object state structure type
+ * @_field: name of field in @_state holding the property value
+ * @_type: QOM type name of link target
+ * @_ptr_type: Type of field @_field in struct @_state
+ */
 #define DEFINE_PROP_LINK(_name, _state, _field, _type, _ptr_type)     \
     DEFINE_PROP(_name, _state, _field, prop_info_link, _ptr_type,     \
                 .link_type  = _type)
 
+/**
+ * DEFINE_PROP_UINT8: Define uint8 property
+ * @_n: name of the property
+ * @_s: name of the object state structure type
+ * @_f: name of ``uint8_t`` field in @_s
+ * @_d: default value of property
+ */
 #define DEFINE_PROP_UINT8(_n, _s, _f, _d)                       \
     DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint8, uint8_t)
+/**
+ * DEFINE_PROP_UINT16: Define uint16 property
+ * @_n: name of the property
+ * @_s: name of the object state structure type
+ * @_f: name of ``uint16_t`` field in @_s
+ * @_d: default value of property
+ */
 #define DEFINE_PROP_UINT16(_n, _s, _f, _d)                      \
     DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint16, uint16_t)
+/**
+ * DEFINE_PROP_UINT32: Define uint32 property
+ * @_n: name of the property
+ * @_s: name of the object state structure type
+ * @_f: name of ``uint32_t`` field in @_s
+ * @_d: default value of property
+ */
 #define DEFINE_PROP_UINT32(_n, _s, _f, _d)                      \
     DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint32, uint32_t)
+/**
+ * DEFINE_PROP_INT32: Define int32 property
+ * @_n: name of the property
+ * @_s: name of the object state structure type
+ * @_f: name of ``int32_t`` field in @_s
+ * @_d: default value of property
+ */
 #define DEFINE_PROP_INT32(_n, _s, _f, _d)                      \
     DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_int32, int32_t)
+/**
+ * DEFINE_PROP_UINT64: Define uint64 property
+ * @_n: name of the property
+ * @_s: name of the object state structure type
+ * @_f: name of ``uint64_t`` field in @_s
+ * @_d: default value of property
+ */
 #define DEFINE_PROP_UINT64(_n, _s, _f, _d)                      \
     DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint64, uint64_t)
+/**
+ * DEFINE_PROP_INT64: Define int64 property
+ * @_n: name of the property
+ * @_s: name of the object state structure type
+ * @_f: name of ``int64_t`` field in @_s
+ * @_d: default value of property
+ */
 #define DEFINE_PROP_INT64(_n, _s, _f, _d)                      \
     DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_int64, int64_t)
+/**
+ * DEFINE_PROP_SIZE: Define uint64 property
+ * @_n: name of the property
+ * @_s: name of the object state structure type
+ * @_f: name of ``uint64_t`` field in @_s
+ * @_d: default value of property
+ */
 #define DEFINE_PROP_SIZE(_n, _s, _f, _d)                       \
     DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_size, uint64_t)
+/**
+ * DEFINE_PROP_STRING:
+ * @_n: name of the property
+ * @_s: name of the object state structure type
+ * @_f: name of ``char *`` field in @_state
+ */
 #define DEFINE_PROP_STRING(_n, _s, _f)             \
     DEFINE_PROP(_n, _s, _f, prop_info_string, char*)
+/**
+ * DEFINE_PROP_ON_OFF_AUTO: Define OnOffAuto property
+ * @_n: name of the property
+ * @_s: name of the object state structure type
+ * @_f: name of ``OnOffAuto`` field in @_s
+ * @_d: default value of property
+ */
 #define DEFINE_PROP_ON_OFF_AUTO(_n, _s, _f, _d) \
     DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_on_off_auto, OnOffAuto)
+/**
+ * DEFINE_PROP_SIZE32: Define uint32 property
+ * @_n: name of the property
+ * @_s: name of the object state structure type
+ * @_f: name of ``uint32_t`` field in @_s
+ * @_d: default value of property
+ */
 #define DEFINE_PROP_SIZE32(_n, _s, _f, _d)                       \
     DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_size32, uint32_t)
 
+/**
+ * DEFINE_PROP_END_OF_LIST: Mark end of property array
+ *
+ * This must be the last entry in #Property arrays when calling
+ * object_class_add_static_props().
+ */
 #define DEFINE_PROP_END_OF_LIST()               \
     {}
 
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 43/44] tests: Use field properties at check-qom-proplist test case
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (41 preceding siblings ...)
  2020-11-04 16:00 ` [PATCH v2 42/44] qom: Include static property API reference in documentation Eduardo Habkost
@ 2020-11-04 16:00 ` Eduardo Habkost
  2020-11-04 16:00 ` [PATCH v2 44/44] machine: Register most properties as field properties Eduardo Habkost
                   ` (2 subsequent siblings)
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 16:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

Use field properties for the bool and string properties used at
check-qom-proplist.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Changes v2:
* Redone patch using PROP_* instead of DEFINE_PROP_*
---
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
---
 include/qom/property-types.h |  2 +-
 tests/check-qom-proplist.c   | 64 +++++-------------------------------
 2 files changed, 10 insertions(+), 56 deletions(-)

diff --git a/include/qom/property-types.h b/include/qom/property-types.h
index a891dffb6e..3a36e1fec5 100644
--- a/include/qom/property-types.h
+++ b/include/qom/property-types.h
@@ -242,7 +242,7 @@ extern const PropertyInfo prop_info_link;
  */
 
 #define FIELD_PROP(def) \
-    ({ static Property _p = def; &p; })
+    ({ static Property _p = def; &_p; })
 
 #define PROP_SIGNED(...) \
     FIELD_PROP(DEFINE_PROP_SIGNED(NULL, __VA_ARGS__))
diff --git a/tests/check-qom-proplist.c b/tests/check-qom-proplist.c
index 1b76581980..b960df1964 100644
--- a/tests/check-qom-proplist.c
+++ b/tests/check-qom-proplist.c
@@ -26,6 +26,9 @@
 #include "qemu/option.h"
 #include "qemu/config-file.h"
 #include "qom/object_interfaces.h"
+#include "qom/field-property.h"
+#include "qom/field-property-internal.h"
+#include "qom/property-types.h"
 
 
 #define TYPE_DUMMY "qemu-dummy"
@@ -68,24 +71,6 @@ struct DummyObjectClass {
 };
 
 
-static void dummy_set_bv(Object *obj,
-                         bool value,
-                         Error **errp)
-{
-    DummyObject *dobj = DUMMY_OBJECT(obj);
-
-    dobj->bv = value;
-}
-
-static bool dummy_get_bv(Object *obj,
-                         Error **errp)
-{
-    DummyObject *dobj = DUMMY_OBJECT(obj);
-
-    return dobj->bv;
-}
-
-
 static void dummy_set_av(Object *obj,
                          int value,
                          Error **errp)
@@ -103,39 +88,18 @@ static int dummy_get_av(Object *obj,
     return dobj->av;
 }
 
-
-static void dummy_set_sv(Object *obj,
-                         const char *value,
-                         Error **errp)
-{
-    DummyObject *dobj = DUMMY_OBJECT(obj);
-
-    g_free(dobj->sv);
-    dobj->sv = g_strdup(value);
-}
-
-static char *dummy_get_sv(Object *obj,
-                          Error **errp)
-{
-    DummyObject *dobj = DUMMY_OBJECT(obj);
-
-    return g_strdup(dobj->sv);
-}
-
-
 static void dummy_init(Object *obj)
 {
-    object_property_add_bool(obj, "bv",
-                             dummy_get_bv,
-                             dummy_set_bv);
+    object_property_add_field(obj, "bv",
+                              PROP_BOOL(DummyObject, bv, false),
+                              prop_allow_set_always);
 }
 
-
 static void dummy_class_init(ObjectClass *cls, void *data)
 {
-    object_class_property_add_str(cls, "sv",
-                                  dummy_get_sv,
-                                  dummy_set_sv);
+    object_class_property_add_field(cls, "sv",
+                                    PROP_STRING(DummyObject, sv),
+                                    prop_allow_set_always);
     object_class_property_add_enum(cls, "av",
                                    "DummyAnimal",
                                    &dummy_animal_map,
@@ -143,21 +107,11 @@ static void dummy_class_init(ObjectClass *cls, void *data)
                                    dummy_set_av);
 }
 
-
-static void dummy_finalize(Object *obj)
-{
-    DummyObject *dobj = DUMMY_OBJECT(obj);
-
-    g_free(dobj->sv);
-}
-
-
 static const TypeInfo dummy_info = {
     .name          = TYPE_DUMMY,
     .parent        = TYPE_OBJECT,
     .instance_size = sizeof(DummyObject),
     .instance_init = dummy_init,
-    .instance_finalize = dummy_finalize,
     .class_size = sizeof(DummyObjectClass),
     .class_init = dummy_class_init,
     .interfaces = (InterfaceInfo[]) {
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH v2 44/44] machine: Register most properties as field properties
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (42 preceding siblings ...)
  2020-11-04 16:00 ` [PATCH v2 43/44] tests: Use field properties at check-qom-proplist test case Eduardo Habkost
@ 2020-11-04 16:00 ` Eduardo Habkost
  2020-11-04 16:36 ` [PATCH v2 00/44] Make qdev static property API usable by any QOM type no-reply
  2020-11-06  9:45 ` Kevin Wolf
  45 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 16:00 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Paolo Bonzini,
	Stefan Berger

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Changes v1 -> v2:
* Redone using object_class_add_property_field() + PROP_* macros
  instead of DEFINE_PROP_* array, as suggested by Paolo
---
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
Cc: qemu-devel@nongnu.org
---
 hw/core/machine.c | 256 +++++++---------------------------------------
 1 file changed, 39 insertions(+), 217 deletions(-)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index 98b87f76cb..2d39b56191 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -27,6 +27,8 @@
 #include "hw/pci/pci.h"
 #include "hw/mem/nvdimm.h"
 #include "migration/vmstate.h"
+#include "qom/field-property.h"
+#include "qom/property-types.h"
 
 GlobalProperty hw_compat_5_1[] = {
     { "vhost-scsi", "num_queues", "1"},
@@ -212,81 +214,6 @@ GlobalProperty hw_compat_2_1[] = {
 };
 const size_t hw_compat_2_1_len = G_N_ELEMENTS(hw_compat_2_1);
 
-static char *machine_get_kernel(Object *obj, Error **errp)
-{
-    MachineState *ms = MACHINE(obj);
-
-    return g_strdup(ms->kernel_filename);
-}
-
-static void machine_set_kernel(Object *obj, const char *value, Error **errp)
-{
-    MachineState *ms = MACHINE(obj);
-
-    g_free(ms->kernel_filename);
-    ms->kernel_filename = g_strdup(value);
-}
-
-static char *machine_get_initrd(Object *obj, Error **errp)
-{
-    MachineState *ms = MACHINE(obj);
-
-    return g_strdup(ms->initrd_filename);
-}
-
-static void machine_set_initrd(Object *obj, const char *value, Error **errp)
-{
-    MachineState *ms = MACHINE(obj);
-
-    g_free(ms->initrd_filename);
-    ms->initrd_filename = g_strdup(value);
-}
-
-static char *machine_get_append(Object *obj, Error **errp)
-{
-    MachineState *ms = MACHINE(obj);
-
-    return g_strdup(ms->kernel_cmdline);
-}
-
-static void machine_set_append(Object *obj, const char *value, Error **errp)
-{
-    MachineState *ms = MACHINE(obj);
-
-    g_free(ms->kernel_cmdline);
-    ms->kernel_cmdline = g_strdup(value);
-}
-
-static char *machine_get_dtb(Object *obj, Error **errp)
-{
-    MachineState *ms = MACHINE(obj);
-
-    return g_strdup(ms->dtb);
-}
-
-static void machine_set_dtb(Object *obj, const char *value, Error **errp)
-{
-    MachineState *ms = MACHINE(obj);
-
-    g_free(ms->dtb);
-    ms->dtb = g_strdup(value);
-}
-
-static char *machine_get_dumpdtb(Object *obj, Error **errp)
-{
-    MachineState *ms = MACHINE(obj);
-
-    return g_strdup(ms->dumpdtb);
-}
-
-static void machine_set_dumpdtb(Object *obj, const char *value, Error **errp)
-{
-    MachineState *ms = MACHINE(obj);
-
-    g_free(ms->dumpdtb);
-    ms->dumpdtb = g_strdup(value);
-}
-
 static void machine_get_phandle_start(Object *obj, Visitor *v,
                                       const char *name, void *opaque,
                                       Error **errp)
@@ -311,48 +238,6 @@ static void machine_set_phandle_start(Object *obj, Visitor *v,
     ms->phandle_start = value;
 }
 
-static char *machine_get_dt_compatible(Object *obj, Error **errp)
-{
-    MachineState *ms = MACHINE(obj);
-
-    return g_strdup(ms->dt_compatible);
-}
-
-static void machine_set_dt_compatible(Object *obj, const char *value, Error **errp)
-{
-    MachineState *ms = MACHINE(obj);
-
-    g_free(ms->dt_compatible);
-    ms->dt_compatible = g_strdup(value);
-}
-
-static bool machine_get_dump_guest_core(Object *obj, Error **errp)
-{
-    MachineState *ms = MACHINE(obj);
-
-    return ms->dump_guest_core;
-}
-
-static void machine_set_dump_guest_core(Object *obj, bool value, Error **errp)
-{
-    MachineState *ms = MACHINE(obj);
-
-    ms->dump_guest_core = value;
-}
-
-static bool machine_get_mem_merge(Object *obj, Error **errp)
-{
-    MachineState *ms = MACHINE(obj);
-
-    return ms->mem_merge;
-}
-
-static void machine_set_mem_merge(Object *obj, bool value, Error **errp)
-{
-    MachineState *ms = MACHINE(obj);
-
-    ms->mem_merge = value;
-}
 
 static bool machine_get_usb(Object *obj, Error **errp)
 {
@@ -369,49 +254,6 @@ static void machine_set_usb(Object *obj, bool value, Error **errp)
     ms->usb_disabled = !value;
 }
 
-static bool machine_get_graphics(Object *obj, Error **errp)
-{
-    MachineState *ms = MACHINE(obj);
-
-    return ms->enable_graphics;
-}
-
-static void machine_set_graphics(Object *obj, bool value, Error **errp)
-{
-    MachineState *ms = MACHINE(obj);
-
-    ms->enable_graphics = value;
-}
-
-static char *machine_get_firmware(Object *obj, Error **errp)
-{
-    MachineState *ms = MACHINE(obj);
-
-    return g_strdup(ms->firmware);
-}
-
-static void machine_set_firmware(Object *obj, const char *value, Error **errp)
-{
-    MachineState *ms = MACHINE(obj);
-
-    g_free(ms->firmware);
-    ms->firmware = g_strdup(value);
-}
-
-static void machine_set_suppress_vmdesc(Object *obj, bool value, Error **errp)
-{
-    MachineState *ms = MACHINE(obj);
-
-    ms->suppress_vmdesc = value;
-}
-
-static bool machine_get_suppress_vmdesc(Object *obj, Error **errp)
-{
-    MachineState *ms = MACHINE(obj);
-
-    return ms->suppress_vmdesc;
-}
-
 static char *machine_get_memory_encryption(Object *obj, Error **errp)
 {
     MachineState *ms = MACHINE(obj);
@@ -432,7 +274,7 @@ static void machine_set_memory_encryption(Object *obj, const char *value,
      * so there's no point in it trying to merge areas.
      */
     if (value) {
-        machine_set_mem_merge(obj, false, errp);
+        ms->mem_merge = false;
     }
 }
 
@@ -520,21 +362,6 @@ static void validate_sysbus_device(SysBusDevice *sbdev, void *opaque)
     }
 }
 
-static char *machine_get_memdev(Object *obj, Error **errp)
-{
-    MachineState *ms = MACHINE(obj);
-
-    return g_strdup(ms->ram_memdev_id);
-}
-
-static void machine_set_memdev(Object *obj, const char *value, Error **errp)
-{
-    MachineState *ms = MACHINE(obj);
-
-    g_free(ms->ram_memdev_id);
-    ms->ram_memdev_id = g_strdup(value);
-}
-
 
 static void machine_init_notify(Notifier *notifier, void *data)
 {
@@ -774,28 +601,29 @@ static void machine_class_init(ObjectClass *oc, void *data)
      */
     mc->numa_mem_align_shift = 23;
 
-    object_class_property_add_str(oc, "kernel",
-        machine_get_kernel, machine_set_kernel);
+    object_class_property_add_field(oc, "kernel",
+                                    PROP_STRING(MachineState, kernel_filename),
+                                    prop_allow_set_always);
     object_class_property_set_description(oc, "kernel",
         "Linux kernel image file");
-
-    object_class_property_add_str(oc, "initrd",
-        machine_get_initrd, machine_set_initrd);
+    object_class_property_add_field(oc, "initrd",
+                                    PROP_STRING(MachineState, initrd_filename),
+                                    prop_allow_set_always);
     object_class_property_set_description(oc, "initrd",
         "Linux initial ramdisk file");
-
-    object_class_property_add_str(oc, "append",
-        machine_get_append, machine_set_append);
+    object_class_property_add_field(oc, "append",
+                                    PROP_STRING(MachineState, kernel_cmdline),
+                                    prop_allow_set_always);
     object_class_property_set_description(oc, "append",
         "Linux kernel command line");
-
-    object_class_property_add_str(oc, "dtb",
-        machine_get_dtb, machine_set_dtb);
+    object_class_property_add_field(oc, "dtb",
+                                    PROP_STRING(MachineState, dtb),
+                                    prop_allow_set_always);
     object_class_property_set_description(oc, "dtb",
         "Linux kernel device tree file");
-
-    object_class_property_add_str(oc, "dumpdtb",
-        machine_get_dumpdtb, machine_set_dumpdtb);
+    object_class_property_add_field(oc, "dumpdtb",
+                                    PROP_STRING(MachineState, dumpdtb),
+                                    prop_allow_set_always);
     object_class_property_set_description(oc, "dumpdtb",
         "Dump current dtb to a file and quit");
 
@@ -805,18 +633,20 @@ static void machine_class_init(ObjectClass *oc, void *data)
     object_class_property_set_description(oc, "phandle-start",
         "The first phandle ID we may generate dynamically");
 
-    object_class_property_add_str(oc, "dt-compatible",
-        machine_get_dt_compatible, machine_set_dt_compatible);
+    object_class_property_add_field(oc, "dt-compatible",
+                                    PROP_STRING(MachineState, dt_compatible),
+                                    prop_allow_set_always);
     object_class_property_set_description(oc, "dt-compatible",
         "Overrides the \"compatible\" property of the dt root node");
 
-    object_class_property_add_bool(oc, "dump-guest-core",
-        machine_get_dump_guest_core, machine_set_dump_guest_core);
+    object_class_property_add_field(oc, "dump-guest-core",
+                                    PROP_BOOL(MachineState, dump_guest_core, true),
+                                    prop_allow_set_always);
     object_class_property_set_description(oc, "dump-guest-core",
         "Include guest memory in a core dump");
-
-    object_class_property_add_bool(oc, "mem-merge",
-        machine_get_mem_merge, machine_set_mem_merge);
+    object_class_property_add_field(oc, "mem-merge",
+                                    PROP_BOOL(MachineState, mem_merge, true),
+                                    prop_allow_set_always);
     object_class_property_set_description(oc, "mem-merge",
         "Enable/disable memory merge support");
 
@@ -825,18 +655,20 @@ static void machine_class_init(ObjectClass *oc, void *data)
     object_class_property_set_description(oc, "usb",
         "Set on/off to enable/disable usb");
 
-    object_class_property_add_bool(oc, "graphics",
-        machine_get_graphics, machine_set_graphics);
+    object_class_property_add_field(oc, "graphics",
+                                    PROP_BOOL(MachineState, enable_graphics, true),
+                                    prop_allow_set_always);
     object_class_property_set_description(oc, "graphics",
         "Set on/off to enable/disable graphics emulation");
 
-    object_class_property_add_str(oc, "firmware",
-        machine_get_firmware, machine_set_firmware);
+    object_class_property_add_field(oc, "firmware",
+                                    PROP_STRING(MachineState, firmware),
+                                    prop_allow_set_always);
     object_class_property_set_description(oc, "firmware",
         "Firmware image");
-
-    object_class_property_add_bool(oc, "suppress-vmdesc",
-        machine_get_suppress_vmdesc, machine_set_suppress_vmdesc);
+    object_class_property_add_field(oc, "suppress-vmdesc",
+                                    PROP_BOOL(MachineState, suppress_vmdesc, false),
+                                    prop_allow_set_always);
     object_class_property_set_description(oc, "suppress-vmdesc",
         "Set on to disable self-describing migration");
 
@@ -845,8 +677,9 @@ static void machine_class_init(ObjectClass *oc, void *data)
     object_class_property_set_description(oc, "memory-encryption",
         "Set memory encryption object to use");
 
-    object_class_property_add_str(oc, "memory-backend",
-                                  machine_get_memdev, machine_set_memdev);
+    object_class_property_add_field(oc, "memory-backend",
+                                    PROP_STRING(MachineState, ram_memdev_id),
+                                    prop_allow_set_always);
     object_class_property_set_description(oc, "memory-backend",
                                           "Set RAM backend"
                                           "Valid value is ID of hostmem based backend");
@@ -873,10 +706,6 @@ static void machine_initfn(Object *obj)
     MachineState *ms = MACHINE(obj);
     MachineClass *mc = MACHINE_GET_CLASS(obj);
 
-    ms->dump_guest_core = true;
-    ms->mem_merge = true;
-    ms->enable_graphics = true;
-
     if (mc->nvdimm_supported) {
         Object *obj = OBJECT(ms);
 
@@ -921,13 +750,6 @@ static void machine_finalize(Object *obj)
 {
     MachineState *ms = MACHINE(obj);
 
-    g_free(ms->kernel_filename);
-    g_free(ms->initrd_filename);
-    g_free(ms->kernel_cmdline);
-    g_free(ms->dtb);
-    g_free(ms->dumpdtb);
-    g_free(ms->dt_compatible);
-    g_free(ms->firmware);
     g_free(ms->device_memory);
     g_free(ms->nvdimms_state);
     g_free(ms->numa_state);
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 41/44] qdev: Move base property types to qom/property-types.c
  2020-11-04 16:00 ` [PATCH v2 41/44] qdev: Move base property types to qom/property-types.c Eduardo Habkost
@ 2020-11-04 16:36   ` Paolo Bonzini
  2020-11-04 20:50     ` Eduardo Habkost
  0 siblings, 1 reply; 77+ messages in thread
From: Paolo Bonzini @ 2020-11-04 16:36 UTC (permalink / raw)
  To: Eduardo Habkost, qemu-devel
  Cc: Daniel P. Berrange, John Snow, Markus Armbruster,
	Philippe Mathieu-Daudé,
	Marc-André Lureau, Igor Mammedov, Stefan Berger

On 04/11/20 17:00, Eduardo Habkost wrote:
> Move all property types from qdev-properties.c to
> qom/property-types.c.
> 
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> ---
> Changes v1 -> v2:
> * Rebased after changes in previous patches in the series
> ---
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Cc: "Daniel P. Berrangé" <berrange@redhat.com>
> Cc: Eduardo Habkost <ehabkost@redhat.com>
> Cc: qemu-devel@nongnu.org
> ---
>   include/hw/qdev-properties.h | 179 +-----------
>   include/qom/property-types.h | 185 ++++++++++++
>   hw/core/qdev-properties.c    | 537 ----------------------------------
>   qom/property-types.c         | 545 +++++++++++++++++++++++++++++++++++
>   qom/meson.build              |   1 +
>   5 files changed, 732 insertions(+), 715 deletions(-)
>   create mode 100644 include/qom/property-types.h
>   create mode 100644 qom/property-types.c

I would merge property-types.h and field-property.h in a single file.

Actually I wouldn't even bother having separate headers, however it's 
certainly valuable to have headers like you have in patch 42:

Core QOM API Reference
----------------------

....


Field Property API Reference
----------------------------

....



I'm not sure if it's possible to include rST headers in .h files.

Paolo

> diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
> index bee26d0319..939b6dbf4e 100644
> --- a/include/hw/qdev-properties.h
> +++ b/include/hw/qdev-properties.h
> @@ -3,184 +3,7 @@
>   
>   #include "hw/qdev-core.h"
>   #include "qom/field-property.h"
> -
> -/*** qdev-properties.c ***/
> -
> -extern const PropertyInfo prop_info_bit;
> -extern const PropertyInfo prop_info_bit64;
> -extern const PropertyInfo prop_info_bool;
> -extern const PropertyInfo prop_info_enum;
> -extern const PropertyInfo prop_info_uint8;
> -extern const PropertyInfo prop_info_uint16;
> -extern const PropertyInfo prop_info_uint32;
> -extern const PropertyInfo prop_info_int32;
> -extern const PropertyInfo prop_info_uint64;
> -extern const PropertyInfo prop_info_int64;
> -extern const PropertyInfo prop_info_size;
> -extern const PropertyInfo prop_info_string;
> -extern const PropertyInfo prop_info_on_off_auto;
> -extern const PropertyInfo prop_info_size32;
> -extern const PropertyInfo prop_info_arraylen;
> -extern const PropertyInfo prop_info_link;
> -
> -#define DEFINE_PROP(_name, _state, _field, _prop, _type, ...) {  \
> -        .qdev_prop_name      = (_name),                          \
> -        .info      = &(_prop),                                   \
> -        .offset    = offsetof(_state, _field)                    \
> -            + type_check(_type, typeof_field(_state, _field)),   \
> -        __VA_ARGS__                                              \
> -        }
> -
> -#define DEFINE_PROP_SIGNED(_name, _state, _field, _defval, _prop, _type) \
> -    DEFINE_PROP(_name, _state, _field, _prop, _type,                     \
> -                .set_default = true,                                     \
> -                .defval.i    = (_type)_defval)
> -
> -#define DEFINE_PROP_SIGNED_NODEFAULT(_name, _state, _field, _prop, _type) \
> -    DEFINE_PROP(_name, _state, _field, _prop, _type)
> -
> -#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval)   \
> -    DEFINE_PROP(_name, _state, _field, prop_info_bit, uint32_t, \
> -                .bitnr       = (_bit),                          \
> -                .set_default = true,                            \
> -                .defval.u    = (bool)_defval)
> -
> -#define DEFINE_PROP_UNSIGNED(_name, _state, _field, _defval, _prop, _type) \
> -    DEFINE_PROP(_name, _state, _field, _prop, _type,                       \
> -                .set_default = true,                                       \
> -                .defval.u  = (_type)_defval)
> -
> -#define DEFINE_PROP_UNSIGNED_NODEFAULT(_name, _state, _field, _prop, _type) \
> -    DEFINE_PROP(_name, _state, _field, _prop, _type)
> -
> -#define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval)   \
> -    DEFINE_PROP(_name, _state, _field, prop_info_bit64, uint64_t, \
> -                .bitnr    = (_bit),                               \
> -                .set_default = true,                              \
> -                .defval.u  = (bool)_defval)
> -
> -#define DEFINE_PROP_BOOL(_name, _state, _field, _defval)     \
> -    DEFINE_PROP(_name, _state, _field, prop_info_bool, bool, \
> -                .set_default = true,                         \
> -                .defval.u    = (bool)_defval)
> -
> -#define PROP_ARRAY_LEN_PREFIX "len-"
> -
> -/**
> - * DEFINE_PROP_ARRAY:
> - * @_name: name of the array
> - * @_state: name of the device state structure type
> - * @_field: uint32_t field in @_state to hold the array length
> - * @_arrayfield: field in @_state (of type '@_arraytype *') which
> - *               will point to the array
> - * @_arrayprop: PropertyInfo defining what property the array elements have
> - * @_arraytype: C type of the array elements
> - *
> - * Define device properties for a variable-length array _name.  A
> - * static property "len-arrayname" is defined. When the device creator
> - * sets this property to the desired length of array, further dynamic
> - * properties "arrayname[0]", "arrayname[1]", ...  are defined so the
> - * device creator can set the array element values. Setting the
> - * "len-arrayname" property more than once is an error.
> - *
> - * When the array length is set, the @_field member of the device
> - * struct is set to the array length, and @_arrayfield is set to point
> - * to (zero-initialised) memory allocated for the array.  For a zero
> - * length array, @_field will be set to 0 and @_arrayfield to NULL.
> - * It is the responsibility of the device deinit code to free the
> - * @_arrayfield memory.
> - */
> -#define DEFINE_PROP_ARRAY(_name, _state, _field,               \
> -                          _arrayfield, _arrayprop, _arraytype) \
> -    DEFINE_PROP((PROP_ARRAY_LEN_PREFIX _name),                 \
> -                _state, _field, prop_info_arraylen, uint32_t,  \
> -                .set_default = true,                           \
> -                .defval.u = 0,                                 \
> -                .arrayinfo = &(_arrayprop),                    \
> -                .arrayfieldsize = sizeof(_arraytype),          \
> -                .arrayoffset = offsetof(_state, _arrayfield))
> -
> -#define DEFINE_PROP_LINK(_name, _state, _field, _type, _ptr_type)     \
> -    DEFINE_PROP(_name, _state, _field, prop_info_link, _ptr_type,     \
> -                .link_type  = _type)
> -
> -#define DEFINE_PROP_UINT8(_n, _s, _f, _d)                       \
> -    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint8, uint8_t)
> -#define DEFINE_PROP_UINT16(_n, _s, _f, _d)                      \
> -    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint16, uint16_t)
> -#define DEFINE_PROP_UINT32(_n, _s, _f, _d)                      \
> -    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint32, uint32_t)
> -#define DEFINE_PROP_INT32(_n, _s, _f, _d)                      \
> -    DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_int32, int32_t)
> -#define DEFINE_PROP_UINT64(_n, _s, _f, _d)                      \
> -    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint64, uint64_t)
> -#define DEFINE_PROP_INT64(_n, _s, _f, _d)                      \
> -    DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_int64, int64_t)
> -#define DEFINE_PROP_SIZE(_n, _s, _f, _d)                       \
> -    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_size, uint64_t)
> -#define DEFINE_PROP_STRING(_n, _s, _f)             \
> -    DEFINE_PROP(_n, _s, _f, prop_info_string, char*)
> -#define DEFINE_PROP_ON_OFF_AUTO(_n, _s, _f, _d) \
> -    DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_on_off_auto, OnOffAuto)
> -#define DEFINE_PROP_SIZE32(_n, _s, _f, _d)                       \
> -    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_size32, uint32_t)
> -
> -#define DEFINE_PROP_END_OF_LIST()               \
> -    {}
> -
> -/*
> - * The PROP_* macros can be used as arguments for
> - * object_class_property_add_field().  They will evaluate to a
> - * pointer to a static variable.
> - */
> -
> -#define FIELD_PROP(def) \
> -    ({ static Property _p = def; &p; })
> -
> -#define PROP_SIGNED(...) \
> -    FIELD_PROP(DEFINE_PROP_SIGNED(NULL, __VA_ARGS__))
> -#define PROP_SIGNED_NODEFAULT(...) \
> -    FIELD_PROP(DEFINE_PROP_SIGNED_NODEFAULT(NULL, __VA_ARGS__))
> -#define PROP_BIT(...) \
> -    FIELD_PROP(DEFINE_PROP_BIT(NULL, __VA_ARGS__))
> -#define PROP_UNSIGNED(...) \
> -    FIELD_PROP(DEFINE_PROP_UNSIGNED(NULL, __VA_ARGS__))
> -#define PROP_UNSIGNED_NODEFAULT(...) \
> -    FIELD_PROP(DEFINE_PROP_UNSIGNED_NODEFAULT(NULL, __VA_ARGS__))
> -#define PROP_BIT64(...) \
> -    FIELD_PROP(DEFINE_PROP_BIT64(NULL, __VA_ARGS__))
> -#define PROP_BOOL(...) \
> -    FIELD_PROP(DEFINE_PROP_BOOL(NULL, __VA_ARGS__))
> -#define PROP_ARRAY(...) \
> -    FIELD_PROP(DEFINE_PROP_ARRAY(NULL, __VA_ARGS__))
> -#define PROP_LINK(...) \
> -    FIELD_PROP(DEFINE_PROP_LINK(NULL, __VA_ARGS__))
> -#define PROP_UINT8(...) \
> -    FIELD_PROP(DEFINE_PROP_UINT8(NULL, __VA_ARGS__))
> -#define PROP_UINT16(...) \
> -    FIELD_PROP(DEFINE_PROP_UINT16(NULL, __VA_ARGS__))
> -#define PROP_UINT32(...) \
> -    FIELD_PROP(DEFINE_PROP_UINT32(NULL, __VA_ARGS__))
> -#define PROP_INT32(...) \
> -    FIELD_PROP(DEFINE_PROP_INT32(NULL, __VA_ARGS__))
> -#define PROP_UINT64(...) \
> -    FIELD_PROP(DEFINE_PROP_UINT64(NULL, __VA_ARGS__))
> -#define PROP_INT64(...) \
> -    FIELD_PROP(DEFINE_PROP_INT64(NULL, __VA_ARGS__))
> -#define PROP_SIZE(...) \
> -    FIELD_PROP(DEFINE_PROP_SIZE(NULL, __VA_ARGS__))
> -#define PROP_STRING(...) \
> -    FIELD_PROP(DEFINE_PROP_STRING(NULL, __VA_ARGS__))
> -#define PROP_ON_OFF_AUTO(...) \
> -    FIELD_PROP(DEFINE_PROP_ON_OFF_AUTO(NULL, __VA_ARGS__))
> -#define PROP_SIZE32(...) \
> -    FIELD_PROP(DEFINE_PROP_SIZE32(NULL, __VA_ARGS__))
> -#define PROP_UUID(...) \
> -    FIELD_PROP(DEFINE_PROP_UUID(NULL, __VA_ARGS__))
> -#define PROP_UUID_NODEFAULT(...) \
> -    FIELD_PROP(DEFINE_PROP_UUID_NODEFAULT(NULL, __VA_ARGS__))
> -#define PROP_END_OF_LIST(...) \
> -    FIELD_PROP(DEFINE_PROP_END_OF_LIST(NULL, __VA_ARGS__))
> +#include "qom/property-types.h"
>   
>   /*
>    * Set properties between creation and realization.
> diff --git a/include/qom/property-types.h b/include/qom/property-types.h
> new file mode 100644
> index 0000000000..75f758e835
> --- /dev/null
> +++ b/include/qom/property-types.h
> @@ -0,0 +1,185 @@
> +/*
> + * QOM field property types
> + */
> +#ifndef QOM_PROPERTY_TYPES_H
> +#define QOM_PROPERTY_TYPES_H
> +
> +#include "qom/field-property.h"
> +
> +extern const PropertyInfo prop_info_bit;
> +extern const PropertyInfo prop_info_bit64;
> +extern const PropertyInfo prop_info_bool;
> +extern const PropertyInfo prop_info_enum;
> +extern const PropertyInfo prop_info_uint8;
> +extern const PropertyInfo prop_info_uint16;
> +extern const PropertyInfo prop_info_uint32;
> +extern const PropertyInfo prop_info_int32;
> +extern const PropertyInfo prop_info_uint64;
> +extern const PropertyInfo prop_info_int64;
> +extern const PropertyInfo prop_info_size;
> +extern const PropertyInfo prop_info_string;
> +extern const PropertyInfo prop_info_on_off_auto;
> +extern const PropertyInfo prop_info_size32;
> +extern const PropertyInfo prop_info_arraylen;
> +extern const PropertyInfo prop_info_link;
> +
> +#define DEFINE_PROP(_name, _state, _field, _prop, _type, ...) {  \
> +        .qdev_prop_name      = (_name),                          \
> +        .info      = &(_prop),                                   \
> +        .offset    = offsetof(_state, _field)                    \
> +            + type_check(_type, typeof_field(_state, _field)),   \
> +        __VA_ARGS__                                              \
> +        }
> +
> +#define DEFINE_PROP_SIGNED(_name, _state, _field, _defval, _prop, _type) \
> +    DEFINE_PROP(_name, _state, _field, _prop, _type,                     \
> +                .set_default = true,                                     \
> +                .defval.i    = (_type)_defval)
> +
> +#define DEFINE_PROP_SIGNED_NODEFAULT(_name, _state, _field, _prop, _type) \
> +    DEFINE_PROP(_name, _state, _field, _prop, _type)
> +
> +#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval)   \
> +    DEFINE_PROP(_name, _state, _field, prop_info_bit, uint32_t, \
> +                .bitnr       = (_bit),                          \
> +                .set_default = true,                            \
> +                .defval.u    = (bool)_defval)
> +
> +#define DEFINE_PROP_UNSIGNED(_name, _state, _field, _defval, _prop, _type) \
> +    DEFINE_PROP(_name, _state, _field, _prop, _type,                       \
> +                .set_default = true,                                       \
> +                .defval.u  = (_type)_defval)
> +
> +#define DEFINE_PROP_UNSIGNED_NODEFAULT(_name, _state, _field, _prop, _type) \
> +    DEFINE_PROP(_name, _state, _field, _prop, _type)
> +
> +#define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval)   \
> +    DEFINE_PROP(_name, _state, _field, prop_info_bit64, uint64_t, \
> +                .bitnr    = (_bit),                               \
> +                .set_default = true,                              \
> +                .defval.u  = (bool)_defval)
> +
> +#define DEFINE_PROP_BOOL(_name, _state, _field, _defval)     \
> +    DEFINE_PROP(_name, _state, _field, prop_info_bool, bool, \
> +                .set_default = true,                         \
> +                .defval.u    = (bool)_defval)
> +
> +#define PROP_ARRAY_LEN_PREFIX "len-"
> +
> +/**
> + * DEFINE_PROP_ARRAY:
> + * @_name: name of the array
> + * @_state: name of the device state structure type
> + * @_field: uint32_t field in @_state to hold the array length
> + * @_arrayfield: field in @_state (of type '@_arraytype *') which
> + *               will point to the array
> + * @_arrayprop: PropertyInfo defining what property the array elements have
> + * @_arraytype: C type of the array elements
> + *
> + * Define device properties for a variable-length array _name.  A
> + * static property "len-arrayname" is defined. When the device creator
> + * sets this property to the desired length of array, further dynamic
> + * properties "arrayname[0]", "arrayname[1]", ...  are defined so the
> + * device creator can set the array element values. Setting the
> + * "len-arrayname" property more than once is an error.
> + *
> + * When the array length is set, the @_field member of the device
> + * struct is set to the array length, and @_arrayfield is set to point
> + * to (zero-initialised) memory allocated for the array.  For a zero
> + * length array, @_field will be set to 0 and @_arrayfield to NULL.
> + * It is the responsibility of the device deinit code to free the
> + * @_arrayfield memory.
> + */
> +#define DEFINE_PROP_ARRAY(_name, _state, _field,               \
> +                          _arrayfield, _arrayprop, _arraytype) \
> +    DEFINE_PROP((PROP_ARRAY_LEN_PREFIX _name),                 \
> +                _state, _field, prop_info_arraylen, uint32_t,  \
> +                .set_default = true,                           \
> +                .defval.u = 0,                                 \
> +                .arrayinfo = &(_arrayprop),                    \
> +                .arrayfieldsize = sizeof(_arraytype),          \
> +                .arrayoffset = offsetof(_state, _arrayfield))
> +
> +#define DEFINE_PROP_LINK(_name, _state, _field, _type, _ptr_type)     \
> +    DEFINE_PROP(_name, _state, _field, prop_info_link, _ptr_type,     \
> +                .link_type  = _type)
> +
> +#define DEFINE_PROP_UINT8(_n, _s, _f, _d)                       \
> +    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint8, uint8_t)
> +#define DEFINE_PROP_UINT16(_n, _s, _f, _d)                      \
> +    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint16, uint16_t)
> +#define DEFINE_PROP_UINT32(_n, _s, _f, _d)                      \
> +    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint32, uint32_t)
> +#define DEFINE_PROP_INT32(_n, _s, _f, _d)                      \
> +    DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_int32, int32_t)
> +#define DEFINE_PROP_UINT64(_n, _s, _f, _d)                      \
> +    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint64, uint64_t)
> +#define DEFINE_PROP_INT64(_n, _s, _f, _d)                      \
> +    DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_int64, int64_t)
> +#define DEFINE_PROP_SIZE(_n, _s, _f, _d)                       \
> +    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_size, uint64_t)
> +#define DEFINE_PROP_STRING(_n, _s, _f)             \
> +    DEFINE_PROP(_n, _s, _f, prop_info_string, char*)
> +#define DEFINE_PROP_ON_OFF_AUTO(_n, _s, _f, _d) \
> +    DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_on_off_auto, OnOffAuto)
> +#define DEFINE_PROP_SIZE32(_n, _s, _f, _d)                       \
> +    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_size32, uint32_t)
> +
> +#define DEFINE_PROP_END_OF_LIST()               \
> +    {}
> +
> +/*
> + * The PROP_* macros can be used as arguments for
> + * object_class_property_add_field().  They will evaluate to a
> + * pointer to a static variable.
> + */
> +
> +#define FIELD_PROP(def) \
> +    ({ static Property _p = def; &p; })
> +
> +#define PROP_SIGNED(...) \
> +    FIELD_PROP(DEFINE_PROP_SIGNED(NULL, __VA_ARGS__))
> +#define PROP_SIGNED_NODEFAULT(...) \
> +    FIELD_PROP(DEFINE_PROP_SIGNED_NODEFAULT(NULL, __VA_ARGS__))
> +#define PROP_BIT(...) \
> +    FIELD_PROP(DEFINE_PROP_BIT(NULL, __VA_ARGS__))
> +#define PROP_UNSIGNED(...) \
> +    FIELD_PROP(DEFINE_PROP_UNSIGNED(NULL, __VA_ARGS__))
> +#define PROP_UNSIGNED_NODEFAULT(...) \
> +    FIELD_PROP(DEFINE_PROP_UNSIGNED_NODEFAULT(NULL, __VA_ARGS__))
> +#define PROP_BIT64(...) \
> +    FIELD_PROP(DEFINE_PROP_BIT64(NULL, __VA_ARGS__))
> +#define PROP_BOOL(...) \
> +    FIELD_PROP(DEFINE_PROP_BOOL(NULL, __VA_ARGS__))
> +#define PROP_ARRAY(...) \
> +    FIELD_PROP(DEFINE_PROP_ARRAY(NULL, __VA_ARGS__))
> +#define PROP_LINK(...) \
> +    FIELD_PROP(DEFINE_PROP_LINK(NULL, __VA_ARGS__))
> +#define PROP_UINT8(...) \
> +    FIELD_PROP(DEFINE_PROP_UINT8(NULL, __VA_ARGS__))
> +#define PROP_UINT16(...) \
> +    FIELD_PROP(DEFINE_PROP_UINT16(NULL, __VA_ARGS__))
> +#define PROP_UINT32(...) \
> +    FIELD_PROP(DEFINE_PROP_UINT32(NULL, __VA_ARGS__))
> +#define PROP_INT32(...) \
> +    FIELD_PROP(DEFINE_PROP_INT32(NULL, __VA_ARGS__))
> +#define PROP_UINT64(...) \
> +    FIELD_PROP(DEFINE_PROP_UINT64(NULL, __VA_ARGS__))
> +#define PROP_INT64(...) \
> +    FIELD_PROP(DEFINE_PROP_INT64(NULL, __VA_ARGS__))
> +#define PROP_SIZE(...) \
> +    FIELD_PROP(DEFINE_PROP_SIZE(NULL, __VA_ARGS__))
> +#define PROP_STRING(...) \
> +    FIELD_PROP(DEFINE_PROP_STRING(NULL, __VA_ARGS__))
> +#define PROP_ON_OFF_AUTO(...) \
> +    FIELD_PROP(DEFINE_PROP_ON_OFF_AUTO(NULL, __VA_ARGS__))
> +#define PROP_SIZE32(...) \
> +    FIELD_PROP(DEFINE_PROP_SIZE32(NULL, __VA_ARGS__))
> +#define PROP_UUID(...) \
> +    FIELD_PROP(DEFINE_PROP_UUID(NULL, __VA_ARGS__))
> +#define PROP_UUID_NODEFAULT(...) \
> +    FIELD_PROP(DEFINE_PROP_UUID_NODEFAULT(NULL, __VA_ARGS__))
> +#define PROP_END_OF_LIST(...) \
> +    FIELD_PROP(DEFINE_PROP_END_OF_LIST(NULL, __VA_ARGS__))
> +
> +#endif
> diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
> index b75730f15c..5bb4ff5f46 100644
> --- a/hw/core/qdev-properties.c
> +++ b/hw/core/qdev-properties.c
> @@ -50,496 +50,6 @@ void qdev_prop_allow_set_link_before_realize(const Object *obj,
>       }
>   }
>   
> -void field_prop_get_enum(Object *obj, Visitor *v, const char *name,
> -                         void *opaque, Error **errp)
> -{
> -    Property *prop = opaque;
> -    int *ptr = object_field_prop_ptr(obj, prop);
> -
> -    visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
> -}
> -
> -void field_prop_set_enum(Object *obj, Visitor *v, const char *name,
> -                         void *opaque, Error **errp)
> -{
> -    Property *prop = opaque;
> -    int *ptr = object_field_prop_ptr(obj, prop);
> -
> -    visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
> -}
> -
> -void field_prop_set_default_value_enum(ObjectProperty *op,
> -                                       const Property *prop)
> -{
> -    object_property_set_default_str(op,
> -        qapi_enum_lookup(prop->info->enum_table, prop->defval.i));
> -}
> -
> -const PropertyInfo prop_info_enum = {
> -    .name  = "enum",
> -    .get   = field_prop_get_enum,
> -    .set   = field_prop_set_enum,
> -    .set_default_value = field_prop_set_default_value_enum,
> -};
> -
> -/* Bit */
> -
> -static uint32_t qdev_get_prop_mask(Property *prop)
> -{
> -    assert(prop->info == &prop_info_bit);
> -    return 0x1 << prop->bitnr;
> -}
> -
> -static void bit_prop_set(Object *obj, Property *props, bool val)
> -{
> -    uint32_t *p = object_field_prop_ptr(obj, props);
> -    uint32_t mask = qdev_get_prop_mask(props);
> -    if (val) {
> -        *p |= mask;
> -    } else {
> -        *p &= ~mask;
> -    }
> -}
> -
> -static void prop_get_bit(Object *obj, Visitor *v, const char *name,
> -                         void *opaque, Error **errp)
> -{
> -    Property *prop = opaque;
> -    uint32_t *p = object_field_prop_ptr(obj, prop);
> -    bool value = (*p & qdev_get_prop_mask(prop)) != 0;
> -
> -    visit_type_bool(v, name, &value, errp);
> -}
> -
> -static void prop_set_bit(Object *obj, Visitor *v, const char *name,
> -                         void *opaque, Error **errp)
> -{
> -    Property *prop = opaque;
> -    bool value;
> -
> -    if (!visit_type_bool(v, name, &value, errp)) {
> -        return;
> -    }
> -    bit_prop_set(obj, prop, value);
> -}
> -
> -static void set_default_value_bool(ObjectProperty *op, const Property *prop)
> -{
> -    object_property_set_default_bool(op, prop->defval.u);
> -}
> -
> -const PropertyInfo prop_info_bit = {
> -    .name  = "bool",
> -    .description = "on/off",
> -    .get   = prop_get_bit,
> -    .set   = prop_set_bit,
> -    .set_default_value = set_default_value_bool,
> -};
> -
> -/* Bit64 */
> -
> -static uint64_t qdev_get_prop_mask64(Property *prop)
> -{
> -    assert(prop->info == &prop_info_bit64);
> -    return 0x1ull << prop->bitnr;
> -}
> -
> -static void bit64_prop_set(Object *obj, Property *props, bool val)
> -{
> -    uint64_t *p = object_field_prop_ptr(obj, props);
> -    uint64_t mask = qdev_get_prop_mask64(props);
> -    if (val) {
> -        *p |= mask;
> -    } else {
> -        *p &= ~mask;
> -    }
> -}
> -
> -static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
> -                           void *opaque, Error **errp)
> -{
> -    Property *prop = opaque;
> -    uint64_t *p = object_field_prop_ptr(obj, prop);
> -    bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
> -
> -    visit_type_bool(v, name, &value, errp);
> -}
> -
> -static void prop_set_bit64(Object *obj, Visitor *v, const char *name,
> -                           void *opaque, Error **errp)
> -{
> -    Property *prop = opaque;
> -    bool value;
> -
> -    if (!visit_type_bool(v, name, &value, errp)) {
> -        return;
> -    }
> -    bit64_prop_set(obj, prop, value);
> -}
> -
> -const PropertyInfo prop_info_bit64 = {
> -    .name  = "bool",
> -    .description = "on/off",
> -    .get   = prop_get_bit64,
> -    .set   = prop_set_bit64,
> -    .set_default_value = set_default_value_bool,
> -};
> -
> -/* --- bool --- */
> -
> -static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
> -                     Error **errp)
> -{
> -    Property *prop = opaque;
> -    bool *ptr = object_field_prop_ptr(obj, prop);
> -
> -    visit_type_bool(v, name, ptr, errp);
> -}
> -
> -static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
> -                     Error **errp)
> -{
> -    Property *prop = opaque;
> -    bool *ptr = object_field_prop_ptr(obj, prop);
> -
> -    visit_type_bool(v, name, ptr, errp);
> -}
> -
> -const PropertyInfo prop_info_bool = {
> -    .name  = "bool",
> -    .get   = get_bool,
> -    .set   = set_bool,
> -    .set_default_value = set_default_value_bool,
> -};
> -
> -/* --- 8bit integer --- */
> -
> -static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
> -                      Error **errp)
> -{
> -    Property *prop = opaque;
> -    uint8_t *ptr = object_field_prop_ptr(obj, prop);
> -
> -    visit_type_uint8(v, name, ptr, errp);
> -}
> -
> -static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
> -                      Error **errp)
> -{
> -    Property *prop = opaque;
> -    uint8_t *ptr = object_field_prop_ptr(obj, prop);
> -
> -    visit_type_uint8(v, name, ptr, errp);
> -}
> -
> -void field_prop_set_default_value_int(ObjectProperty *op,
> -                                      const Property *prop)
> -{
> -    object_property_set_default_int(op, prop->defval.i);
> -}
> -
> -void field_prop_set_default_value_uint(ObjectProperty *op,
> -                                       const Property *prop)
> -{
> -    object_property_set_default_uint(op, prop->defval.u);
> -}
> -
> -const PropertyInfo prop_info_uint8 = {
> -    .name  = "uint8",
> -    .get   = get_uint8,
> -    .set   = set_uint8,
> -    .set_default_value = field_prop_set_default_value_uint,
> -};
> -
> -/* --- 16bit integer --- */
> -
> -static void get_uint16(Object *obj, Visitor *v, const char *name,
> -                       void *opaque, Error **errp)
> -{
> -    Property *prop = opaque;
> -    uint16_t *ptr = object_field_prop_ptr(obj, prop);
> -
> -    visit_type_uint16(v, name, ptr, errp);
> -}
> -
> -static void set_uint16(Object *obj, Visitor *v, const char *name,
> -                       void *opaque, Error **errp)
> -{
> -    Property *prop = opaque;
> -    uint16_t *ptr = object_field_prop_ptr(obj, prop);
> -
> -    visit_type_uint16(v, name, ptr, errp);
> -}
> -
> -const PropertyInfo prop_info_uint16 = {
> -    .name  = "uint16",
> -    .get   = get_uint16,
> -    .set   = set_uint16,
> -    .set_default_value = field_prop_set_default_value_uint,
> -};
> -
> -/* --- 32bit integer --- */
> -
> -static void get_uint32(Object *obj, Visitor *v, const char *name,
> -                       void *opaque, Error **errp)
> -{
> -    Property *prop = opaque;
> -    uint32_t *ptr = object_field_prop_ptr(obj, prop);
> -
> -    visit_type_uint32(v, name, ptr, errp);
> -}
> -
> -static void set_uint32(Object *obj, Visitor *v, const char *name,
> -                       void *opaque, Error **errp)
> -{
> -    Property *prop = opaque;
> -    uint32_t *ptr = object_field_prop_ptr(obj, prop);
> -
> -    visit_type_uint32(v, name, ptr, errp);
> -}
> -
> -void field_prop_get_int32(Object *obj, Visitor *v, const char *name,
> -                          void *opaque, Error **errp)
> -{
> -    Property *prop = opaque;
> -    int32_t *ptr = object_field_prop_ptr(obj, prop);
> -
> -    visit_type_int32(v, name, ptr, errp);
> -}
> -
> -static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
> -                      Error **errp)
> -{
> -    Property *prop = opaque;
> -    int32_t *ptr = object_field_prop_ptr(obj, prop);
> -
> -    visit_type_int32(v, name, ptr, errp);
> -}
> -
> -const PropertyInfo prop_info_uint32 = {
> -    .name  = "uint32",
> -    .get   = get_uint32,
> -    .set   = set_uint32,
> -    .set_default_value = field_prop_set_default_value_uint,
> -};
> -
> -const PropertyInfo prop_info_int32 = {
> -    .name  = "int32",
> -    .get   = field_prop_get_int32,
> -    .set   = set_int32,
> -    .set_default_value = field_prop_set_default_value_int,
> -};
> -
> -/* --- 64bit integer --- */
> -
> -static void get_uint64(Object *obj, Visitor *v, const char *name,
> -                       void *opaque, Error **errp)
> -{
> -    Property *prop = opaque;
> -    uint64_t *ptr = object_field_prop_ptr(obj, prop);
> -
> -    visit_type_uint64(v, name, ptr, errp);
> -}
> -
> -static void set_uint64(Object *obj, Visitor *v, const char *name,
> -                       void *opaque, Error **errp)
> -{
> -    Property *prop = opaque;
> -    uint64_t *ptr = object_field_prop_ptr(obj, prop);
> -
> -    visit_type_uint64(v, name, ptr, errp);
> -}
> -
> -static void get_int64(Object *obj, Visitor *v, const char *name,
> -                      void *opaque, Error **errp)
> -{
> -    Property *prop = opaque;
> -    int64_t *ptr = object_field_prop_ptr(obj, prop);
> -
> -    visit_type_int64(v, name, ptr, errp);
> -}
> -
> -static void set_int64(Object *obj, Visitor *v, const char *name,
> -                      void *opaque, Error **errp)
> -{
> -    Property *prop = opaque;
> -    int64_t *ptr = object_field_prop_ptr(obj, prop);
> -
> -    visit_type_int64(v, name, ptr, errp);
> -}
> -
> -const PropertyInfo prop_info_uint64 = {
> -    .name  = "uint64",
> -    .get   = get_uint64,
> -    .set   = set_uint64,
> -    .set_default_value = field_prop_set_default_value_uint,
> -};
> -
> -const PropertyInfo prop_info_int64 = {
> -    .name  = "int64",
> -    .get   = get_int64,
> -    .set   = set_int64,
> -    .set_default_value = field_prop_set_default_value_int,
> -};
> -
> -/* --- string --- */
> -
> -static void release_string(Object *obj, const char *name, void *opaque)
> -{
> -    Property *prop = opaque;
> -    g_free(*(char **)object_field_prop_ptr(obj, prop));
> -}
> -
> -static void get_string(Object *obj, Visitor *v, const char *name,
> -                       void *opaque, Error **errp)
> -{
> -    Property *prop = opaque;
> -    char **ptr = object_field_prop_ptr(obj, prop);
> -
> -    if (!*ptr) {
> -        char *str = (char *)"";
> -        visit_type_str(v, name, &str, errp);
> -    } else {
> -        visit_type_str(v, name, ptr, errp);
> -    }
> -}
> -
> -static void set_string(Object *obj, Visitor *v, const char *name,
> -                       void *opaque, Error **errp)
> -{
> -    Property *prop = opaque;
> -    char **ptr = object_field_prop_ptr(obj, prop);
> -    char *str;
> -
> -    if (!visit_type_str(v, name, &str, errp)) {
> -        return;
> -    }
> -    g_free(*ptr);
> -    *ptr = str;
> -}
> -
> -const PropertyInfo prop_info_string = {
> -    .name  = "str",
> -    .release = release_string,
> -    .get   = get_string,
> -    .set   = set_string,
> -};
> -
> -/* --- on/off/auto --- */
> -
> -const PropertyInfo prop_info_on_off_auto = {
> -    .name = "OnOffAuto",
> -    .description = "on/off/auto",
> -    .enum_table = &OnOffAuto_lookup,
> -    .get = field_prop_get_enum,
> -    .set = field_prop_set_enum,
> -    .set_default_value = field_prop_set_default_value_enum,
> -};
> -
> -/* --- 32bit unsigned int 'size' type --- */
> -
> -void field_prop_get_size32(Object *obj, Visitor *v, const char *name,
> -                           void *opaque, Error **errp)
> -{
> -    Property *prop = opaque;
> -    uint32_t *ptr = object_field_prop_ptr(obj, prop);
> -    uint64_t value = *ptr;
> -
> -    visit_type_size(v, name, &value, errp);
> -}
> -
> -static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
> -                       Error **errp)
> -{
> -    Property *prop = opaque;
> -    uint32_t *ptr = object_field_prop_ptr(obj, prop);
> -    uint64_t value;
> -
> -    if (!visit_type_size(v, name, &value, errp)) {
> -        return;
> -    }
> -
> -    if (value > UINT32_MAX) {
> -        error_setg(errp,
> -                   "Property %s.%s doesn't take value %" PRIu64
> -                   " (maximum: %u)",
> -                   object_get_typename(obj), name, value, UINT32_MAX);
> -        return;
> -    }
> -
> -    *ptr = value;
> -}
> -
> -const PropertyInfo prop_info_size32 = {
> -    .name  = "size",
> -    .get = field_prop_get_size32,
> -    .set = set_size32,
> -    .set_default_value = field_prop_set_default_value_uint,
> -};
> -
> -/* --- support for array properties --- */
> -
> -static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
> -                              void *opaque, Error **errp)
> -{
> -    /* Setter for the property which defines the length of a
> -     * variable-sized property array. As well as actually setting the
> -     * array-length field in the device struct, we have to create the
> -     * array itself and dynamically add the corresponding properties.
> -     */
> -    Property *prop = opaque;
> -    ObjectProperty *op = object_property_find_err(obj, name, &error_abort);
> -    uint32_t *alenptr = object_field_prop_ptr(obj, prop);
> -    void **arrayptr = (void *)obj + prop->arrayoffset;
> -    void *eltptr;
> -    const char *arrayname;
> -    int i;
> -
> -    if (*alenptr) {
> -        error_setg(errp, "array size property %s may not be set more than once",
> -                   name);
> -        return;
> -    }
> -    if (!visit_type_uint32(v, name, alenptr, errp)) {
> -        return;
> -    }
> -    if (!*alenptr) {
> -        return;
> -    }
> -
> -    /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix;
> -     * strip it off so we can get the name of the array itself.
> -     */
> -    assert(strncmp(name, PROP_ARRAY_LEN_PREFIX,
> -                   strlen(PROP_ARRAY_LEN_PREFIX)) == 0);
> -    arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX);
> -
> -    /* Note that it is the responsibility of the individual device's deinit
> -     * to free the array proper.
> -     */
> -    *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize);
> -    for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) {
> -        g_autofree char *propname = g_strdup_printf("%s[%d]", arrayname, i);
> -        Property *arrayprop = g_new0(Property, 1);
> -        arrayprop->info = prop->arrayinfo;
> -        /* This ugly piece of pointer arithmetic sets up the offset so
> -         * that when the underlying get/set hooks call qdev_get_prop_ptr
> -         * they get the right answer despite the array element not actually
> -         * being inside the device struct.
> -         */
> -        arrayprop->offset = eltptr - (void *)obj;
> -        assert(object_field_prop_ptr(obj, arrayprop) == eltptr);
> -        object_property_add_field(obj, propname, arrayprop, op->allow_set);
> -    }
> -}
> -
> -const PropertyInfo prop_info_arraylen = {
> -    .name = "uint32",
> -    .get = get_uint32,
> -    .set = set_prop_arraylen,
> -    .set_default_value = field_prop_set_default_value_uint,
> -};
> -
>   /* --- public helpers --- */
>   
>   static Property *qdev_prop_walk(Property *props, const char *name)
> @@ -712,53 +222,6 @@ void qdev_prop_set_globals(DeviceState *dev)
>                                 dev->hotplugged ? NULL : &error_fatal);
>   }
>   
> -/* --- 64bit unsigned int 'size' type --- */
> -
> -static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
> -                     Error **errp)
> -{
> -    Property *prop = opaque;
> -    uint64_t *ptr = object_field_prop_ptr(obj, prop);
> -
> -    visit_type_size(v, name, ptr, errp);
> -}
> -
> -static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
> -                     Error **errp)
> -{
> -    Property *prop = opaque;
> -    uint64_t *ptr = object_field_prop_ptr(obj, prop);
> -
> -    visit_type_size(v, name, ptr, errp);
> -}
> -
> -const PropertyInfo prop_info_size = {
> -    .name  = "size",
> -    .get = get_size,
> -    .set = set_size,
> -    .set_default_value = field_prop_set_default_value_uint,
> -};
> -
> -/* --- object link property --- */
> -
> -static ObjectProperty *create_link_property(ObjectClass *oc, const char *name,
> -                                            Property *prop)
> -{
> -    /*
> -     * NOTE: object_property_allow_set_link is unconditional, but
> -     *       ObjectProperty.allow_set may be set for the property too.
> -     */
> -    return object_class_property_add_link(oc, name, prop->link_type,
> -                                          prop->offset,
> -                                          object_property_allow_set_link,
> -                                          OBJ_PROP_LINK_STRONG);
> -}
> -
> -const PropertyInfo prop_info_link = {
> -    .name = "link",
> -    .create = create_link_property,
> -};
> -
>   void qdev_property_add_static(DeviceState *dev, Property *prop)
>   {
>       object_property_add_field(OBJECT(dev), prop->qdev_prop_name, prop,
> diff --git a/qom/property-types.c b/qom/property-types.c
> new file mode 100644
> index 0000000000..f566c05ec2
> --- /dev/null
> +++ b/qom/property-types.c
> @@ -0,0 +1,545 @@
> +#include "qemu/osdep.h"
> +#include "qom/field-property.h"
> +#include "qom/property-types.h"
> +#include "qom/field-property-internal.h"
> +#include "qapi/qapi-types-common.h"
> +#include "qapi/visitor.h"
> +#include "qapi/error.h"
> +#include "qemu/uuid.h"
> +
> +void field_prop_get_enum(Object *obj, Visitor *v, const char *name,
> +                         void *opaque, Error **errp)
> +{
> +    Property *prop = opaque;
> +    int *ptr = object_field_prop_ptr(obj, prop);
> +
> +    visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
> +}
> +
> +void field_prop_set_enum(Object *obj, Visitor *v, const char *name,
> +                         void *opaque, Error **errp)
> +{
> +    Property *prop = opaque;
> +    int *ptr = object_field_prop_ptr(obj, prop);
> +
> +    visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
> +}
> +
> +void field_prop_set_default_value_enum(ObjectProperty *op,
> +                                       const Property *prop)
> +{
> +    object_property_set_default_str(op,
> +        qapi_enum_lookup(prop->info->enum_table, prop->defval.i));
> +}
> +
> +const PropertyInfo prop_info_enum = {
> +    .name  = "enum",
> +    .get   = field_prop_get_enum,
> +    .set   = field_prop_set_enum,
> +    .set_default_value = field_prop_set_default_value_enum,
> +};
> +
> +/* Bit */
> +
> +static uint32_t qdev_get_prop_mask(Property *prop)
> +{
> +    assert(prop->info == &prop_info_bit);
> +    return 0x1 << prop->bitnr;
> +}
> +
> +static void bit_prop_set(Object *obj, Property *props, bool val)
> +{
> +    uint32_t *p = object_field_prop_ptr(obj, props);
> +    uint32_t mask = qdev_get_prop_mask(props);
> +    if (val) {
> +        *p |= mask;
> +    } else {
> +        *p &= ~mask;
> +    }
> +}
> +
> +static void prop_get_bit(Object *obj, Visitor *v, const char *name,
> +                         void *opaque, Error **errp)
> +{
> +    Property *prop = opaque;
> +    uint32_t *p = object_field_prop_ptr(obj, prop);
> +    bool value = (*p & qdev_get_prop_mask(prop)) != 0;
> +
> +    visit_type_bool(v, name, &value, errp);
> +}
> +
> +static void prop_set_bit(Object *obj, Visitor *v, const char *name,
> +                         void *opaque, Error **errp)
> +{
> +    Property *prop = opaque;
> +    bool value;
> +
> +    if (!visit_type_bool(v, name, &value, errp)) {
> +        return;
> +    }
> +    bit_prop_set(obj, prop, value);
> +}
> +
> +static void set_default_value_bool(ObjectProperty *op, const Property *prop)
> +{
> +    object_property_set_default_bool(op, prop->defval.u);
> +}
> +
> +const PropertyInfo prop_info_bit = {
> +    .name  = "bool",
> +    .description = "on/off",
> +    .get   = prop_get_bit,
> +    .set   = prop_set_bit,
> +    .set_default_value = set_default_value_bool,
> +};
> +
> +/* Bit64 */
> +
> +static uint64_t qdev_get_prop_mask64(Property *prop)
> +{
> +    assert(prop->info == &prop_info_bit64);
> +    return 0x1ull << prop->bitnr;
> +}
> +
> +static void bit64_prop_set(Object *obj, Property *props, bool val)
> +{
> +    uint64_t *p = object_field_prop_ptr(obj, props);
> +    uint64_t mask = qdev_get_prop_mask64(props);
> +    if (val) {
> +        *p |= mask;
> +    } else {
> +        *p &= ~mask;
> +    }
> +}
> +
> +static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
> +                           void *opaque, Error **errp)
> +{
> +    Property *prop = opaque;
> +    uint64_t *p = object_field_prop_ptr(obj, prop);
> +    bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
> +
> +    visit_type_bool(v, name, &value, errp);
> +}
> +
> +static void prop_set_bit64(Object *obj, Visitor *v, const char *name,
> +                           void *opaque, Error **errp)
> +{
> +    Property *prop = opaque;
> +    bool value;
> +
> +    if (!visit_type_bool(v, name, &value, errp)) {
> +        return;
> +    }
> +    bit64_prop_set(obj, prop, value);
> +}
> +
> +const PropertyInfo prop_info_bit64 = {
> +    .name  = "bool",
> +    .description = "on/off",
> +    .get   = prop_get_bit64,
> +    .set   = prop_set_bit64,
> +    .set_default_value = set_default_value_bool,
> +};
> +
> +/* --- bool --- */
> +
> +static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
> +                     Error **errp)
> +{
> +    Property *prop = opaque;
> +    bool *ptr = object_field_prop_ptr(obj, prop);
> +
> +    visit_type_bool(v, name, ptr, errp);
> +}
> +
> +static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
> +                     Error **errp)
> +{
> +    Property *prop = opaque;
> +    bool *ptr = object_field_prop_ptr(obj, prop);
> +
> +    visit_type_bool(v, name, ptr, errp);
> +}
> +
> +const PropertyInfo prop_info_bool = {
> +    .name  = "bool",
> +    .get   = get_bool,
> +    .set   = set_bool,
> +    .set_default_value = set_default_value_bool,
> +};
> +
> +/* --- 8bit integer --- */
> +
> +static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
> +                      Error **errp)
> +{
> +    Property *prop = opaque;
> +    uint8_t *ptr = object_field_prop_ptr(obj, prop);
> +
> +    visit_type_uint8(v, name, ptr, errp);
> +}
> +
> +static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
> +                      Error **errp)
> +{
> +    Property *prop = opaque;
> +    uint8_t *ptr = object_field_prop_ptr(obj, prop);
> +
> +    visit_type_uint8(v, name, ptr, errp);
> +}
> +
> +void field_prop_set_default_value_int(ObjectProperty *op,
> +                                      const Property *prop)
> +{
> +    object_property_set_default_int(op, prop->defval.i);
> +}
> +
> +void field_prop_set_default_value_uint(ObjectProperty *op,
> +                                       const Property *prop)
> +{
> +    object_property_set_default_uint(op, prop->defval.u);
> +}
> +
> +const PropertyInfo prop_info_uint8 = {
> +    .name  = "uint8",
> +    .get   = get_uint8,
> +    .set   = set_uint8,
> +    .set_default_value = field_prop_set_default_value_uint,
> +};
> +
> +/* --- 16bit integer --- */
> +
> +static void get_uint16(Object *obj, Visitor *v, const char *name,
> +                       void *opaque, Error **errp)
> +{
> +    Property *prop = opaque;
> +    uint16_t *ptr = object_field_prop_ptr(obj, prop);
> +
> +    visit_type_uint16(v, name, ptr, errp);
> +}
> +
> +static void set_uint16(Object *obj, Visitor *v, const char *name,
> +                       void *opaque, Error **errp)
> +{
> +    Property *prop = opaque;
> +    uint16_t *ptr = object_field_prop_ptr(obj, prop);
> +
> +    visit_type_uint16(v, name, ptr, errp);
> +}
> +
> +const PropertyInfo prop_info_uint16 = {
> +    .name  = "uint16",
> +    .get   = get_uint16,
> +    .set   = set_uint16,
> +    .set_default_value = field_prop_set_default_value_uint,
> +};
> +
> +/* --- 32bit integer --- */
> +
> +static void get_uint32(Object *obj, Visitor *v, const char *name,
> +                       void *opaque, Error **errp)
> +{
> +    Property *prop = opaque;
> +    uint32_t *ptr = object_field_prop_ptr(obj, prop);
> +
> +    visit_type_uint32(v, name, ptr, errp);
> +}
> +
> +static void set_uint32(Object *obj, Visitor *v, const char *name,
> +                       void *opaque, Error **errp)
> +{
> +    Property *prop = opaque;
> +    uint32_t *ptr = object_field_prop_ptr(obj, prop);
> +
> +    visit_type_uint32(v, name, ptr, errp);
> +}
> +
> +void field_prop_get_int32(Object *obj, Visitor *v, const char *name,
> +                          void *opaque, Error **errp)
> +{
> +    Property *prop = opaque;
> +    int32_t *ptr = object_field_prop_ptr(obj, prop);
> +
> +    visit_type_int32(v, name, ptr, errp);
> +}
> +
> +static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
> +                      Error **errp)
> +{
> +    Property *prop = opaque;
> +    int32_t *ptr = object_field_prop_ptr(obj, prop);
> +
> +    visit_type_int32(v, name, ptr, errp);
> +}
> +
> +const PropertyInfo prop_info_uint32 = {
> +    .name  = "uint32",
> +    .get   = get_uint32,
> +    .set   = set_uint32,
> +    .set_default_value = field_prop_set_default_value_uint,
> +};
> +
> +const PropertyInfo prop_info_int32 = {
> +    .name  = "int32",
> +    .get   = field_prop_get_int32,
> +    .set   = set_int32,
> +    .set_default_value = field_prop_set_default_value_int,
> +};
> +
> +/* --- 64bit integer --- */
> +
> +static void get_uint64(Object *obj, Visitor *v, const char *name,
> +                       void *opaque, Error **errp)
> +{
> +    Property *prop = opaque;
> +    uint64_t *ptr = object_field_prop_ptr(obj, prop);
> +
> +    visit_type_uint64(v, name, ptr, errp);
> +}
> +
> +static void set_uint64(Object *obj, Visitor *v, const char *name,
> +                       void *opaque, Error **errp)
> +{
> +    Property *prop = opaque;
> +    uint64_t *ptr = object_field_prop_ptr(obj, prop);
> +
> +    visit_type_uint64(v, name, ptr, errp);
> +}
> +
> +static void get_int64(Object *obj, Visitor *v, const char *name,
> +                      void *opaque, Error **errp)
> +{
> +    Property *prop = opaque;
> +    int64_t *ptr = object_field_prop_ptr(obj, prop);
> +
> +    visit_type_int64(v, name, ptr, errp);
> +}
> +
> +static void set_int64(Object *obj, Visitor *v, const char *name,
> +                      void *opaque, Error **errp)
> +{
> +    Property *prop = opaque;
> +    int64_t *ptr = object_field_prop_ptr(obj, prop);
> +
> +    visit_type_int64(v, name, ptr, errp);
> +}
> +
> +const PropertyInfo prop_info_uint64 = {
> +    .name  = "uint64",
> +    .get   = get_uint64,
> +    .set   = set_uint64,
> +    .set_default_value = field_prop_set_default_value_uint,
> +};
> +
> +const PropertyInfo prop_info_int64 = {
> +    .name  = "int64",
> +    .get   = get_int64,
> +    .set   = set_int64,
> +    .set_default_value = field_prop_set_default_value_int,
> +};
> +
> +/* --- string --- */
> +
> +static void release_string(Object *obj, const char *name, void *opaque)
> +{
> +    Property *prop = opaque;
> +    g_free(*(char **)object_field_prop_ptr(obj, prop));
> +}
> +
> +static void get_string(Object *obj, Visitor *v, const char *name,
> +                       void *opaque, Error **errp)
> +{
> +    Property *prop = opaque;
> +    char **ptr = object_field_prop_ptr(obj, prop);
> +
> +    if (!*ptr) {
> +        char *str = (char *)"";
> +        visit_type_str(v, name, &str, errp);
> +    } else {
> +        visit_type_str(v, name, ptr, errp);
> +    }
> +}
> +
> +static void set_string(Object *obj, Visitor *v, const char *name,
> +                       void *opaque, Error **errp)
> +{
> +    Property *prop = opaque;
> +    char **ptr = object_field_prop_ptr(obj, prop);
> +    char *str;
> +
> +    if (!visit_type_str(v, name, &str, errp)) {
> +        return;
> +    }
> +    g_free(*ptr);
> +    *ptr = str;
> +}
> +
> +const PropertyInfo prop_info_string = {
> +    .name  = "str",
> +    .release = release_string,
> +    .get   = get_string,
> +    .set   = set_string,
> +};
> +
> +/* --- on/off/auto --- */
> +
> +const PropertyInfo prop_info_on_off_auto = {
> +    .name = "OnOffAuto",
> +    .description = "on/off/auto",
> +    .enum_table = &OnOffAuto_lookup,
> +    .get = field_prop_get_enum,
> +    .set = field_prop_set_enum,
> +    .set_default_value = field_prop_set_default_value_enum,
> +};
> +
> +/* --- 32bit unsigned int 'size' type --- */
> +
> +void field_prop_get_size32(Object *obj, Visitor *v, const char *name,
> +                           void *opaque, Error **errp)
> +{
> +    Property *prop = opaque;
> +    uint32_t *ptr = object_field_prop_ptr(obj, prop);
> +    uint64_t value = *ptr;
> +
> +    visit_type_size(v, name, &value, errp);
> +}
> +
> +static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
> +                       Error **errp)
> +{
> +    Property *prop = opaque;
> +    uint32_t *ptr = object_field_prop_ptr(obj, prop);
> +    uint64_t value;
> +
> +    if (!visit_type_size(v, name, &value, errp)) {
> +        return;
> +    }
> +
> +    if (value > UINT32_MAX) {
> +        error_setg(errp,
> +                   "Property %s.%s doesn't take value %" PRIu64
> +                   " (maximum: %u)",
> +                   object_get_typename(obj), name, value, UINT32_MAX);
> +        return;
> +    }
> +
> +    *ptr = value;
> +}
> +
> +const PropertyInfo prop_info_size32 = {
> +    .name  = "size",
> +    .get = field_prop_get_size32,
> +    .set = set_size32,
> +    .set_default_value = field_prop_set_default_value_uint,
> +};
> +
> +/* --- support for array properties --- */
> +
> +static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
> +                              void *opaque, Error **errp)
> +{
> +    /* Setter for the property which defines the length of a
> +     * variable-sized property array. As well as actually setting the
> +     * array-length field in the device struct, we have to create the
> +     * array itself and dynamically add the corresponding properties.
> +     */
> +    Property *prop = opaque;
> +    ObjectProperty *op = object_property_find_err(obj, name, &error_abort);
> +    uint32_t *alenptr = object_field_prop_ptr(obj, prop);
> +    void **arrayptr = (void *)obj + prop->arrayoffset;
> +    void *eltptr;
> +    const char *arrayname;
> +    int i;
> +
> +    if (*alenptr) {
> +        error_setg(errp, "array size property %s may not be set more than once",
> +                   name);
> +        return;
> +    }
> +    if (!visit_type_uint32(v, name, alenptr, errp)) {
> +        return;
> +    }
> +    if (!*alenptr) {
> +        return;
> +    }
> +
> +    /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix;
> +     * strip it off so we can get the name of the array itself.
> +     */
> +    assert(strncmp(name, PROP_ARRAY_LEN_PREFIX,
> +                   strlen(PROP_ARRAY_LEN_PREFIX)) == 0);
> +    arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX);
> +
> +    /* Note that it is the responsibility of the individual device's deinit
> +     * to free the array proper.
> +     */
> +    *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize);
> +    for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) {
> +        g_autofree char *propname = g_strdup_printf("%s[%d]", arrayname, i);
> +        Property *arrayprop = g_new0(Property, 1);
> +        arrayprop->info = prop->arrayinfo;
> +        /* This ugly piece of pointer arithmetic sets up the offset so
> +         * that when the underlying get/set hooks call qdev_get_prop_ptr
> +         * they get the right answer despite the array element not actually
> +         * being inside the device struct.
> +         */
> +        arrayprop->offset = eltptr - (void *)obj;
> +        assert(object_field_prop_ptr(obj, arrayprop) == eltptr);
> +        object_property_add_field(obj, propname, arrayprop, op->allow_set);
> +    }
> +}
> +
> +const PropertyInfo prop_info_arraylen = {
> +    .name = "uint32",
> +    .get = get_uint32,
> +    .set = set_prop_arraylen,
> +    .set_default_value = field_prop_set_default_value_uint,
> +};
> +
> +/* --- 64bit unsigned int 'size' type --- */
> +
> +static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
> +                     Error **errp)
> +{
> +    Property *prop = opaque;
> +    uint64_t *ptr = object_field_prop_ptr(obj, prop);
> +
> +    visit_type_size(v, name, ptr, errp);
> +}
> +
> +static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
> +                     Error **errp)
> +{
> +    Property *prop = opaque;
> +    uint64_t *ptr = object_field_prop_ptr(obj, prop);
> +
> +    visit_type_size(v, name, ptr, errp);
> +}
> +
> +const PropertyInfo prop_info_size = {
> +    .name  = "size",
> +    .get = get_size,
> +    .set = set_size,
> +    .set_default_value = field_prop_set_default_value_uint,
> +};
> +
> +/* --- object link property --- */
> +
> +static ObjectProperty *create_link_property(ObjectClass *oc, const char *name,
> +                                            Property *prop)
> +{
> +    /*
> +     * NOTE: object_property_allow_set_link is unconditional, but
> +     *       ObjectProperty.allow_set may be set for the property too.
> +     */
> +    return object_class_property_add_link(oc, name, prop->link_type,
> +                                          prop->offset,
> +                                          object_property_allow_set_link,
> +                                          OBJ_PROP_LINK_STRONG);
> +}
> +
> +const PropertyInfo prop_info_link = {
> +    .name = "link",
> +    .create = create_link_property,
> +};
> diff --git a/qom/meson.build b/qom/meson.build
> index e83794454d..7fdfd6fe7b 100644
> --- a/qom/meson.build
> +++ b/qom/meson.build
> @@ -5,6 +5,7 @@ qom_ss.add(files(
>     'object_interfaces.c',
>     'qom-qobject.c',
>     'field-property.c',
> +  'property-types.c',
>   ))
>   
>   qmp_ss.add(files('qom-qmp-cmds.c'))
> 



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 00/44] Make qdev static property API usable by any QOM type
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (43 preceding siblings ...)
  2020-11-04 16:00 ` [PATCH v2 44/44] machine: Register most properties as field properties Eduardo Habkost
@ 2020-11-04 16:36 ` no-reply
  2020-11-06  9:45 ` Kevin Wolf
  45 siblings, 0 replies; 77+ messages in thread
From: no-reply @ 2020-11-04 16:36 UTC (permalink / raw)
  To: ehabkost
  Cc: berrange, philmd, qemu-devel, armbru, pbonzini, imammedo,
	marcandre.lureau, jsnow, stefanb

Patchew URL: https://patchew.org/QEMU/20201104160021.2342108-1-ehabkost@redhat.com/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 20201104160021.2342108-1-ehabkost@redhat.com
Subject: [PATCH v2 00/44] Make qdev static property API usable by any QOM type

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag]         patchew/20201104160021.2342108-1-ehabkost@redhat.com -> patchew/20201104160021.2342108-1-ehabkost@redhat.com
 - [tag update]      patchew/cover.1604464950.git.alistair.francis@wdc.com -> patchew/cover.1604464950.git.alistair.francis@wdc.com
Switched to a new branch 'test'
74d2a4f machine: Register most properties as field properties
e57a72b tests: Use field properties at check-qom-proplist test case
46f06f6 qom: Include static property API reference in documentation
e2754e0 qdev: Move base property types to qom/property-types.c
c83750c qdev: Move core field property code to QOM
c1f0ca8 qdev: PROP_* macros
ba5c6dc qdev: Rename qdev_prop_* to prop_info_*
151ee6d qdev: Move qdev_prop_tpm declaration to tpm_prop.h
d69260f qdev: Rename qdev_get_prop_ptr() to object_field_prop_ptr()
a403dfd qdev: Rename qdev_propinfo_* to field_prop_*
abf9c0e qdev: Make qdev_propinfo_get_uint16() static
949e6fd qdev: Make qdev_prop_allow_set() a ObjectProperty.allow_set callback
5b51a20 qom: Add allow_set callback to ObjectProperty
a785525 qdev: Reuse object_property_add_field() when adding array elements
9c2a384 qdev: Get rid of ArrayElementProperty struct
ae7a992 qdev: Remove ArrayElementProperty.propname field
f065d16 qdev: Avoid unnecessary DeviceState* variable at set_prop_arraylen()
529f3bf qdev: Don't set qdev_prop_name for array elements
a0b808f qdev: Rename Property.name to Property.qdev_prop_name
531c8f7 qdev: Separate generic and device-specific property registration
d7a02b8 qdev: Make qdev_class_add_property() more flexible
05ee196 qdev: Make PropertyInfo.create return ObjectProperty*
ff520f7 qdev: Move dev->realized check to qdev_property_set()
2822481 qdev: Wrap getters and setters in separate helpers
e25f29d qdev: Add name argument to PropertyInfo.create method
a709b9f qdev: Add name parameter to qdev_class_add_property()
0dac961 qdev: Avoid using prop->name unnecessarily
460626c qdev: Get just property name at error_set_from_qdev_prop_error()
3b17a2f sparc: Use DEFINE_PROP for nwindows property
5d719ec qdev: Reuse DEFINE_PROP in all DEFINE_PROP_* macros
461571e qdev: Move softmmu properties to qdev-properties-system.h
39ddc78 qdev: Move UUID property to qdev-properties-system.c
0f14166 qdev: Make error_set_from_qdev_prop_error() get Object* argument
9785bda qdev: Make check_prop_still_unset() get Object* argument
f0f09a3 qdev: Make qdev_find_global_prop() get Object* argument
755cc12 qdev: Make qdev_get_prop_ptr() get Object* arg
743a7b9 qdev: Make bit_prop_set() get Object* argument
c2dedd0 qdev: Make PropertyInfo.print method get Object* argument
40c9d21 qdev: Don't use dev->id on set_size32() error message
8ca5b2b sparc: Check dev->realized at sparc_set_nwindows()
bc82801 qdev: Check dev->realized at set_size()
f2497db qdev: Move property code to qdev-properties.[ch]
969306e cpu: Move cpu_common_props to hw/core/cpu.c
3d0ba5f cs4231: Get rid of empty property array

=== OUTPUT BEGIN ===
1/44 Checking commit 3d0ba5f057e5 (cs4231: Get rid of empty property array)
2/44 Checking commit 969306e01eb3 (cpu: Move cpu_common_props to hw/core/cpu.c)
WARNING: Block comments use a leading /* on a separate line
#51: FILE: hw/core/cpu.c:398:
+    /* Create a memory property for softmmu CPU object,

total: 0 errors, 1 warnings, 49 lines checked

Patch 2/44 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
3/44 Checking commit f2497db84ed4 (qdev: Move property code to qdev-properties.[ch])
4/44 Checking commit bc8280160af2 (qdev: Check dev->realized at set_size())
5/44 Checking commit 8ca5b2bcbef0 (sparc: Check dev->realized at sparc_set_nwindows())
6/44 Checking commit 40c9d2144d73 (qdev: Don't use dev->id on set_size32() error message)
7/44 Checking commit c2dedd0f2664 (qdev: Make PropertyInfo.print method get Object* argument)
8/44 Checking commit 743a7b94d217 (qdev: Make bit_prop_set() get Object* argument)
9/44 Checking commit 755cc1262e1b (qdev: Make qdev_get_prop_ptr() get Object* arg)
10/44 Checking commit f0f09a33e829 (qdev: Make qdev_find_global_prop() get Object* argument)
11/44 Checking commit 9785bdade8e1 (qdev: Make check_prop_still_unset() get Object* argument)
12/44 Checking commit 0f14166bb10b (qdev: Make error_set_from_qdev_prop_error() get Object* argument)
13/44 Checking commit 39ddc785b42a (qdev: Move UUID property to qdev-properties-system.c)
14/44 Checking commit 461571e7c248 (qdev: Move softmmu properties to qdev-properties-system.h)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#879: 
new file mode 100644

total: 0 errors, 1 warnings, 700 lines checked

Patch 14/44 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
15/44 Checking commit 5d719ec2d9af (qdev: Reuse DEFINE_PROP in all DEFINE_PROP_* macros)
16/44 Checking commit 3b17a2f75037 (sparc: Use DEFINE_PROP for nwindows property)
17/44 Checking commit 460626cfbfdf (qdev: Get just property name at error_set_from_qdev_prop_error())
18/44 Checking commit 0dac96100bac (qdev: Avoid using prop->name unnecessarily)
19/44 Checking commit a709b9f94797 (qdev: Add name parameter to qdev_class_add_property())
20/44 Checking commit e25f29d417a4 (qdev: Add name argument to PropertyInfo.create method)
21/44 Checking commit 282248183d5e (qdev: Wrap getters and setters in separate helpers)
22/44 Checking commit ff520f7eebac (qdev: Move dev->realized check to qdev_property_set())
23/44 Checking commit 05ee196058a0 (qdev: Make PropertyInfo.create return ObjectProperty*)
WARNING: line over 80 characters
#33: FILE: hw/core/qdev-properties.c:829:
+                                          qdev_prop_allow_set_link_before_realize,

total: 0 errors, 1 warnings, 28 lines checked

Patch 23/44 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
24/44 Checking commit d7a02b80be4a (qdev: Make qdev_class_add_property() more flexible)
25/44 Checking commit 531c8f760558 (qdev: Separate generic and device-specific property registration)
26/44 Checking commit a0b808face3a (qdev: Rename Property.name to Property.qdev_prop_name)
WARNING: line over 80 characters
#129: FILE: softmmu/qdev-monitor.c:707:
+            value = object_property_print(OBJECT(dev), props->qdev_prop_name, true,

total: 0 errors, 1 warnings, 105 lines checked

Patch 26/44 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
27/44 Checking commit 529f3bfca271 (qdev: Don't set qdev_prop_name for array elements)
28/44 Checking commit f065d1696dbe (qdev: Avoid unnecessary DeviceState* variable at set_prop_arraylen())
29/44 Checking commit ae7a99263c15 (qdev: Remove ArrayElementProperty.propname field)
30/44 Checking commit 9c2a3841ee20 (qdev: Get rid of ArrayElementProperty struct)
31/44 Checking commit a7855258978f (qdev: Reuse object_property_add_field() when adding array elements)
32/44 Checking commit 5b51a20c251d (qom: Add allow_set callback to ObjectProperty)
33/44 Checking commit 949e6fd4ca12 (qdev: Make qdev_prop_allow_set() a ObjectProperty.allow_set callback)
34/44 Checking commit abf9c0ec584b (qdev: Make qdev_propinfo_get_uint16() static)
35/44 Checking commit a403dfd606b4 (qdev: Rename qdev_propinfo_* to field_prop_*)
36/44 Checking commit d69260f76ab9 (qdev: Rename qdev_get_prop_ptr() to object_field_prop_ptr())
37/44 Checking commit 151ee6da64f2 (qdev: Move qdev_prop_tpm declaration to tpm_prop.h)
38/44 Checking commit ba5c6dc490b9 (qdev: Rename qdev_prop_* to prop_info_*)
39/44 Checking commit c1f0ca806ddf (qdev: PROP_* macros)
ERROR: storage class should be at the beginning of the declaration
#28: FILE: include/hw/qdev-properties.h:183:
+    ({ static Property _p = def; &p; })

total: 1 errors, 0 warnings, 60 lines checked

Patch 39/44 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

40/44 Checking commit c83750c46889 (qdev: Move core field property code to QOM)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#255: 
rename from hw/core/qdev-prop-internal.h

total: 0 errors, 1 warnings, 428 lines checked

Patch 40/44 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
41/44 Checking commit e2754e0204f6 (qdev: Move base property types to qom/property-types.c)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#759: 
new file mode 100644

ERROR: storage class should be at the beginning of the declaration
#901: FILE: include/qom/property-types.h:138:
+    ({ static Property _p = def; &p; })

WARNING: Block comments use a leading /* on a separate line
#1408: FILE: qom/property-types.c:442:
+    /* Setter for the property which defines the length of a

WARNING: Block comments use a leading /* on a separate line
#1433: FILE: qom/property-types.c:467:
+    /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix;

WARNING: Block comments use a leading /* on a separate line
#1440: FILE: qom/property-types.c:474:
+    /* Note that it is the responsibility of the individual device's deinit

WARNING: Block comments use a leading /* on a separate line
#1448: FILE: qom/property-types.c:482:
+        /* This ugly piece of pointer arithmetic sets up the offset so

total: 1 errors, 5 warnings, 1471 lines checked

Patch 41/44 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

42/44 Checking commit 46f06f686087 (qom: Include static property API reference in documentation)
WARNING: line over 80 characters
#81: FILE: include/qom/field-property.h:40:
+     * @defval: default value for the property. This is used only if @set_default

total: 0 errors, 1 warnings, 271 lines checked

Patch 42/44 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
43/44 Checking commit e57a72b253fa (tests: Use field properties at check-qom-proplist test case)
ERROR: storage class should be at the beginning of the declaration
#22: FILE: include/qom/property-types.h:245:
+    ({ static Property _p = def; &_p; })

total: 1 errors, 0 warnings, 107 lines checked

Patch 43/44 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

44/44 Checking commit 74d2a4fb19a6 (machine: Register most properties as field properties)
WARNING: line over 80 characters
#294: FILE: hw/core/machine.c:643:
+                                    PROP_BOOL(MachineState, dump_guest_core, true),

WARNING: line over 80 characters
#314: FILE: hw/core/machine.c:659:
+                                    PROP_BOOL(MachineState, enable_graphics, true),

WARNING: line over 80 characters
#330: FILE: hw/core/machine.c:670:
+                                    PROP_BOOL(MachineState, suppress_vmdesc, false),

total: 0 errors, 3 warnings, 346 lines checked

Patch 44/44 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20201104160021.2342108-1-ehabkost@redhat.com/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 18/44] qdev: Avoid using prop->name unnecessarily
  2020-11-04 15:59 ` [PATCH v2 18/44] qdev: Avoid using prop->name unnecessarily Eduardo Habkost
@ 2020-11-04 17:25   ` Stefan Berger
  0 siblings, 0 replies; 77+ messages in thread
From: Stefan Berger @ 2020-11-04 17:25 UTC (permalink / raw)
  To: Eduardo Habkost, qemu-devel
  Cc: Daniel P. Berrange, Igor Mammedov, John Snow, Stefan Berger,
	Markus Armbruster, Philippe Mathieu-Daudé,
	Marc-André Lureau, Paolo Bonzini

On 11/4/20 10:59 AM, Eduardo Habkost wrote:
> We already get the property name as argument to the property
> getter and setters, we don't need to use prop->name.  This will
> make it easier to remove the Property.name field in the future.
>
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>

Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>


> ---
> This is a new patch added in series v2
> ---
> Cc: Stefan Berger <stefanb@linux.vnet.ibm.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Cc: "Daniel P. Berrangé" <berrange@redhat.com>
> Cc: Eduardo Habkost <ehabkost@redhat.com>
> Cc: qemu-devel@nongnu.org
> ---
>   backends/tpm/tpm_util.c          |  2 +-
>   hw/core/qdev-properties-system.c | 14 +++++++-------
>   hw/core/qdev-properties.c        |  4 ++--
>   3 files changed, 10 insertions(+), 10 deletions(-)
>
> diff --git a/backends/tpm/tpm_util.c b/backends/tpm/tpm_util.c
> index e91c21dd4a..dba2f6b04a 100644
> --- a/backends/tpm/tpm_util.c
> +++ b/backends/tpm/tpm_util.c
> @@ -63,7 +63,7 @@ static void set_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
>       s = qemu_find_tpm_be(str);
>       if (s == NULL) {
>           error_setg(errp, "Property '%s.%s' can't find value '%s'",
> -                   object_get_typename(obj), prop->name, str);
> +                   object_get_typename(obj), name, str);
>       } else if (tpm_backend_init(s, TPM_IF(obj), errp) == 0) {
>           *be = s; /* weak reference, avoid cyclic ref */
>       }
> diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
> index 808e7136a0..202abd0e4b 100644
> --- a/hw/core/qdev-properties-system.c
> +++ b/hw/core/qdev-properties-system.c
> @@ -141,7 +141,7 @@ static void set_drive_helper(Object *obj, Visitor *v, const char *name,
>       }
>       if (!blk) {
>           error_setg(errp, "Property '%s.%s' can't find value '%s'",
> -                   object_get_typename(OBJECT(dev)), prop->name, str);
> +                   object_get_typename(OBJECT(dev)), name, str);
>           goto fail;
>       }
>       if (blk_attach_dev(blk, dev) < 0) {
> @@ -262,10 +262,10 @@ static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
>       s = qemu_chr_find(str);
>       if (s == NULL) {
>           error_setg(errp, "Property '%s.%s' can't find value '%s'",
> -                   object_get_typename(obj), prop->name, str);
> +                   object_get_typename(obj), name, str);
>       } else if (!qemu_chr_fe_init(be, s, errp)) {
>           error_prepend(errp, "Property '%s.%s' can't take value '%s': ",
> -                      object_get_typename(obj), prop->name, str);
> +                      object_get_typename(obj), name, str);
>       }
>       g_free(str);
>   }
> @@ -965,7 +965,7 @@ static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
>           abort();
>       }
>   
> -    visit_type_enum(v, prop->name, &speed, prop->info->enum_table, errp);
> +    visit_type_enum(v, name, &speed, prop->info->enum_table, errp);
>   }
>   
>   static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
> @@ -981,7 +981,7 @@ static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
>           return;
>       }
>   
> -    if (!visit_type_enum(v, prop->name, &speed, prop->info->enum_table,
> +    if (!visit_type_enum(v, name, &speed, prop->info->enum_table,
>                            errp)) {
>           return;
>       }
> @@ -1050,7 +1050,7 @@ static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
>           abort();
>       }
>   
> -    visit_type_enum(v, prop->name, &width, prop->info->enum_table, errp);
> +    visit_type_enum(v, name, &width, prop->info->enum_table, errp);
>   }
>   
>   static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
> @@ -1066,7 +1066,7 @@ static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
>           return;
>       }
>   
> -    if (!visit_type_enum(v, prop->name, &width, prop->info->enum_table,
> +    if (!visit_type_enum(v, name, &width, prop->info->enum_table,
>                            errp)) {
>           return;
>       }
> diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
> index a7bbc1235a..69181ce31d 100644
> --- a/hw/core/qdev-properties.c
> +++ b/hw/core/qdev-properties.c
> @@ -50,7 +50,7 @@ void qdev_propinfo_get_enum(Object *obj, Visitor *v, const char *name,
>       Property *prop = opaque;
>       int *ptr = qdev_get_prop_ptr(obj, prop);
>   
> -    visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp);
> +    visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
>   }
>   
>   void qdev_propinfo_set_enum(Object *obj, Visitor *v, const char *name,
> @@ -65,7 +65,7 @@ void qdev_propinfo_set_enum(Object *obj, Visitor *v, const char *name,
>           return;
>       }
>   
> -    visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp);
> +    visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
>   }
>   
>   void qdev_propinfo_set_default_value_enum(ObjectProperty *op,




^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 22/44] qdev: Move dev->realized check to qdev_property_set()
  2020-11-04 15:59   ` Eduardo Habkost
@ 2020-11-04 17:28     ` Stefan Berger
  -1 siblings, 0 replies; 77+ messages in thread
From: Stefan Berger @ 2020-11-04 17:28 UTC (permalink / raw)
  To: Eduardo Habkost, qemu-devel
  Cc: Matthew Rosato, David Hildenbrand, Mark Cave-Ayland,
	Stefano Stabellini, xen-devel, qemu-block, Stefan Berger,
	Paul Durrant, Markus Armbruster, Halil Pasic,
	Christian Borntraeger, Anthony Perard, Marc-André Lureau,
	Philippe Mathieu-Daudé,
	Artyom Tarasenko, Thomas Huth, Alex Williamson, Paolo Bonzini,
	John Snow, Richard Henderson, Kevin Wolf, Daniel P. Berrange,
	Cornelia Huck, qemu-s390x, Max Reitz, Igor Mammedov

On 11/4/20 10:59 AM, Eduardo Habkost wrote:
> Every single qdev property setter function manually checks
> dev->realized.  We can just check dev->realized inside
> qdev_property_set() instead.
>
> The check is being added as a separate function
> (qdev_prop_allow_set()) because it will become a callback later.
>
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>

Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>


> ---
> Changes v1 -> v2:
> * Removed unused variable at xen_block_set_vdev()
> * Redone patch after changes in the previous patches in the
>    series
> ---
> Cc: Stefan Berger <stefanb@linux.vnet.ibm.com>
> Cc: Stefano Stabellini <sstabellini@kernel.org>
> Cc: Anthony Perard <anthony.perard@citrix.com>
> Cc: Paul Durrant <paul@xen.org>
> Cc: Kevin Wolf <kwolf@redhat.com>
> Cc: Max Reitz <mreitz@redhat.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Cc: "Daniel P. Berrangé" <berrange@redhat.com>
> Cc: Eduardo Habkost <ehabkost@redhat.com>
> Cc: Cornelia Huck <cohuck@redhat.com>
> Cc: Halil Pasic <pasic@linux.ibm.com>
> Cc: Christian Borntraeger <borntraeger@de.ibm.com>
> Cc: Richard Henderson <rth@twiddle.net>
> Cc: David Hildenbrand <david@redhat.com>
> Cc: Thomas Huth <thuth@redhat.com>
> Cc: Matthew Rosato <mjrosato@linux.ibm.com>
> Cc: Alex Williamson <alex.williamson@redhat.com>
> Cc: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> Cc: Artyom Tarasenko <atar4qemu@gmail.com>
> Cc: qemu-devel@nongnu.org
> Cc: xen-devel@lists.xenproject.org
> Cc: qemu-block@nongnu.org
> Cc: qemu-s390x@nongnu.org
> ---
>   backends/tpm/tpm_util.c          |   6 --
>   hw/block/xen-block.c             |   6 --
>   hw/core/qdev-properties-system.c |  70 ----------------------
>   hw/core/qdev-properties.c        | 100 ++++++-------------------------
>   hw/s390x/css.c                   |   6 --
>   hw/s390x/s390-pci-bus.c          |   6 --
>   hw/vfio/pci-quirks.c             |   6 --
>   target/sparc/cpu.c               |   6 --
>   8 files changed, 18 insertions(+), 188 deletions(-)
>
> diff --git a/backends/tpm/tpm_util.c b/backends/tpm/tpm_util.c
> index dba2f6b04a..0b07cf55ea 100644
> --- a/backends/tpm/tpm_util.c
> +++ b/backends/tpm/tpm_util.c
> @@ -46,16 +46,10 @@ static void get_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
>   static void set_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
>                       Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       TPMBackend *s, **be = qdev_get_prop_ptr(obj, prop);
>       char *str;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_str(v, name, &str, errp)) {
>           return;
>       }
> diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
> index 905e4acd97..bd1aef63a7 100644
> --- a/hw/block/xen-block.c
> +++ b/hw/block/xen-block.c
> @@ -395,17 +395,11 @@ static int vbd_name_to_disk(const char *name, const char **endp,
>   static void xen_block_set_vdev(Object *obj, Visitor *v, const char *name,
>                                  void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       XenBlockVdev *vdev = qdev_get_prop_ptr(obj, prop);
>       char *str, *p;
>       const char *end;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_str(v, name, &str, errp)) {
>           return;
>       }
> diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
> index 202abd0e4b..0d3e57bba0 100644
> --- a/hw/core/qdev-properties-system.c
> +++ b/hw/core/qdev-properties-system.c
> @@ -94,11 +94,6 @@ static void set_drive_helper(Object *obj, Visitor *v, const char *name,
>       bool blk_created = false;
>       int ret;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_str(v, name, &str, errp)) {
>           return;
>       }
> @@ -230,17 +225,11 @@ static void get_chr(Object *obj, Visitor *v, const char *name, void *opaque,
>   static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
>                       Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       CharBackend *be = qdev_get_prop_ptr(obj, prop);
>       Chardev *s;
>       char *str;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_str(v, name, &str, errp)) {
>           return;
>       }
> @@ -311,18 +300,12 @@ static void get_mac(Object *obj, Visitor *v, const char *name, void *opaque,
>   static void set_mac(Object *obj, Visitor *v, const char *name, void *opaque,
>                       Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       MACAddr *mac = qdev_get_prop_ptr(obj, prop);
>       int i, pos;
>       char *str;
>       const char *p;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_str(v, name, &str, errp)) {
>           return;
>       }
> @@ -390,7 +373,6 @@ static void get_netdev(Object *obj, Visitor *v, const char *name,
>   static void set_netdev(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       NICPeers *peers_ptr = qdev_get_prop_ptr(obj, prop);
>       NetClientState **ncs = peers_ptr->ncs;
> @@ -398,11 +380,6 @@ static void set_netdev(Object *obj, Visitor *v, const char *name,
>       int queues, err = 0, i = 0;
>       char *str;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_str(v, name, &str, errp)) {
>           return;
>       }
> @@ -469,18 +446,12 @@ static void get_audiodev(Object *obj, Visitor *v, const char* name,
>   static void set_audiodev(Object *obj, Visitor *v, const char* name,
>                            void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       QEMUSoundCard *card = qdev_get_prop_ptr(obj, prop);
>       AudioState *state;
>       int err = 0;
>       char *str;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_str(v, name, &str, errp)) {
>           return;
>       }
> @@ -582,11 +553,6 @@ static void set_blocksize(Object *obj, Visitor *v, const char *name,
>       uint64_t value;
>       Error *local_err = NULL;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_size(v, name, &value, errp)) {
>           return;
>       }
> @@ -686,7 +652,6 @@ static void get_reserved_region(Object *obj, Visitor *v, const char *name,
>   static void set_reserved_region(Object *obj, Visitor *v, const char *name,
>                                   void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       ReservedRegion *rr = qdev_get_prop_ptr(obj, prop);
>       Error *local_err = NULL;
> @@ -694,11 +659,6 @@ static void set_reserved_region(Object *obj, Visitor *v, const char *name,
>       char *str;
>       int ret;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       visit_type_str(v, name, &str, &local_err);
>       if (local_err) {
>           error_propagate(errp, local_err);
> @@ -754,17 +714,11 @@ const PropertyInfo qdev_prop_reserved_region = {
>   static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
>                             void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       int32_t value, *ptr = qdev_get_prop_ptr(obj, prop);
>       unsigned int slot, fn, n;
>       char *str;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_str(v, name, &str, NULL)) {
>           if (!visit_type_int32(v, name, &value, errp)) {
>               return;
> @@ -848,7 +802,6 @@ static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
>   static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
>                                    void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       PCIHostDeviceAddress *addr = qdev_get_prop_ptr(obj, prop);
>       char *str, *p;
> @@ -857,11 +810,6 @@ static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
>       unsigned long dom = 0, bus = 0;
>       unsigned int slot = 0, func = 0;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_str(v, name, &str, errp)) {
>           return;
>       }
> @@ -971,16 +919,10 @@ static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
>   static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
>                                      void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       PCIExpLinkSpeed *p = qdev_get_prop_ptr(obj, prop);
>       int speed;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_enum(v, name, &speed, prop->info->enum_table,
>                            errp)) {
>           return;
> @@ -1056,16 +998,10 @@ static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
>   static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
>                                      void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       PCIExpLinkWidth *p = qdev_get_prop_ptr(obj, prop);
>       int width;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_enum(v, name, &width, prop->info->enum_table,
>                            errp)) {
>           return;
> @@ -1128,16 +1064,10 @@ static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
>   static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
>                       Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       QemuUUID *uuid = qdev_get_prop_ptr(obj, prop);
>       char *str;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_str(v, name, &str, errp)) {
>           return;
>       }
> diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
> index 0e5ff81da8..ff36eb250e 100644
> --- a/hw/core/qdev-properties.c
> +++ b/hw/core/qdev-properties.c
> @@ -24,6 +24,19 @@ void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
>       }
>   }
>   
> +/* returns: true if property is allowed to be set, false otherwise */
> +static bool qdev_prop_allow_set(Object *obj, const char *name,
> +                                Error **errp)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +
> +    if (dev->realized) {
> +        qdev_prop_set_after_realize(dev, name, errp);
> +        return false;
> +    }
> +    return true;
> +}
> +
>   void qdev_prop_allow_set_link_before_realize(const Object *obj,
>                                                const char *name,
>                                                Object *val, Error **errp)
> @@ -65,6 +78,11 @@ static void field_prop_set(Object *obj, Visitor *v, const char *name,
>                              void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> +
> +    if (!qdev_prop_allow_set(obj, name, errp)) {
> +        return;
> +    }
> +
>       return prop->info->set(obj, v, name, opaque, errp);
>   }
>   
> @@ -90,15 +108,9 @@ void qdev_propinfo_get_enum(Object *obj, Visitor *v, const char *name,
>   void qdev_propinfo_set_enum(Object *obj, Visitor *v, const char *name,
>                               void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       int *ptr = qdev_get_prop_ptr(obj, prop);
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
>   }
>   
> @@ -148,15 +160,9 @@ static void prop_get_bit(Object *obj, Visitor *v, const char *name,
>   static void prop_set_bit(Object *obj, Visitor *v, const char *name,
>                            void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       bool value;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_bool(v, name, &value, errp)) {
>           return;
>       }
> @@ -208,15 +214,9 @@ static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
>   static void prop_set_bit64(Object *obj, Visitor *v, const char *name,
>                              void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       bool value;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_bool(v, name, &value, errp)) {
>           return;
>       }
> @@ -245,15 +245,9 @@ static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
>   static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
>                        Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       bool *ptr = qdev_get_prop_ptr(obj, prop);
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       visit_type_bool(v, name, ptr, errp);
>   }
>   
> @@ -278,15 +272,9 @@ static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
>   static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
>                         Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       uint8_t *ptr = qdev_get_prop_ptr(obj, prop);
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       visit_type_uint8(v, name, ptr, errp);
>   }
>   
> @@ -323,15 +311,9 @@ void qdev_propinfo_get_uint16(Object *obj, Visitor *v, const char *name,
>   static void set_uint16(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       uint16_t *ptr = qdev_get_prop_ptr(obj, prop);
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       visit_type_uint16(v, name, ptr, errp);
>   }
>   
> @@ -356,15 +338,9 @@ static void get_uint32(Object *obj, Visitor *v, const char *name,
>   static void set_uint32(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       visit_type_uint32(v, name, ptr, errp);
>   }
>   
> @@ -380,15 +356,9 @@ void qdev_propinfo_get_int32(Object *obj, Visitor *v, const char *name,
>   static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
>                         Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       int32_t *ptr = qdev_get_prop_ptr(obj, prop);
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       visit_type_int32(v, name, ptr, errp);
>   }
>   
> @@ -420,15 +390,9 @@ static void get_uint64(Object *obj, Visitor *v, const char *name,
>   static void set_uint64(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       visit_type_uint64(v, name, ptr, errp);
>   }
>   
> @@ -444,15 +408,9 @@ static void get_int64(Object *obj, Visitor *v, const char *name,
>   static void set_int64(Object *obj, Visitor *v, const char *name,
>                         void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       int64_t *ptr = qdev_get_prop_ptr(obj, prop);
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       visit_type_int64(v, name, ptr, errp);
>   }
>   
> @@ -495,16 +453,10 @@ static void get_string(Object *obj, Visitor *v, const char *name,
>   static void set_string(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       char **ptr = qdev_get_prop_ptr(obj, prop);
>       char *str;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_str(v, name, &str, errp)) {
>           return;
>       }
> @@ -545,16 +497,10 @@ void qdev_propinfo_get_size32(Object *obj, Visitor *v, const char *name,
>   static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
>                          Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
>       uint64_t value;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_size(v, name, &value, errp)) {
>           return;
>       }
> @@ -621,10 +567,6 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
>       const char *arrayname;
>       int i;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
>       if (*alenptr) {
>           error_setg(errp, "array size property %s may not be set more than once",
>                      name);
> @@ -864,15 +806,9 @@ static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
>   static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
>                        Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       visit_type_size(v, name, ptr, errp);
>   }
>   
> diff --git a/hw/s390x/css.c b/hw/s390x/css.c
> index 7a44320d12..496e2c5801 100644
> --- a/hw/s390x/css.c
> +++ b/hw/s390x/css.c
> @@ -2372,18 +2372,12 @@ static void get_css_devid(Object *obj, Visitor *v, const char *name,
>   static void set_css_devid(Object *obj, Visitor *v, const char *name,
>                             void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       CssDevId *dev_id = qdev_get_prop_ptr(obj, prop);
>       char *str;
>       int num, n1, n2;
>       unsigned int cssid, ssid, devid;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_str(v, name, &str, errp)) {
>           return;
>       }
> diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
> index ab27b6e848..54fac3851d 100644
> --- a/hw/s390x/s390-pci-bus.c
> +++ b/hw/s390x/s390-pci-bus.c
> @@ -1331,16 +1331,10 @@ static void s390_pci_get_fid(Object *obj, Visitor *v, const char *name,
>   static void s390_pci_set_fid(Object *obj, Visitor *v, const char *name,
>                            void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       S390PCIBusDevice *zpci = S390_PCI_DEVICE(obj);
>       Property *prop = opaque;
>       uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_uint32(v, name, ptr, errp)) {
>           return;
>       }
> diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
> index 53569925a2..802979635c 100644
> --- a/hw/vfio/pci-quirks.c
> +++ b/hw/vfio/pci-quirks.c
> @@ -1498,15 +1498,9 @@ static void set_nv_gpudirect_clique_id(Object *obj, Visitor *v,
>                                          const char *name, void *opaque,
>                                          Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       uint8_t value, *ptr = qdev_get_prop_ptr(obj, prop);
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_uint8(v, name, &value, errp)) {
>           return;
>       }
> diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
> index f5cff4103b..3375fffb38 100644
> --- a/target/sparc/cpu.c
> +++ b/target/sparc/cpu.c
> @@ -798,17 +798,11 @@ static void sparc_get_nwindows(Object *obj, Visitor *v, const char *name,
>   static void sparc_set_nwindows(Object *obj, Visitor *v, const char *name,
>                                  void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       const int64_t min = MIN_NWINDOWS;
>       const int64_t max = MAX_NWINDOWS;
>       SPARCCPU *cpu = SPARC_CPU(obj);
>       int64_t value;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_int(v, name, &value, errp)) {
>           return;
>       }




^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 22/44] qdev: Move dev->realized check to qdev_property_set()
@ 2020-11-04 17:28     ` Stefan Berger
  0 siblings, 0 replies; 77+ messages in thread
From: Stefan Berger @ 2020-11-04 17:28 UTC (permalink / raw)
  To: Eduardo Habkost, qemu-devel
  Cc: Daniel P. Berrange, Paolo Bonzini, Igor Mammedov, Eric Blake,
	Markus Armbruster, Marc-André Lureau, John Snow,
	Philippe Mathieu-Daudé,
	Stefan Berger, Stefano Stabellini, Anthony Perard, Paul Durrant,
	Kevin Wolf, Max Reitz, Cornelia Huck, Halil Pasic,
	Christian Borntraeger, Richard Henderson, David Hildenbrand,
	Thomas Huth, Matthew Rosato, Alex Williamson, Mark Cave-Ayland,
	Artyom Tarasenko, xen-devel, qemu-block, qemu-s390x

On 11/4/20 10:59 AM, Eduardo Habkost wrote:
> Every single qdev property setter function manually checks
> dev->realized.  We can just check dev->realized inside
> qdev_property_set() instead.
>
> The check is being added as a separate function
> (qdev_prop_allow_set()) because it will become a callback later.
>
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>

Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>


> ---
> Changes v1 -> v2:
> * Removed unused variable at xen_block_set_vdev()
> * Redone patch after changes in the previous patches in the
>    series
> ---
> Cc: Stefan Berger <stefanb@linux.vnet.ibm.com>
> Cc: Stefano Stabellini <sstabellini@kernel.org>
> Cc: Anthony Perard <anthony.perard@citrix.com>
> Cc: Paul Durrant <paul@xen.org>
> Cc: Kevin Wolf <kwolf@redhat.com>
> Cc: Max Reitz <mreitz@redhat.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Cc: "Daniel P. Berrangé" <berrange@redhat.com>
> Cc: Eduardo Habkost <ehabkost@redhat.com>
> Cc: Cornelia Huck <cohuck@redhat.com>
> Cc: Halil Pasic <pasic@linux.ibm.com>
> Cc: Christian Borntraeger <borntraeger@de.ibm.com>
> Cc: Richard Henderson <rth@twiddle.net>
> Cc: David Hildenbrand <david@redhat.com>
> Cc: Thomas Huth <thuth@redhat.com>
> Cc: Matthew Rosato <mjrosato@linux.ibm.com>
> Cc: Alex Williamson <alex.williamson@redhat.com>
> Cc: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> Cc: Artyom Tarasenko <atar4qemu@gmail.com>
> Cc: qemu-devel@nongnu.org
> Cc: xen-devel@lists.xenproject.org
> Cc: qemu-block@nongnu.org
> Cc: qemu-s390x@nongnu.org
> ---
>   backends/tpm/tpm_util.c          |   6 --
>   hw/block/xen-block.c             |   6 --
>   hw/core/qdev-properties-system.c |  70 ----------------------
>   hw/core/qdev-properties.c        | 100 ++++++-------------------------
>   hw/s390x/css.c                   |   6 --
>   hw/s390x/s390-pci-bus.c          |   6 --
>   hw/vfio/pci-quirks.c             |   6 --
>   target/sparc/cpu.c               |   6 --
>   8 files changed, 18 insertions(+), 188 deletions(-)
>
> diff --git a/backends/tpm/tpm_util.c b/backends/tpm/tpm_util.c
> index dba2f6b04a..0b07cf55ea 100644
> --- a/backends/tpm/tpm_util.c
> +++ b/backends/tpm/tpm_util.c
> @@ -46,16 +46,10 @@ static void get_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
>   static void set_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
>                       Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       TPMBackend *s, **be = qdev_get_prop_ptr(obj, prop);
>       char *str;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_str(v, name, &str, errp)) {
>           return;
>       }
> diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
> index 905e4acd97..bd1aef63a7 100644
> --- a/hw/block/xen-block.c
> +++ b/hw/block/xen-block.c
> @@ -395,17 +395,11 @@ static int vbd_name_to_disk(const char *name, const char **endp,
>   static void xen_block_set_vdev(Object *obj, Visitor *v, const char *name,
>                                  void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       XenBlockVdev *vdev = qdev_get_prop_ptr(obj, prop);
>       char *str, *p;
>       const char *end;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_str(v, name, &str, errp)) {
>           return;
>       }
> diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
> index 202abd0e4b..0d3e57bba0 100644
> --- a/hw/core/qdev-properties-system.c
> +++ b/hw/core/qdev-properties-system.c
> @@ -94,11 +94,6 @@ static void set_drive_helper(Object *obj, Visitor *v, const char *name,
>       bool blk_created = false;
>       int ret;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_str(v, name, &str, errp)) {
>           return;
>       }
> @@ -230,17 +225,11 @@ static void get_chr(Object *obj, Visitor *v, const char *name, void *opaque,
>   static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
>                       Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       CharBackend *be = qdev_get_prop_ptr(obj, prop);
>       Chardev *s;
>       char *str;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_str(v, name, &str, errp)) {
>           return;
>       }
> @@ -311,18 +300,12 @@ static void get_mac(Object *obj, Visitor *v, const char *name, void *opaque,
>   static void set_mac(Object *obj, Visitor *v, const char *name, void *opaque,
>                       Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       MACAddr *mac = qdev_get_prop_ptr(obj, prop);
>       int i, pos;
>       char *str;
>       const char *p;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_str(v, name, &str, errp)) {
>           return;
>       }
> @@ -390,7 +373,6 @@ static void get_netdev(Object *obj, Visitor *v, const char *name,
>   static void set_netdev(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       NICPeers *peers_ptr = qdev_get_prop_ptr(obj, prop);
>       NetClientState **ncs = peers_ptr->ncs;
> @@ -398,11 +380,6 @@ static void set_netdev(Object *obj, Visitor *v, const char *name,
>       int queues, err = 0, i = 0;
>       char *str;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_str(v, name, &str, errp)) {
>           return;
>       }
> @@ -469,18 +446,12 @@ static void get_audiodev(Object *obj, Visitor *v, const char* name,
>   static void set_audiodev(Object *obj, Visitor *v, const char* name,
>                            void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       QEMUSoundCard *card = qdev_get_prop_ptr(obj, prop);
>       AudioState *state;
>       int err = 0;
>       char *str;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_str(v, name, &str, errp)) {
>           return;
>       }
> @@ -582,11 +553,6 @@ static void set_blocksize(Object *obj, Visitor *v, const char *name,
>       uint64_t value;
>       Error *local_err = NULL;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_size(v, name, &value, errp)) {
>           return;
>       }
> @@ -686,7 +652,6 @@ static void get_reserved_region(Object *obj, Visitor *v, const char *name,
>   static void set_reserved_region(Object *obj, Visitor *v, const char *name,
>                                   void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       ReservedRegion *rr = qdev_get_prop_ptr(obj, prop);
>       Error *local_err = NULL;
> @@ -694,11 +659,6 @@ static void set_reserved_region(Object *obj, Visitor *v, const char *name,
>       char *str;
>       int ret;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       visit_type_str(v, name, &str, &local_err);
>       if (local_err) {
>           error_propagate(errp, local_err);
> @@ -754,17 +714,11 @@ const PropertyInfo qdev_prop_reserved_region = {
>   static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
>                             void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       int32_t value, *ptr = qdev_get_prop_ptr(obj, prop);
>       unsigned int slot, fn, n;
>       char *str;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_str(v, name, &str, NULL)) {
>           if (!visit_type_int32(v, name, &value, errp)) {
>               return;
> @@ -848,7 +802,6 @@ static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
>   static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
>                                    void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       PCIHostDeviceAddress *addr = qdev_get_prop_ptr(obj, prop);
>       char *str, *p;
> @@ -857,11 +810,6 @@ static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
>       unsigned long dom = 0, bus = 0;
>       unsigned int slot = 0, func = 0;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_str(v, name, &str, errp)) {
>           return;
>       }
> @@ -971,16 +919,10 @@ static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
>   static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
>                                      void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       PCIExpLinkSpeed *p = qdev_get_prop_ptr(obj, prop);
>       int speed;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_enum(v, name, &speed, prop->info->enum_table,
>                            errp)) {
>           return;
> @@ -1056,16 +998,10 @@ static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
>   static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
>                                      void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       PCIExpLinkWidth *p = qdev_get_prop_ptr(obj, prop);
>       int width;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_enum(v, name, &width, prop->info->enum_table,
>                            errp)) {
>           return;
> @@ -1128,16 +1064,10 @@ static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
>   static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
>                       Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       QemuUUID *uuid = qdev_get_prop_ptr(obj, prop);
>       char *str;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_str(v, name, &str, errp)) {
>           return;
>       }
> diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
> index 0e5ff81da8..ff36eb250e 100644
> --- a/hw/core/qdev-properties.c
> +++ b/hw/core/qdev-properties.c
> @@ -24,6 +24,19 @@ void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
>       }
>   }
>   
> +/* returns: true if property is allowed to be set, false otherwise */
> +static bool qdev_prop_allow_set(Object *obj, const char *name,
> +                                Error **errp)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +
> +    if (dev->realized) {
> +        qdev_prop_set_after_realize(dev, name, errp);
> +        return false;
> +    }
> +    return true;
> +}
> +
>   void qdev_prop_allow_set_link_before_realize(const Object *obj,
>                                                const char *name,
>                                                Object *val, Error **errp)
> @@ -65,6 +78,11 @@ static void field_prop_set(Object *obj, Visitor *v, const char *name,
>                              void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> +
> +    if (!qdev_prop_allow_set(obj, name, errp)) {
> +        return;
> +    }
> +
>       return prop->info->set(obj, v, name, opaque, errp);
>   }
>   
> @@ -90,15 +108,9 @@ void qdev_propinfo_get_enum(Object *obj, Visitor *v, const char *name,
>   void qdev_propinfo_set_enum(Object *obj, Visitor *v, const char *name,
>                               void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       int *ptr = qdev_get_prop_ptr(obj, prop);
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
>   }
>   
> @@ -148,15 +160,9 @@ static void prop_get_bit(Object *obj, Visitor *v, const char *name,
>   static void prop_set_bit(Object *obj, Visitor *v, const char *name,
>                            void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       bool value;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_bool(v, name, &value, errp)) {
>           return;
>       }
> @@ -208,15 +214,9 @@ static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
>   static void prop_set_bit64(Object *obj, Visitor *v, const char *name,
>                              void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       bool value;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_bool(v, name, &value, errp)) {
>           return;
>       }
> @@ -245,15 +245,9 @@ static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
>   static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
>                        Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       bool *ptr = qdev_get_prop_ptr(obj, prop);
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       visit_type_bool(v, name, ptr, errp);
>   }
>   
> @@ -278,15 +272,9 @@ static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
>   static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
>                         Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       uint8_t *ptr = qdev_get_prop_ptr(obj, prop);
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       visit_type_uint8(v, name, ptr, errp);
>   }
>   
> @@ -323,15 +311,9 @@ void qdev_propinfo_get_uint16(Object *obj, Visitor *v, const char *name,
>   static void set_uint16(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       uint16_t *ptr = qdev_get_prop_ptr(obj, prop);
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       visit_type_uint16(v, name, ptr, errp);
>   }
>   
> @@ -356,15 +338,9 @@ static void get_uint32(Object *obj, Visitor *v, const char *name,
>   static void set_uint32(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       visit_type_uint32(v, name, ptr, errp);
>   }
>   
> @@ -380,15 +356,9 @@ void qdev_propinfo_get_int32(Object *obj, Visitor *v, const char *name,
>   static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
>                         Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       int32_t *ptr = qdev_get_prop_ptr(obj, prop);
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       visit_type_int32(v, name, ptr, errp);
>   }
>   
> @@ -420,15 +390,9 @@ static void get_uint64(Object *obj, Visitor *v, const char *name,
>   static void set_uint64(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       visit_type_uint64(v, name, ptr, errp);
>   }
>   
> @@ -444,15 +408,9 @@ static void get_int64(Object *obj, Visitor *v, const char *name,
>   static void set_int64(Object *obj, Visitor *v, const char *name,
>                         void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       int64_t *ptr = qdev_get_prop_ptr(obj, prop);
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       visit_type_int64(v, name, ptr, errp);
>   }
>   
> @@ -495,16 +453,10 @@ static void get_string(Object *obj, Visitor *v, const char *name,
>   static void set_string(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       char **ptr = qdev_get_prop_ptr(obj, prop);
>       char *str;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_str(v, name, &str, errp)) {
>           return;
>       }
> @@ -545,16 +497,10 @@ void qdev_propinfo_get_size32(Object *obj, Visitor *v, const char *name,
>   static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
>                          Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
>       uint64_t value;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_size(v, name, &value, errp)) {
>           return;
>       }
> @@ -621,10 +567,6 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
>       const char *arrayname;
>       int i;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
>       if (*alenptr) {
>           error_setg(errp, "array size property %s may not be set more than once",
>                      name);
> @@ -864,15 +806,9 @@ static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
>   static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
>                        Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       visit_type_size(v, name, ptr, errp);
>   }
>   
> diff --git a/hw/s390x/css.c b/hw/s390x/css.c
> index 7a44320d12..496e2c5801 100644
> --- a/hw/s390x/css.c
> +++ b/hw/s390x/css.c
> @@ -2372,18 +2372,12 @@ static void get_css_devid(Object *obj, Visitor *v, const char *name,
>   static void set_css_devid(Object *obj, Visitor *v, const char *name,
>                             void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       CssDevId *dev_id = qdev_get_prop_ptr(obj, prop);
>       char *str;
>       int num, n1, n2;
>       unsigned int cssid, ssid, devid;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_str(v, name, &str, errp)) {
>           return;
>       }
> diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
> index ab27b6e848..54fac3851d 100644
> --- a/hw/s390x/s390-pci-bus.c
> +++ b/hw/s390x/s390-pci-bus.c
> @@ -1331,16 +1331,10 @@ static void s390_pci_get_fid(Object *obj, Visitor *v, const char *name,
>   static void s390_pci_set_fid(Object *obj, Visitor *v, const char *name,
>                            void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       S390PCIBusDevice *zpci = S390_PCI_DEVICE(obj);
>       Property *prop = opaque;
>       uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_uint32(v, name, ptr, errp)) {
>           return;
>       }
> diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
> index 53569925a2..802979635c 100644
> --- a/hw/vfio/pci-quirks.c
> +++ b/hw/vfio/pci-quirks.c
> @@ -1498,15 +1498,9 @@ static void set_nv_gpudirect_clique_id(Object *obj, Visitor *v,
>                                          const char *name, void *opaque,
>                                          Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
>       uint8_t value, *ptr = qdev_get_prop_ptr(obj, prop);
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_uint8(v, name, &value, errp)) {
>           return;
>       }
> diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
> index f5cff4103b..3375fffb38 100644
> --- a/target/sparc/cpu.c
> +++ b/target/sparc/cpu.c
> @@ -798,17 +798,11 @@ static void sparc_get_nwindows(Object *obj, Visitor *v, const char *name,
>   static void sparc_set_nwindows(Object *obj, Visitor *v, const char *name,
>                                  void *opaque, Error **errp)
>   {
> -    DeviceState *dev = DEVICE(obj);
>       const int64_t min = MIN_NWINDOWS;
>       const int64_t max = MAX_NWINDOWS;
>       SPARCCPU *cpu = SPARC_CPU(obj);
>       int64_t value;
>   
> -    if (dev->realized) {
> -        qdev_prop_set_after_realize(dev, name, errp);
> -        return;
> -    }
> -
>       if (!visit_type_int(v, name, &value, errp)) {
>           return;
>       }




^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 41/44] qdev: Move base property types to qom/property-types.c
  2020-11-04 16:36   ` Paolo Bonzini
@ 2020-11-04 20:50     ` Eduardo Habkost
  2020-11-05  9:36       ` Paolo Bonzini
  0 siblings, 1 reply; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-04 20:50 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Daniel P. Berrange, John Snow, Philippe Mathieu-Daudé,
	Markus Armbruster, qemu-devel, Marc-André Lureau,
	Igor Mammedov, Stefan Berger

On Wed, Nov 04, 2020 at 05:36:20PM +0100, Paolo Bonzini wrote:
> On 04/11/20 17:00, Eduardo Habkost wrote:
> > Move all property types from qdev-properties.c to
> > qom/property-types.c.
> > 
> > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> > ---
> > Changes v1 -> v2:
> > * Rebased after changes in previous patches in the series
> > ---
> > Cc: Paolo Bonzini <pbonzini@redhat.com>
> > Cc: "Daniel P. Berrangé" <berrange@redhat.com>
> > Cc: Eduardo Habkost <ehabkost@redhat.com>
> > Cc: qemu-devel@nongnu.org
> > ---
> >   include/hw/qdev-properties.h | 179 +-----------
> >   include/qom/property-types.h | 185 ++++++++++++
> >   hw/core/qdev-properties.c    | 537 ----------------------------------
> >   qom/property-types.c         | 545 +++++++++++++++++++++++++++++++++++
> >   qom/meson.build              |   1 +
> >   5 files changed, 732 insertions(+), 715 deletions(-)
> >   create mode 100644 include/qom/property-types.h
> >   create mode 100644 qom/property-types.c
> 
> I would merge property-types.h and field-property.h in a single file.

I like keeping them separate, to force us to define the API used
to create new property types clearly.

What if I create a qom/qom.h header that includes object.h +
field-properties.h + property-types.h to make this easier to use?

> 
> Actually I wouldn't even bother having separate headers, however it's
> certainly valuable to have headers like you have in patch 42:
> 
> Core QOM API Reference
> ----------------------
> 
> ....
> 
> 
> Field Property API Reference
> ----------------------------
> 
> ....
> 
> 
> 
> I'm not sure if it's possible to include rST headers in .h files.

It is possible to include rST headers in doc comments, but the
way the DOC: blocks work in kernel-doc is weird and has subtle
rules and side effects.

> 
> Paolo
> 
> > diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
> > index bee26d0319..939b6dbf4e 100644
> > --- a/include/hw/qdev-properties.h
> > +++ b/include/hw/qdev-properties.h
> > @@ -3,184 +3,7 @@
> >   #include "hw/qdev-core.h"
> >   #include "qom/field-property.h"
> > -
> > -/*** qdev-properties.c ***/
> > -
> > -extern const PropertyInfo prop_info_bit;
> > -extern const PropertyInfo prop_info_bit64;
> > -extern const PropertyInfo prop_info_bool;
> > -extern const PropertyInfo prop_info_enum;
> > -extern const PropertyInfo prop_info_uint8;
> > -extern const PropertyInfo prop_info_uint16;
> > -extern const PropertyInfo prop_info_uint32;
> > -extern const PropertyInfo prop_info_int32;
> > -extern const PropertyInfo prop_info_uint64;
> > -extern const PropertyInfo prop_info_int64;
> > -extern const PropertyInfo prop_info_size;
> > -extern const PropertyInfo prop_info_string;
> > -extern const PropertyInfo prop_info_on_off_auto;
> > -extern const PropertyInfo prop_info_size32;
> > -extern const PropertyInfo prop_info_arraylen;
> > -extern const PropertyInfo prop_info_link;
> > -
> > -#define DEFINE_PROP(_name, _state, _field, _prop, _type, ...) {  \
> > -        .qdev_prop_name      = (_name),                          \
> > -        .info      = &(_prop),                                   \
> > -        .offset    = offsetof(_state, _field)                    \
> > -            + type_check(_type, typeof_field(_state, _field)),   \
> > -        __VA_ARGS__                                              \
> > -        }
> > -
> > -#define DEFINE_PROP_SIGNED(_name, _state, _field, _defval, _prop, _type) \
> > -    DEFINE_PROP(_name, _state, _field, _prop, _type,                     \
> > -                .set_default = true,                                     \
> > -                .defval.i    = (_type)_defval)
> > -
> > -#define DEFINE_PROP_SIGNED_NODEFAULT(_name, _state, _field, _prop, _type) \
> > -    DEFINE_PROP(_name, _state, _field, _prop, _type)
> > -
> > -#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval)   \
> > -    DEFINE_PROP(_name, _state, _field, prop_info_bit, uint32_t, \
> > -                .bitnr       = (_bit),                          \
> > -                .set_default = true,                            \
> > -                .defval.u    = (bool)_defval)
> > -
> > -#define DEFINE_PROP_UNSIGNED(_name, _state, _field, _defval, _prop, _type) \
> > -    DEFINE_PROP(_name, _state, _field, _prop, _type,                       \
> > -                .set_default = true,                                       \
> > -                .defval.u  = (_type)_defval)
> > -
> > -#define DEFINE_PROP_UNSIGNED_NODEFAULT(_name, _state, _field, _prop, _type) \
> > -    DEFINE_PROP(_name, _state, _field, _prop, _type)
> > -
> > -#define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval)   \
> > -    DEFINE_PROP(_name, _state, _field, prop_info_bit64, uint64_t, \
> > -                .bitnr    = (_bit),                               \
> > -                .set_default = true,                              \
> > -                .defval.u  = (bool)_defval)
> > -
> > -#define DEFINE_PROP_BOOL(_name, _state, _field, _defval)     \
> > -    DEFINE_PROP(_name, _state, _field, prop_info_bool, bool, \
> > -                .set_default = true,                         \
> > -                .defval.u    = (bool)_defval)
> > -
> > -#define PROP_ARRAY_LEN_PREFIX "len-"
> > -
> > -/**
> > - * DEFINE_PROP_ARRAY:
> > - * @_name: name of the array
> > - * @_state: name of the device state structure type
> > - * @_field: uint32_t field in @_state to hold the array length
> > - * @_arrayfield: field in @_state (of type '@_arraytype *') which
> > - *               will point to the array
> > - * @_arrayprop: PropertyInfo defining what property the array elements have
> > - * @_arraytype: C type of the array elements
> > - *
> > - * Define device properties for a variable-length array _name.  A
> > - * static property "len-arrayname" is defined. When the device creator
> > - * sets this property to the desired length of array, further dynamic
> > - * properties "arrayname[0]", "arrayname[1]", ...  are defined so the
> > - * device creator can set the array element values. Setting the
> > - * "len-arrayname" property more than once is an error.
> > - *
> > - * When the array length is set, the @_field member of the device
> > - * struct is set to the array length, and @_arrayfield is set to point
> > - * to (zero-initialised) memory allocated for the array.  For a zero
> > - * length array, @_field will be set to 0 and @_arrayfield to NULL.
> > - * It is the responsibility of the device deinit code to free the
> > - * @_arrayfield memory.
> > - */
> > -#define DEFINE_PROP_ARRAY(_name, _state, _field,               \
> > -                          _arrayfield, _arrayprop, _arraytype) \
> > -    DEFINE_PROP((PROP_ARRAY_LEN_PREFIX _name),                 \
> > -                _state, _field, prop_info_arraylen, uint32_t,  \
> > -                .set_default = true,                           \
> > -                .defval.u = 0,                                 \
> > -                .arrayinfo = &(_arrayprop),                    \
> > -                .arrayfieldsize = sizeof(_arraytype),          \
> > -                .arrayoffset = offsetof(_state, _arrayfield))
> > -
> > -#define DEFINE_PROP_LINK(_name, _state, _field, _type, _ptr_type)     \
> > -    DEFINE_PROP(_name, _state, _field, prop_info_link, _ptr_type,     \
> > -                .link_type  = _type)
> > -
> > -#define DEFINE_PROP_UINT8(_n, _s, _f, _d)                       \
> > -    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint8, uint8_t)
> > -#define DEFINE_PROP_UINT16(_n, _s, _f, _d)                      \
> > -    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint16, uint16_t)
> > -#define DEFINE_PROP_UINT32(_n, _s, _f, _d)                      \
> > -    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint32, uint32_t)
> > -#define DEFINE_PROP_INT32(_n, _s, _f, _d)                      \
> > -    DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_int32, int32_t)
> > -#define DEFINE_PROP_UINT64(_n, _s, _f, _d)                      \
> > -    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint64, uint64_t)
> > -#define DEFINE_PROP_INT64(_n, _s, _f, _d)                      \
> > -    DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_int64, int64_t)
> > -#define DEFINE_PROP_SIZE(_n, _s, _f, _d)                       \
> > -    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_size, uint64_t)
> > -#define DEFINE_PROP_STRING(_n, _s, _f)             \
> > -    DEFINE_PROP(_n, _s, _f, prop_info_string, char*)
> > -#define DEFINE_PROP_ON_OFF_AUTO(_n, _s, _f, _d) \
> > -    DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_on_off_auto, OnOffAuto)
> > -#define DEFINE_PROP_SIZE32(_n, _s, _f, _d)                       \
> > -    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_size32, uint32_t)
> > -
> > -#define DEFINE_PROP_END_OF_LIST()               \
> > -    {}
> > -
> > -/*
> > - * The PROP_* macros can be used as arguments for
> > - * object_class_property_add_field().  They will evaluate to a
> > - * pointer to a static variable.
> > - */
> > -
> > -#define FIELD_PROP(def) \
> > -    ({ static Property _p = def; &p; })
> > -
> > -#define PROP_SIGNED(...) \
> > -    FIELD_PROP(DEFINE_PROP_SIGNED(NULL, __VA_ARGS__))
> > -#define PROP_SIGNED_NODEFAULT(...) \
> > -    FIELD_PROP(DEFINE_PROP_SIGNED_NODEFAULT(NULL, __VA_ARGS__))
> > -#define PROP_BIT(...) \
> > -    FIELD_PROP(DEFINE_PROP_BIT(NULL, __VA_ARGS__))
> > -#define PROP_UNSIGNED(...) \
> > -    FIELD_PROP(DEFINE_PROP_UNSIGNED(NULL, __VA_ARGS__))
> > -#define PROP_UNSIGNED_NODEFAULT(...) \
> > -    FIELD_PROP(DEFINE_PROP_UNSIGNED_NODEFAULT(NULL, __VA_ARGS__))
> > -#define PROP_BIT64(...) \
> > -    FIELD_PROP(DEFINE_PROP_BIT64(NULL, __VA_ARGS__))
> > -#define PROP_BOOL(...) \
> > -    FIELD_PROP(DEFINE_PROP_BOOL(NULL, __VA_ARGS__))
> > -#define PROP_ARRAY(...) \
> > -    FIELD_PROP(DEFINE_PROP_ARRAY(NULL, __VA_ARGS__))
> > -#define PROP_LINK(...) \
> > -    FIELD_PROP(DEFINE_PROP_LINK(NULL, __VA_ARGS__))
> > -#define PROP_UINT8(...) \
> > -    FIELD_PROP(DEFINE_PROP_UINT8(NULL, __VA_ARGS__))
> > -#define PROP_UINT16(...) \
> > -    FIELD_PROP(DEFINE_PROP_UINT16(NULL, __VA_ARGS__))
> > -#define PROP_UINT32(...) \
> > -    FIELD_PROP(DEFINE_PROP_UINT32(NULL, __VA_ARGS__))
> > -#define PROP_INT32(...) \
> > -    FIELD_PROP(DEFINE_PROP_INT32(NULL, __VA_ARGS__))
> > -#define PROP_UINT64(...) \
> > -    FIELD_PROP(DEFINE_PROP_UINT64(NULL, __VA_ARGS__))
> > -#define PROP_INT64(...) \
> > -    FIELD_PROP(DEFINE_PROP_INT64(NULL, __VA_ARGS__))
> > -#define PROP_SIZE(...) \
> > -    FIELD_PROP(DEFINE_PROP_SIZE(NULL, __VA_ARGS__))
> > -#define PROP_STRING(...) \
> > -    FIELD_PROP(DEFINE_PROP_STRING(NULL, __VA_ARGS__))
> > -#define PROP_ON_OFF_AUTO(...) \
> > -    FIELD_PROP(DEFINE_PROP_ON_OFF_AUTO(NULL, __VA_ARGS__))
> > -#define PROP_SIZE32(...) \
> > -    FIELD_PROP(DEFINE_PROP_SIZE32(NULL, __VA_ARGS__))
> > -#define PROP_UUID(...) \
> > -    FIELD_PROP(DEFINE_PROP_UUID(NULL, __VA_ARGS__))
> > -#define PROP_UUID_NODEFAULT(...) \
> > -    FIELD_PROP(DEFINE_PROP_UUID_NODEFAULT(NULL, __VA_ARGS__))
> > -#define PROP_END_OF_LIST(...) \
> > -    FIELD_PROP(DEFINE_PROP_END_OF_LIST(NULL, __VA_ARGS__))
> > +#include "qom/property-types.h"
> >   /*
> >    * Set properties between creation and realization.
> > diff --git a/include/qom/property-types.h b/include/qom/property-types.h
> > new file mode 100644
> > index 0000000000..75f758e835
> > --- /dev/null
> > +++ b/include/qom/property-types.h
> > @@ -0,0 +1,185 @@
> > +/*
> > + * QOM field property types
> > + */
> > +#ifndef QOM_PROPERTY_TYPES_H
> > +#define QOM_PROPERTY_TYPES_H
> > +
> > +#include "qom/field-property.h"
> > +
> > +extern const PropertyInfo prop_info_bit;
> > +extern const PropertyInfo prop_info_bit64;
> > +extern const PropertyInfo prop_info_bool;
> > +extern const PropertyInfo prop_info_enum;
> > +extern const PropertyInfo prop_info_uint8;
> > +extern const PropertyInfo prop_info_uint16;
> > +extern const PropertyInfo prop_info_uint32;
> > +extern const PropertyInfo prop_info_int32;
> > +extern const PropertyInfo prop_info_uint64;
> > +extern const PropertyInfo prop_info_int64;
> > +extern const PropertyInfo prop_info_size;
> > +extern const PropertyInfo prop_info_string;
> > +extern const PropertyInfo prop_info_on_off_auto;
> > +extern const PropertyInfo prop_info_size32;
> > +extern const PropertyInfo prop_info_arraylen;
> > +extern const PropertyInfo prop_info_link;
> > +
> > +#define DEFINE_PROP(_name, _state, _field, _prop, _type, ...) {  \
> > +        .qdev_prop_name      = (_name),                          \
> > +        .info      = &(_prop),                                   \
> > +        .offset    = offsetof(_state, _field)                    \
> > +            + type_check(_type, typeof_field(_state, _field)),   \
> > +        __VA_ARGS__                                              \
> > +        }
> > +
> > +#define DEFINE_PROP_SIGNED(_name, _state, _field, _defval, _prop, _type) \
> > +    DEFINE_PROP(_name, _state, _field, _prop, _type,                     \
> > +                .set_default = true,                                     \
> > +                .defval.i    = (_type)_defval)
> > +
> > +#define DEFINE_PROP_SIGNED_NODEFAULT(_name, _state, _field, _prop, _type) \
> > +    DEFINE_PROP(_name, _state, _field, _prop, _type)
> > +
> > +#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval)   \
> > +    DEFINE_PROP(_name, _state, _field, prop_info_bit, uint32_t, \
> > +                .bitnr       = (_bit),                          \
> > +                .set_default = true,                            \
> > +                .defval.u    = (bool)_defval)
> > +
> > +#define DEFINE_PROP_UNSIGNED(_name, _state, _field, _defval, _prop, _type) \
> > +    DEFINE_PROP(_name, _state, _field, _prop, _type,                       \
> > +                .set_default = true,                                       \
> > +                .defval.u  = (_type)_defval)
> > +
> > +#define DEFINE_PROP_UNSIGNED_NODEFAULT(_name, _state, _field, _prop, _type) \
> > +    DEFINE_PROP(_name, _state, _field, _prop, _type)
> > +
> > +#define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval)   \
> > +    DEFINE_PROP(_name, _state, _field, prop_info_bit64, uint64_t, \
> > +                .bitnr    = (_bit),                               \
> > +                .set_default = true,                              \
> > +                .defval.u  = (bool)_defval)
> > +
> > +#define DEFINE_PROP_BOOL(_name, _state, _field, _defval)     \
> > +    DEFINE_PROP(_name, _state, _field, prop_info_bool, bool, \
> > +                .set_default = true,                         \
> > +                .defval.u    = (bool)_defval)
> > +
> > +#define PROP_ARRAY_LEN_PREFIX "len-"
> > +
> > +/**
> > + * DEFINE_PROP_ARRAY:
> > + * @_name: name of the array
> > + * @_state: name of the device state structure type
> > + * @_field: uint32_t field in @_state to hold the array length
> > + * @_arrayfield: field in @_state (of type '@_arraytype *') which
> > + *               will point to the array
> > + * @_arrayprop: PropertyInfo defining what property the array elements have
> > + * @_arraytype: C type of the array elements
> > + *
> > + * Define device properties for a variable-length array _name.  A
> > + * static property "len-arrayname" is defined. When the device creator
> > + * sets this property to the desired length of array, further dynamic
> > + * properties "arrayname[0]", "arrayname[1]", ...  are defined so the
> > + * device creator can set the array element values. Setting the
> > + * "len-arrayname" property more than once is an error.
> > + *
> > + * When the array length is set, the @_field member of the device
> > + * struct is set to the array length, and @_arrayfield is set to point
> > + * to (zero-initialised) memory allocated for the array.  For a zero
> > + * length array, @_field will be set to 0 and @_arrayfield to NULL.
> > + * It is the responsibility of the device deinit code to free the
> > + * @_arrayfield memory.
> > + */
> > +#define DEFINE_PROP_ARRAY(_name, _state, _field,               \
> > +                          _arrayfield, _arrayprop, _arraytype) \
> > +    DEFINE_PROP((PROP_ARRAY_LEN_PREFIX _name),                 \
> > +                _state, _field, prop_info_arraylen, uint32_t,  \
> > +                .set_default = true,                           \
> > +                .defval.u = 0,                                 \
> > +                .arrayinfo = &(_arrayprop),                    \
> > +                .arrayfieldsize = sizeof(_arraytype),          \
> > +                .arrayoffset = offsetof(_state, _arrayfield))
> > +
> > +#define DEFINE_PROP_LINK(_name, _state, _field, _type, _ptr_type)     \
> > +    DEFINE_PROP(_name, _state, _field, prop_info_link, _ptr_type,     \
> > +                .link_type  = _type)
> > +
> > +#define DEFINE_PROP_UINT8(_n, _s, _f, _d)                       \
> > +    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint8, uint8_t)
> > +#define DEFINE_PROP_UINT16(_n, _s, _f, _d)                      \
> > +    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint16, uint16_t)
> > +#define DEFINE_PROP_UINT32(_n, _s, _f, _d)                      \
> > +    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint32, uint32_t)
> > +#define DEFINE_PROP_INT32(_n, _s, _f, _d)                      \
> > +    DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_int32, int32_t)
> > +#define DEFINE_PROP_UINT64(_n, _s, _f, _d)                      \
> > +    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint64, uint64_t)
> > +#define DEFINE_PROP_INT64(_n, _s, _f, _d)                      \
> > +    DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_int64, int64_t)
> > +#define DEFINE_PROP_SIZE(_n, _s, _f, _d)                       \
> > +    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_size, uint64_t)
> > +#define DEFINE_PROP_STRING(_n, _s, _f)             \
> > +    DEFINE_PROP(_n, _s, _f, prop_info_string, char*)
> > +#define DEFINE_PROP_ON_OFF_AUTO(_n, _s, _f, _d) \
> > +    DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_on_off_auto, OnOffAuto)
> > +#define DEFINE_PROP_SIZE32(_n, _s, _f, _d)                       \
> > +    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_size32, uint32_t)
> > +
> > +#define DEFINE_PROP_END_OF_LIST()               \
> > +    {}
> > +
> > +/*
> > + * The PROP_* macros can be used as arguments for
> > + * object_class_property_add_field().  They will evaluate to a
> > + * pointer to a static variable.
> > + */
> > +
> > +#define FIELD_PROP(def) \
> > +    ({ static Property _p = def; &p; })
> > +
> > +#define PROP_SIGNED(...) \
> > +    FIELD_PROP(DEFINE_PROP_SIGNED(NULL, __VA_ARGS__))
> > +#define PROP_SIGNED_NODEFAULT(...) \
> > +    FIELD_PROP(DEFINE_PROP_SIGNED_NODEFAULT(NULL, __VA_ARGS__))
> > +#define PROP_BIT(...) \
> > +    FIELD_PROP(DEFINE_PROP_BIT(NULL, __VA_ARGS__))
> > +#define PROP_UNSIGNED(...) \
> > +    FIELD_PROP(DEFINE_PROP_UNSIGNED(NULL, __VA_ARGS__))
> > +#define PROP_UNSIGNED_NODEFAULT(...) \
> > +    FIELD_PROP(DEFINE_PROP_UNSIGNED_NODEFAULT(NULL, __VA_ARGS__))
> > +#define PROP_BIT64(...) \
> > +    FIELD_PROP(DEFINE_PROP_BIT64(NULL, __VA_ARGS__))
> > +#define PROP_BOOL(...) \
> > +    FIELD_PROP(DEFINE_PROP_BOOL(NULL, __VA_ARGS__))
> > +#define PROP_ARRAY(...) \
> > +    FIELD_PROP(DEFINE_PROP_ARRAY(NULL, __VA_ARGS__))
> > +#define PROP_LINK(...) \
> > +    FIELD_PROP(DEFINE_PROP_LINK(NULL, __VA_ARGS__))
> > +#define PROP_UINT8(...) \
> > +    FIELD_PROP(DEFINE_PROP_UINT8(NULL, __VA_ARGS__))
> > +#define PROP_UINT16(...) \
> > +    FIELD_PROP(DEFINE_PROP_UINT16(NULL, __VA_ARGS__))
> > +#define PROP_UINT32(...) \
> > +    FIELD_PROP(DEFINE_PROP_UINT32(NULL, __VA_ARGS__))
> > +#define PROP_INT32(...) \
> > +    FIELD_PROP(DEFINE_PROP_INT32(NULL, __VA_ARGS__))
> > +#define PROP_UINT64(...) \
> > +    FIELD_PROP(DEFINE_PROP_UINT64(NULL, __VA_ARGS__))
> > +#define PROP_INT64(...) \
> > +    FIELD_PROP(DEFINE_PROP_INT64(NULL, __VA_ARGS__))
> > +#define PROP_SIZE(...) \
> > +    FIELD_PROP(DEFINE_PROP_SIZE(NULL, __VA_ARGS__))
> > +#define PROP_STRING(...) \
> > +    FIELD_PROP(DEFINE_PROP_STRING(NULL, __VA_ARGS__))
> > +#define PROP_ON_OFF_AUTO(...) \
> > +    FIELD_PROP(DEFINE_PROP_ON_OFF_AUTO(NULL, __VA_ARGS__))
> > +#define PROP_SIZE32(...) \
> > +    FIELD_PROP(DEFINE_PROP_SIZE32(NULL, __VA_ARGS__))
> > +#define PROP_UUID(...) \
> > +    FIELD_PROP(DEFINE_PROP_UUID(NULL, __VA_ARGS__))
> > +#define PROP_UUID_NODEFAULT(...) \
> > +    FIELD_PROP(DEFINE_PROP_UUID_NODEFAULT(NULL, __VA_ARGS__))
> > +#define PROP_END_OF_LIST(...) \
> > +    FIELD_PROP(DEFINE_PROP_END_OF_LIST(NULL, __VA_ARGS__))
> > +
> > +#endif
> > diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
> > index b75730f15c..5bb4ff5f46 100644
> > --- a/hw/core/qdev-properties.c
> > +++ b/hw/core/qdev-properties.c
> > @@ -50,496 +50,6 @@ void qdev_prop_allow_set_link_before_realize(const Object *obj,
> >       }
> >   }
> > -void field_prop_get_enum(Object *obj, Visitor *v, const char *name,
> > -                         void *opaque, Error **errp)
> > -{
> > -    Property *prop = opaque;
> > -    int *ptr = object_field_prop_ptr(obj, prop);
> > -
> > -    visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
> > -}
> > -
> > -void field_prop_set_enum(Object *obj, Visitor *v, const char *name,
> > -                         void *opaque, Error **errp)
> > -{
> > -    Property *prop = opaque;
> > -    int *ptr = object_field_prop_ptr(obj, prop);
> > -
> > -    visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
> > -}
> > -
> > -void field_prop_set_default_value_enum(ObjectProperty *op,
> > -                                       const Property *prop)
> > -{
> > -    object_property_set_default_str(op,
> > -        qapi_enum_lookup(prop->info->enum_table, prop->defval.i));
> > -}
> > -
> > -const PropertyInfo prop_info_enum = {
> > -    .name  = "enum",
> > -    .get   = field_prop_get_enum,
> > -    .set   = field_prop_set_enum,
> > -    .set_default_value = field_prop_set_default_value_enum,
> > -};
> > -
> > -/* Bit */
> > -
> > -static uint32_t qdev_get_prop_mask(Property *prop)
> > -{
> > -    assert(prop->info == &prop_info_bit);
> > -    return 0x1 << prop->bitnr;
> > -}
> > -
> > -static void bit_prop_set(Object *obj, Property *props, bool val)
> > -{
> > -    uint32_t *p = object_field_prop_ptr(obj, props);
> > -    uint32_t mask = qdev_get_prop_mask(props);
> > -    if (val) {
> > -        *p |= mask;
> > -    } else {
> > -        *p &= ~mask;
> > -    }
> > -}
> > -
> > -static void prop_get_bit(Object *obj, Visitor *v, const char *name,
> > -                         void *opaque, Error **errp)
> > -{
> > -    Property *prop = opaque;
> > -    uint32_t *p = object_field_prop_ptr(obj, prop);
> > -    bool value = (*p & qdev_get_prop_mask(prop)) != 0;
> > -
> > -    visit_type_bool(v, name, &value, errp);
> > -}
> > -
> > -static void prop_set_bit(Object *obj, Visitor *v, const char *name,
> > -                         void *opaque, Error **errp)
> > -{
> > -    Property *prop = opaque;
> > -    bool value;
> > -
> > -    if (!visit_type_bool(v, name, &value, errp)) {
> > -        return;
> > -    }
> > -    bit_prop_set(obj, prop, value);
> > -}
> > -
> > -static void set_default_value_bool(ObjectProperty *op, const Property *prop)
> > -{
> > -    object_property_set_default_bool(op, prop->defval.u);
> > -}
> > -
> > -const PropertyInfo prop_info_bit = {
> > -    .name  = "bool",
> > -    .description = "on/off",
> > -    .get   = prop_get_bit,
> > -    .set   = prop_set_bit,
> > -    .set_default_value = set_default_value_bool,
> > -};
> > -
> > -/* Bit64 */
> > -
> > -static uint64_t qdev_get_prop_mask64(Property *prop)
> > -{
> > -    assert(prop->info == &prop_info_bit64);
> > -    return 0x1ull << prop->bitnr;
> > -}
> > -
> > -static void bit64_prop_set(Object *obj, Property *props, bool val)
> > -{
> > -    uint64_t *p = object_field_prop_ptr(obj, props);
> > -    uint64_t mask = qdev_get_prop_mask64(props);
> > -    if (val) {
> > -        *p |= mask;
> > -    } else {
> > -        *p &= ~mask;
> > -    }
> > -}
> > -
> > -static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
> > -                           void *opaque, Error **errp)
> > -{
> > -    Property *prop = opaque;
> > -    uint64_t *p = object_field_prop_ptr(obj, prop);
> > -    bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
> > -
> > -    visit_type_bool(v, name, &value, errp);
> > -}
> > -
> > -static void prop_set_bit64(Object *obj, Visitor *v, const char *name,
> > -                           void *opaque, Error **errp)
> > -{
> > -    Property *prop = opaque;
> > -    bool value;
> > -
> > -    if (!visit_type_bool(v, name, &value, errp)) {
> > -        return;
> > -    }
> > -    bit64_prop_set(obj, prop, value);
> > -}
> > -
> > -const PropertyInfo prop_info_bit64 = {
> > -    .name  = "bool",
> > -    .description = "on/off",
> > -    .get   = prop_get_bit64,
> > -    .set   = prop_set_bit64,
> > -    .set_default_value = set_default_value_bool,
> > -};
> > -
> > -/* --- bool --- */
> > -
> > -static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
> > -                     Error **errp)
> > -{
> > -    Property *prop = opaque;
> > -    bool *ptr = object_field_prop_ptr(obj, prop);
> > -
> > -    visit_type_bool(v, name, ptr, errp);
> > -}
> > -
> > -static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
> > -                     Error **errp)
> > -{
> > -    Property *prop = opaque;
> > -    bool *ptr = object_field_prop_ptr(obj, prop);
> > -
> > -    visit_type_bool(v, name, ptr, errp);
> > -}
> > -
> > -const PropertyInfo prop_info_bool = {
> > -    .name  = "bool",
> > -    .get   = get_bool,
> > -    .set   = set_bool,
> > -    .set_default_value = set_default_value_bool,
> > -};
> > -
> > -/* --- 8bit integer --- */
> > -
> > -static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
> > -                      Error **errp)
> > -{
> > -    Property *prop = opaque;
> > -    uint8_t *ptr = object_field_prop_ptr(obj, prop);
> > -
> > -    visit_type_uint8(v, name, ptr, errp);
> > -}
> > -
> > -static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
> > -                      Error **errp)
> > -{
> > -    Property *prop = opaque;
> > -    uint8_t *ptr = object_field_prop_ptr(obj, prop);
> > -
> > -    visit_type_uint8(v, name, ptr, errp);
> > -}
> > -
> > -void field_prop_set_default_value_int(ObjectProperty *op,
> > -                                      const Property *prop)
> > -{
> > -    object_property_set_default_int(op, prop->defval.i);
> > -}
> > -
> > -void field_prop_set_default_value_uint(ObjectProperty *op,
> > -                                       const Property *prop)
> > -{
> > -    object_property_set_default_uint(op, prop->defval.u);
> > -}
> > -
> > -const PropertyInfo prop_info_uint8 = {
> > -    .name  = "uint8",
> > -    .get   = get_uint8,
> > -    .set   = set_uint8,
> > -    .set_default_value = field_prop_set_default_value_uint,
> > -};
> > -
> > -/* --- 16bit integer --- */
> > -
> > -static void get_uint16(Object *obj, Visitor *v, const char *name,
> > -                       void *opaque, Error **errp)
> > -{
> > -    Property *prop = opaque;
> > -    uint16_t *ptr = object_field_prop_ptr(obj, prop);
> > -
> > -    visit_type_uint16(v, name, ptr, errp);
> > -}
> > -
> > -static void set_uint16(Object *obj, Visitor *v, const char *name,
> > -                       void *opaque, Error **errp)
> > -{
> > -    Property *prop = opaque;
> > -    uint16_t *ptr = object_field_prop_ptr(obj, prop);
> > -
> > -    visit_type_uint16(v, name, ptr, errp);
> > -}
> > -
> > -const PropertyInfo prop_info_uint16 = {
> > -    .name  = "uint16",
> > -    .get   = get_uint16,
> > -    .set   = set_uint16,
> > -    .set_default_value = field_prop_set_default_value_uint,
> > -};
> > -
> > -/* --- 32bit integer --- */
> > -
> > -static void get_uint32(Object *obj, Visitor *v, const char *name,
> > -                       void *opaque, Error **errp)
> > -{
> > -    Property *prop = opaque;
> > -    uint32_t *ptr = object_field_prop_ptr(obj, prop);
> > -
> > -    visit_type_uint32(v, name, ptr, errp);
> > -}
> > -
> > -static void set_uint32(Object *obj, Visitor *v, const char *name,
> > -                       void *opaque, Error **errp)
> > -{
> > -    Property *prop = opaque;
> > -    uint32_t *ptr = object_field_prop_ptr(obj, prop);
> > -
> > -    visit_type_uint32(v, name, ptr, errp);
> > -}
> > -
> > -void field_prop_get_int32(Object *obj, Visitor *v, const char *name,
> > -                          void *opaque, Error **errp)
> > -{
> > -    Property *prop = opaque;
> > -    int32_t *ptr = object_field_prop_ptr(obj, prop);
> > -
> > -    visit_type_int32(v, name, ptr, errp);
> > -}
> > -
> > -static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
> > -                      Error **errp)
> > -{
> > -    Property *prop = opaque;
> > -    int32_t *ptr = object_field_prop_ptr(obj, prop);
> > -
> > -    visit_type_int32(v, name, ptr, errp);
> > -}
> > -
> > -const PropertyInfo prop_info_uint32 = {
> > -    .name  = "uint32",
> > -    .get   = get_uint32,
> > -    .set   = set_uint32,
> > -    .set_default_value = field_prop_set_default_value_uint,
> > -};
> > -
> > -const PropertyInfo prop_info_int32 = {
> > -    .name  = "int32",
> > -    .get   = field_prop_get_int32,
> > -    .set   = set_int32,
> > -    .set_default_value = field_prop_set_default_value_int,
> > -};
> > -
> > -/* --- 64bit integer --- */
> > -
> > -static void get_uint64(Object *obj, Visitor *v, const char *name,
> > -                       void *opaque, Error **errp)
> > -{
> > -    Property *prop = opaque;
> > -    uint64_t *ptr = object_field_prop_ptr(obj, prop);
> > -
> > -    visit_type_uint64(v, name, ptr, errp);
> > -}
> > -
> > -static void set_uint64(Object *obj, Visitor *v, const char *name,
> > -                       void *opaque, Error **errp)
> > -{
> > -    Property *prop = opaque;
> > -    uint64_t *ptr = object_field_prop_ptr(obj, prop);
> > -
> > -    visit_type_uint64(v, name, ptr, errp);
> > -}
> > -
> > -static void get_int64(Object *obj, Visitor *v, const char *name,
> > -                      void *opaque, Error **errp)
> > -{
> > -    Property *prop = opaque;
> > -    int64_t *ptr = object_field_prop_ptr(obj, prop);
> > -
> > -    visit_type_int64(v, name, ptr, errp);
> > -}
> > -
> > -static void set_int64(Object *obj, Visitor *v, const char *name,
> > -                      void *opaque, Error **errp)
> > -{
> > -    Property *prop = opaque;
> > -    int64_t *ptr = object_field_prop_ptr(obj, prop);
> > -
> > -    visit_type_int64(v, name, ptr, errp);
> > -}
> > -
> > -const PropertyInfo prop_info_uint64 = {
> > -    .name  = "uint64",
> > -    .get   = get_uint64,
> > -    .set   = set_uint64,
> > -    .set_default_value = field_prop_set_default_value_uint,
> > -};
> > -
> > -const PropertyInfo prop_info_int64 = {
> > -    .name  = "int64",
> > -    .get   = get_int64,
> > -    .set   = set_int64,
> > -    .set_default_value = field_prop_set_default_value_int,
> > -};
> > -
> > -/* --- string --- */
> > -
> > -static void release_string(Object *obj, const char *name, void *opaque)
> > -{
> > -    Property *prop = opaque;
> > -    g_free(*(char **)object_field_prop_ptr(obj, prop));
> > -}
> > -
> > -static void get_string(Object *obj, Visitor *v, const char *name,
> > -                       void *opaque, Error **errp)
> > -{
> > -    Property *prop = opaque;
> > -    char **ptr = object_field_prop_ptr(obj, prop);
> > -
> > -    if (!*ptr) {
> > -        char *str = (char *)"";
> > -        visit_type_str(v, name, &str, errp);
> > -    } else {
> > -        visit_type_str(v, name, ptr, errp);
> > -    }
> > -}
> > -
> > -static void set_string(Object *obj, Visitor *v, const char *name,
> > -                       void *opaque, Error **errp)
> > -{
> > -    Property *prop = opaque;
> > -    char **ptr = object_field_prop_ptr(obj, prop);
> > -    char *str;
> > -
> > -    if (!visit_type_str(v, name, &str, errp)) {
> > -        return;
> > -    }
> > -    g_free(*ptr);
> > -    *ptr = str;
> > -}
> > -
> > -const PropertyInfo prop_info_string = {
> > -    .name  = "str",
> > -    .release = release_string,
> > -    .get   = get_string,
> > -    .set   = set_string,
> > -};
> > -
> > -/* --- on/off/auto --- */
> > -
> > -const PropertyInfo prop_info_on_off_auto = {
> > -    .name = "OnOffAuto",
> > -    .description = "on/off/auto",
> > -    .enum_table = &OnOffAuto_lookup,
> > -    .get = field_prop_get_enum,
> > -    .set = field_prop_set_enum,
> > -    .set_default_value = field_prop_set_default_value_enum,
> > -};
> > -
> > -/* --- 32bit unsigned int 'size' type --- */
> > -
> > -void field_prop_get_size32(Object *obj, Visitor *v, const char *name,
> > -                           void *opaque, Error **errp)
> > -{
> > -    Property *prop = opaque;
> > -    uint32_t *ptr = object_field_prop_ptr(obj, prop);
> > -    uint64_t value = *ptr;
> > -
> > -    visit_type_size(v, name, &value, errp);
> > -}
> > -
> > -static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
> > -                       Error **errp)
> > -{
> > -    Property *prop = opaque;
> > -    uint32_t *ptr = object_field_prop_ptr(obj, prop);
> > -    uint64_t value;
> > -
> > -    if (!visit_type_size(v, name, &value, errp)) {
> > -        return;
> > -    }
> > -
> > -    if (value > UINT32_MAX) {
> > -        error_setg(errp,
> > -                   "Property %s.%s doesn't take value %" PRIu64
> > -                   " (maximum: %u)",
> > -                   object_get_typename(obj), name, value, UINT32_MAX);
> > -        return;
> > -    }
> > -
> > -    *ptr = value;
> > -}
> > -
> > -const PropertyInfo prop_info_size32 = {
> > -    .name  = "size",
> > -    .get = field_prop_get_size32,
> > -    .set = set_size32,
> > -    .set_default_value = field_prop_set_default_value_uint,
> > -};
> > -
> > -/* --- support for array properties --- */
> > -
> > -static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
> > -                              void *opaque, Error **errp)
> > -{
> > -    /* Setter for the property which defines the length of a
> > -     * variable-sized property array. As well as actually setting the
> > -     * array-length field in the device struct, we have to create the
> > -     * array itself and dynamically add the corresponding properties.
> > -     */
> > -    Property *prop = opaque;
> > -    ObjectProperty *op = object_property_find_err(obj, name, &error_abort);
> > -    uint32_t *alenptr = object_field_prop_ptr(obj, prop);
> > -    void **arrayptr = (void *)obj + prop->arrayoffset;
> > -    void *eltptr;
> > -    const char *arrayname;
> > -    int i;
> > -
> > -    if (*alenptr) {
> > -        error_setg(errp, "array size property %s may not be set more than once",
> > -                   name);
> > -        return;
> > -    }
> > -    if (!visit_type_uint32(v, name, alenptr, errp)) {
> > -        return;
> > -    }
> > -    if (!*alenptr) {
> > -        return;
> > -    }
> > -
> > -    /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix;
> > -     * strip it off so we can get the name of the array itself.
> > -     */
> > -    assert(strncmp(name, PROP_ARRAY_LEN_PREFIX,
> > -                   strlen(PROP_ARRAY_LEN_PREFIX)) == 0);
> > -    arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX);
> > -
> > -    /* Note that it is the responsibility of the individual device's deinit
> > -     * to free the array proper.
> > -     */
> > -    *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize);
> > -    for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) {
> > -        g_autofree char *propname = g_strdup_printf("%s[%d]", arrayname, i);
> > -        Property *arrayprop = g_new0(Property, 1);
> > -        arrayprop->info = prop->arrayinfo;
> > -        /* This ugly piece of pointer arithmetic sets up the offset so
> > -         * that when the underlying get/set hooks call qdev_get_prop_ptr
> > -         * they get the right answer despite the array element not actually
> > -         * being inside the device struct.
> > -         */
> > -        arrayprop->offset = eltptr - (void *)obj;
> > -        assert(object_field_prop_ptr(obj, arrayprop) == eltptr);
> > -        object_property_add_field(obj, propname, arrayprop, op->allow_set);
> > -    }
> > -}
> > -
> > -const PropertyInfo prop_info_arraylen = {
> > -    .name = "uint32",
> > -    .get = get_uint32,
> > -    .set = set_prop_arraylen,
> > -    .set_default_value = field_prop_set_default_value_uint,
> > -};
> > -
> >   /* --- public helpers --- */
> >   static Property *qdev_prop_walk(Property *props, const char *name)
> > @@ -712,53 +222,6 @@ void qdev_prop_set_globals(DeviceState *dev)
> >                                 dev->hotplugged ? NULL : &error_fatal);
> >   }
> > -/* --- 64bit unsigned int 'size' type --- */
> > -
> > -static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
> > -                     Error **errp)
> > -{
> > -    Property *prop = opaque;
> > -    uint64_t *ptr = object_field_prop_ptr(obj, prop);
> > -
> > -    visit_type_size(v, name, ptr, errp);
> > -}
> > -
> > -static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
> > -                     Error **errp)
> > -{
> > -    Property *prop = opaque;
> > -    uint64_t *ptr = object_field_prop_ptr(obj, prop);
> > -
> > -    visit_type_size(v, name, ptr, errp);
> > -}
> > -
> > -const PropertyInfo prop_info_size = {
> > -    .name  = "size",
> > -    .get = get_size,
> > -    .set = set_size,
> > -    .set_default_value = field_prop_set_default_value_uint,
> > -};
> > -
> > -/* --- object link property --- */
> > -
> > -static ObjectProperty *create_link_property(ObjectClass *oc, const char *name,
> > -                                            Property *prop)
> > -{
> > -    /*
> > -     * NOTE: object_property_allow_set_link is unconditional, but
> > -     *       ObjectProperty.allow_set may be set for the property too.
> > -     */
> > -    return object_class_property_add_link(oc, name, prop->link_type,
> > -                                          prop->offset,
> > -                                          object_property_allow_set_link,
> > -                                          OBJ_PROP_LINK_STRONG);
> > -}
> > -
> > -const PropertyInfo prop_info_link = {
> > -    .name = "link",
> > -    .create = create_link_property,
> > -};
> > -
> >   void qdev_property_add_static(DeviceState *dev, Property *prop)
> >   {
> >       object_property_add_field(OBJECT(dev), prop->qdev_prop_name, prop,
> > diff --git a/qom/property-types.c b/qom/property-types.c
> > new file mode 100644
> > index 0000000000..f566c05ec2
> > --- /dev/null
> > +++ b/qom/property-types.c
> > @@ -0,0 +1,545 @@
> > +#include "qemu/osdep.h"
> > +#include "qom/field-property.h"
> > +#include "qom/property-types.h"
> > +#include "qom/field-property-internal.h"
> > +#include "qapi/qapi-types-common.h"
> > +#include "qapi/visitor.h"
> > +#include "qapi/error.h"
> > +#include "qemu/uuid.h"
> > +
> > +void field_prop_get_enum(Object *obj, Visitor *v, const char *name,
> > +                         void *opaque, Error **errp)
> > +{
> > +    Property *prop = opaque;
> > +    int *ptr = object_field_prop_ptr(obj, prop);
> > +
> > +    visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
> > +}
> > +
> > +void field_prop_set_enum(Object *obj, Visitor *v, const char *name,
> > +                         void *opaque, Error **errp)
> > +{
> > +    Property *prop = opaque;
> > +    int *ptr = object_field_prop_ptr(obj, prop);
> > +
> > +    visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
> > +}
> > +
> > +void field_prop_set_default_value_enum(ObjectProperty *op,
> > +                                       const Property *prop)
> > +{
> > +    object_property_set_default_str(op,
> > +        qapi_enum_lookup(prop->info->enum_table, prop->defval.i));
> > +}
> > +
> > +const PropertyInfo prop_info_enum = {
> > +    .name  = "enum",
> > +    .get   = field_prop_get_enum,
> > +    .set   = field_prop_set_enum,
> > +    .set_default_value = field_prop_set_default_value_enum,
> > +};
> > +
> > +/* Bit */
> > +
> > +static uint32_t qdev_get_prop_mask(Property *prop)
> > +{
> > +    assert(prop->info == &prop_info_bit);
> > +    return 0x1 << prop->bitnr;
> > +}
> > +
> > +static void bit_prop_set(Object *obj, Property *props, bool val)
> > +{
> > +    uint32_t *p = object_field_prop_ptr(obj, props);
> > +    uint32_t mask = qdev_get_prop_mask(props);
> > +    if (val) {
> > +        *p |= mask;
> > +    } else {
> > +        *p &= ~mask;
> > +    }
> > +}
> > +
> > +static void prop_get_bit(Object *obj, Visitor *v, const char *name,
> > +                         void *opaque, Error **errp)
> > +{
> > +    Property *prop = opaque;
> > +    uint32_t *p = object_field_prop_ptr(obj, prop);
> > +    bool value = (*p & qdev_get_prop_mask(prop)) != 0;
> > +
> > +    visit_type_bool(v, name, &value, errp);
> > +}
> > +
> > +static void prop_set_bit(Object *obj, Visitor *v, const char *name,
> > +                         void *opaque, Error **errp)
> > +{
> > +    Property *prop = opaque;
> > +    bool value;
> > +
> > +    if (!visit_type_bool(v, name, &value, errp)) {
> > +        return;
> > +    }
> > +    bit_prop_set(obj, prop, value);
> > +}
> > +
> > +static void set_default_value_bool(ObjectProperty *op, const Property *prop)
> > +{
> > +    object_property_set_default_bool(op, prop->defval.u);
> > +}
> > +
> > +const PropertyInfo prop_info_bit = {
> > +    .name  = "bool",
> > +    .description = "on/off",
> > +    .get   = prop_get_bit,
> > +    .set   = prop_set_bit,
> > +    .set_default_value = set_default_value_bool,
> > +};
> > +
> > +/* Bit64 */
> > +
> > +static uint64_t qdev_get_prop_mask64(Property *prop)
> > +{
> > +    assert(prop->info == &prop_info_bit64);
> > +    return 0x1ull << prop->bitnr;
> > +}
> > +
> > +static void bit64_prop_set(Object *obj, Property *props, bool val)
> > +{
> > +    uint64_t *p = object_field_prop_ptr(obj, props);
> > +    uint64_t mask = qdev_get_prop_mask64(props);
> > +    if (val) {
> > +        *p |= mask;
> > +    } else {
> > +        *p &= ~mask;
> > +    }
> > +}
> > +
> > +static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
> > +                           void *opaque, Error **errp)
> > +{
> > +    Property *prop = opaque;
> > +    uint64_t *p = object_field_prop_ptr(obj, prop);
> > +    bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
> > +
> > +    visit_type_bool(v, name, &value, errp);
> > +}
> > +
> > +static void prop_set_bit64(Object *obj, Visitor *v, const char *name,
> > +                           void *opaque, Error **errp)
> > +{
> > +    Property *prop = opaque;
> > +    bool value;
> > +
> > +    if (!visit_type_bool(v, name, &value, errp)) {
> > +        return;
> > +    }
> > +    bit64_prop_set(obj, prop, value);
> > +}
> > +
> > +const PropertyInfo prop_info_bit64 = {
> > +    .name  = "bool",
> > +    .description = "on/off",
> > +    .get   = prop_get_bit64,
> > +    .set   = prop_set_bit64,
> > +    .set_default_value = set_default_value_bool,
> > +};
> > +
> > +/* --- bool --- */
> > +
> > +static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
> > +                     Error **errp)
> > +{
> > +    Property *prop = opaque;
> > +    bool *ptr = object_field_prop_ptr(obj, prop);
> > +
> > +    visit_type_bool(v, name, ptr, errp);
> > +}
> > +
> > +static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
> > +                     Error **errp)
> > +{
> > +    Property *prop = opaque;
> > +    bool *ptr = object_field_prop_ptr(obj, prop);
> > +
> > +    visit_type_bool(v, name, ptr, errp);
> > +}
> > +
> > +const PropertyInfo prop_info_bool = {
> > +    .name  = "bool",
> > +    .get   = get_bool,
> > +    .set   = set_bool,
> > +    .set_default_value = set_default_value_bool,
> > +};
> > +
> > +/* --- 8bit integer --- */
> > +
> > +static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
> > +                      Error **errp)
> > +{
> > +    Property *prop = opaque;
> > +    uint8_t *ptr = object_field_prop_ptr(obj, prop);
> > +
> > +    visit_type_uint8(v, name, ptr, errp);
> > +}
> > +
> > +static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
> > +                      Error **errp)
> > +{
> > +    Property *prop = opaque;
> > +    uint8_t *ptr = object_field_prop_ptr(obj, prop);
> > +
> > +    visit_type_uint8(v, name, ptr, errp);
> > +}
> > +
> > +void field_prop_set_default_value_int(ObjectProperty *op,
> > +                                      const Property *prop)
> > +{
> > +    object_property_set_default_int(op, prop->defval.i);
> > +}
> > +
> > +void field_prop_set_default_value_uint(ObjectProperty *op,
> > +                                       const Property *prop)
> > +{
> > +    object_property_set_default_uint(op, prop->defval.u);
> > +}
> > +
> > +const PropertyInfo prop_info_uint8 = {
> > +    .name  = "uint8",
> > +    .get   = get_uint8,
> > +    .set   = set_uint8,
> > +    .set_default_value = field_prop_set_default_value_uint,
> > +};
> > +
> > +/* --- 16bit integer --- */
> > +
> > +static void get_uint16(Object *obj, Visitor *v, const char *name,
> > +                       void *opaque, Error **errp)
> > +{
> > +    Property *prop = opaque;
> > +    uint16_t *ptr = object_field_prop_ptr(obj, prop);
> > +
> > +    visit_type_uint16(v, name, ptr, errp);
> > +}
> > +
> > +static void set_uint16(Object *obj, Visitor *v, const char *name,
> > +                       void *opaque, Error **errp)
> > +{
> > +    Property *prop = opaque;
> > +    uint16_t *ptr = object_field_prop_ptr(obj, prop);
> > +
> > +    visit_type_uint16(v, name, ptr, errp);
> > +}
> > +
> > +const PropertyInfo prop_info_uint16 = {
> > +    .name  = "uint16",
> > +    .get   = get_uint16,
> > +    .set   = set_uint16,
> > +    .set_default_value = field_prop_set_default_value_uint,
> > +};
> > +
> > +/* --- 32bit integer --- */
> > +
> > +static void get_uint32(Object *obj, Visitor *v, const char *name,
> > +                       void *opaque, Error **errp)
> > +{
> > +    Property *prop = opaque;
> > +    uint32_t *ptr = object_field_prop_ptr(obj, prop);
> > +
> > +    visit_type_uint32(v, name, ptr, errp);
> > +}
> > +
> > +static void set_uint32(Object *obj, Visitor *v, const char *name,
> > +                       void *opaque, Error **errp)
> > +{
> > +    Property *prop = opaque;
> > +    uint32_t *ptr = object_field_prop_ptr(obj, prop);
> > +
> > +    visit_type_uint32(v, name, ptr, errp);
> > +}
> > +
> > +void field_prop_get_int32(Object *obj, Visitor *v, const char *name,
> > +                          void *opaque, Error **errp)
> > +{
> > +    Property *prop = opaque;
> > +    int32_t *ptr = object_field_prop_ptr(obj, prop);
> > +
> > +    visit_type_int32(v, name, ptr, errp);
> > +}
> > +
> > +static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
> > +                      Error **errp)
> > +{
> > +    Property *prop = opaque;
> > +    int32_t *ptr = object_field_prop_ptr(obj, prop);
> > +
> > +    visit_type_int32(v, name, ptr, errp);
> > +}
> > +
> > +const PropertyInfo prop_info_uint32 = {
> > +    .name  = "uint32",
> > +    .get   = get_uint32,
> > +    .set   = set_uint32,
> > +    .set_default_value = field_prop_set_default_value_uint,
> > +};
> > +
> > +const PropertyInfo prop_info_int32 = {
> > +    .name  = "int32",
> > +    .get   = field_prop_get_int32,
> > +    .set   = set_int32,
> > +    .set_default_value = field_prop_set_default_value_int,
> > +};
> > +
> > +/* --- 64bit integer --- */
> > +
> > +static void get_uint64(Object *obj, Visitor *v, const char *name,
> > +                       void *opaque, Error **errp)
> > +{
> > +    Property *prop = opaque;
> > +    uint64_t *ptr = object_field_prop_ptr(obj, prop);
> > +
> > +    visit_type_uint64(v, name, ptr, errp);
> > +}
> > +
> > +static void set_uint64(Object *obj, Visitor *v, const char *name,
> > +                       void *opaque, Error **errp)
> > +{
> > +    Property *prop = opaque;
> > +    uint64_t *ptr = object_field_prop_ptr(obj, prop);
> > +
> > +    visit_type_uint64(v, name, ptr, errp);
> > +}
> > +
> > +static void get_int64(Object *obj, Visitor *v, const char *name,
> > +                      void *opaque, Error **errp)
> > +{
> > +    Property *prop = opaque;
> > +    int64_t *ptr = object_field_prop_ptr(obj, prop);
> > +
> > +    visit_type_int64(v, name, ptr, errp);
> > +}
> > +
> > +static void set_int64(Object *obj, Visitor *v, const char *name,
> > +                      void *opaque, Error **errp)
> > +{
> > +    Property *prop = opaque;
> > +    int64_t *ptr = object_field_prop_ptr(obj, prop);
> > +
> > +    visit_type_int64(v, name, ptr, errp);
> > +}
> > +
> > +const PropertyInfo prop_info_uint64 = {
> > +    .name  = "uint64",
> > +    .get   = get_uint64,
> > +    .set   = set_uint64,
> > +    .set_default_value = field_prop_set_default_value_uint,
> > +};
> > +
> > +const PropertyInfo prop_info_int64 = {
> > +    .name  = "int64",
> > +    .get   = get_int64,
> > +    .set   = set_int64,
> > +    .set_default_value = field_prop_set_default_value_int,
> > +};
> > +
> > +/* --- string --- */
> > +
> > +static void release_string(Object *obj, const char *name, void *opaque)
> > +{
> > +    Property *prop = opaque;
> > +    g_free(*(char **)object_field_prop_ptr(obj, prop));
> > +}
> > +
> > +static void get_string(Object *obj, Visitor *v, const char *name,
> > +                       void *opaque, Error **errp)
> > +{
> > +    Property *prop = opaque;
> > +    char **ptr = object_field_prop_ptr(obj, prop);
> > +
> > +    if (!*ptr) {
> > +        char *str = (char *)"";
> > +        visit_type_str(v, name, &str, errp);
> > +    } else {
> > +        visit_type_str(v, name, ptr, errp);
> > +    }
> > +}
> > +
> > +static void set_string(Object *obj, Visitor *v, const char *name,
> > +                       void *opaque, Error **errp)
> > +{
> > +    Property *prop = opaque;
> > +    char **ptr = object_field_prop_ptr(obj, prop);
> > +    char *str;
> > +
> > +    if (!visit_type_str(v, name, &str, errp)) {
> > +        return;
> > +    }
> > +    g_free(*ptr);
> > +    *ptr = str;
> > +}
> > +
> > +const PropertyInfo prop_info_string = {
> > +    .name  = "str",
> > +    .release = release_string,
> > +    .get   = get_string,
> > +    .set   = set_string,
> > +};
> > +
> > +/* --- on/off/auto --- */
> > +
> > +const PropertyInfo prop_info_on_off_auto = {
> > +    .name = "OnOffAuto",
> > +    .description = "on/off/auto",
> > +    .enum_table = &OnOffAuto_lookup,
> > +    .get = field_prop_get_enum,
> > +    .set = field_prop_set_enum,
> > +    .set_default_value = field_prop_set_default_value_enum,
> > +};
> > +
> > +/* --- 32bit unsigned int 'size' type --- */
> > +
> > +void field_prop_get_size32(Object *obj, Visitor *v, const char *name,
> > +                           void *opaque, Error **errp)
> > +{
> > +    Property *prop = opaque;
> > +    uint32_t *ptr = object_field_prop_ptr(obj, prop);
> > +    uint64_t value = *ptr;
> > +
> > +    visit_type_size(v, name, &value, errp);
> > +}
> > +
> > +static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
> > +                       Error **errp)
> > +{
> > +    Property *prop = opaque;
> > +    uint32_t *ptr = object_field_prop_ptr(obj, prop);
> > +    uint64_t value;
> > +
> > +    if (!visit_type_size(v, name, &value, errp)) {
> > +        return;
> > +    }
> > +
> > +    if (value > UINT32_MAX) {
> > +        error_setg(errp,
> > +                   "Property %s.%s doesn't take value %" PRIu64
> > +                   " (maximum: %u)",
> > +                   object_get_typename(obj), name, value, UINT32_MAX);
> > +        return;
> > +    }
> > +
> > +    *ptr = value;
> > +}
> > +
> > +const PropertyInfo prop_info_size32 = {
> > +    .name  = "size",
> > +    .get = field_prop_get_size32,
> > +    .set = set_size32,
> > +    .set_default_value = field_prop_set_default_value_uint,
> > +};
> > +
> > +/* --- support for array properties --- */
> > +
> > +static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
> > +                              void *opaque, Error **errp)
> > +{
> > +    /* Setter for the property which defines the length of a
> > +     * variable-sized property array. As well as actually setting the
> > +     * array-length field in the device struct, we have to create the
> > +     * array itself and dynamically add the corresponding properties.
> > +     */
> > +    Property *prop = opaque;
> > +    ObjectProperty *op = object_property_find_err(obj, name, &error_abort);
> > +    uint32_t *alenptr = object_field_prop_ptr(obj, prop);
> > +    void **arrayptr = (void *)obj + prop->arrayoffset;
> > +    void *eltptr;
> > +    const char *arrayname;
> > +    int i;
> > +
> > +    if (*alenptr) {
> > +        error_setg(errp, "array size property %s may not be set more than once",
> > +                   name);
> > +        return;
> > +    }
> > +    if (!visit_type_uint32(v, name, alenptr, errp)) {
> > +        return;
> > +    }
> > +    if (!*alenptr) {
> > +        return;
> > +    }
> > +
> > +    /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix;
> > +     * strip it off so we can get the name of the array itself.
> > +     */
> > +    assert(strncmp(name, PROP_ARRAY_LEN_PREFIX,
> > +                   strlen(PROP_ARRAY_LEN_PREFIX)) == 0);
> > +    arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX);
> > +
> > +    /* Note that it is the responsibility of the individual device's deinit
> > +     * to free the array proper.
> > +     */
> > +    *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize);
> > +    for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) {
> > +        g_autofree char *propname = g_strdup_printf("%s[%d]", arrayname, i);
> > +        Property *arrayprop = g_new0(Property, 1);
> > +        arrayprop->info = prop->arrayinfo;
> > +        /* This ugly piece of pointer arithmetic sets up the offset so
> > +         * that when the underlying get/set hooks call qdev_get_prop_ptr
> > +         * they get the right answer despite the array element not actually
> > +         * being inside the device struct.
> > +         */
> > +        arrayprop->offset = eltptr - (void *)obj;
> > +        assert(object_field_prop_ptr(obj, arrayprop) == eltptr);
> > +        object_property_add_field(obj, propname, arrayprop, op->allow_set);
> > +    }
> > +}
> > +
> > +const PropertyInfo prop_info_arraylen = {
> > +    .name = "uint32",
> > +    .get = get_uint32,
> > +    .set = set_prop_arraylen,
> > +    .set_default_value = field_prop_set_default_value_uint,
> > +};
> > +
> > +/* --- 64bit unsigned int 'size' type --- */
> > +
> > +static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
> > +                     Error **errp)
> > +{
> > +    Property *prop = opaque;
> > +    uint64_t *ptr = object_field_prop_ptr(obj, prop);
> > +
> > +    visit_type_size(v, name, ptr, errp);
> > +}
> > +
> > +static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
> > +                     Error **errp)
> > +{
> > +    Property *prop = opaque;
> > +    uint64_t *ptr = object_field_prop_ptr(obj, prop);
> > +
> > +    visit_type_size(v, name, ptr, errp);
> > +}
> > +
> > +const PropertyInfo prop_info_size = {
> > +    .name  = "size",
> > +    .get = get_size,
> > +    .set = set_size,
> > +    .set_default_value = field_prop_set_default_value_uint,
> > +};
> > +
> > +/* --- object link property --- */
> > +
> > +static ObjectProperty *create_link_property(ObjectClass *oc, const char *name,
> > +                                            Property *prop)
> > +{
> > +    /*
> > +     * NOTE: object_property_allow_set_link is unconditional, but
> > +     *       ObjectProperty.allow_set may be set for the property too.
> > +     */
> > +    return object_class_property_add_link(oc, name, prop->link_type,
> > +                                          prop->offset,
> > +                                          object_property_allow_set_link,
> > +                                          OBJ_PROP_LINK_STRONG);
> > +}
> > +
> > +const PropertyInfo prop_info_link = {
> > +    .name = "link",
> > +    .create = create_link_property,
> > +};
> > diff --git a/qom/meson.build b/qom/meson.build
> > index e83794454d..7fdfd6fe7b 100644
> > --- a/qom/meson.build
> > +++ b/qom/meson.build
> > @@ -5,6 +5,7 @@ qom_ss.add(files(
> >     'object_interfaces.c',
> >     'qom-qobject.c',
> >     'field-property.c',
> > +  'property-types.c',
> >   ))
> >   qmp_ss.add(files('qom-qmp-cmds.c'))
> > 
> 

-- 
Eduardo



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 41/44] qdev: Move base property types to qom/property-types.c
  2020-11-04 20:50     ` Eduardo Habkost
@ 2020-11-05  9:36       ` Paolo Bonzini
  0 siblings, 0 replies; 77+ messages in thread
From: Paolo Bonzini @ 2020-11-05  9:36 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: Daniel P. Berrange, John Snow, Philippe Mathieu-Daudé,
	Markus Armbruster, qemu-devel, Marc-André Lureau,
	Igor Mammedov, Stefan Berger

On 04/11/20 21:50, Eduardo Habkost wrote:
>> I would merge property-types.h and field-property.h in a single file.
> I like keeping them separate, to force us to define the API used
> to create new property types clearly.
> 
> What if I create a qom/qom.h header that includes object.h +
> field-properties.h + property-types.h to make this easier to use?
> 

Works for me!

Paolo



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 36/44] qdev: Rename qdev_get_prop_ptr() to object_field_prop_ptr()
  2020-11-04 16:00   ` Eduardo Habkost
@ 2020-11-05 18:49     ` Stefan Berger
  -1 siblings, 0 replies; 77+ messages in thread
From: Stefan Berger @ 2020-11-05 18:49 UTC (permalink / raw)
  To: Eduardo Habkost, qemu-devel
  Cc: Matthew Rosato, David Hildenbrand, Stefano Stabellini, xen-devel,
	qemu-block, Stefan Berger, Paul Durrant, Markus Armbruster,
	Halil Pasic, Christian Borntraeger, Anthony Perard,
	Marc-André Lureau, Philippe Mathieu-Daudé,
	Thomas Huth, Alex Williamson, Paolo Bonzini, John Snow,
	Richard Henderson, Kevin Wolf, Daniel P. Berrange, Cornelia Huck,
	qemu-s390x, Max Reitz, Igor Mammedov

On 11/4/20 11:00 AM, Eduardo Habkost wrote:
> The function will be moved to common QOM code, as it is not
> specific to TYPE_DEVICE anymore.
>
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>

Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>


> ---
> Changes v1 -> v2:
> * Rename to object_field_prop_ptr() instead of object_static_prop_ptr()
> ---
> Cc: Stefan Berger <stefanb@linux.vnet.ibm.com>
> Cc: Stefano Stabellini <sstabellini@kernel.org>
> Cc: Anthony Perard <anthony.perard@citrix.com>
> Cc: Paul Durrant <paul@xen.org>
> Cc: Kevin Wolf <kwolf@redhat.com>
> Cc: Max Reitz <mreitz@redhat.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Cc: "Daniel P. Berrangé" <berrange@redhat.com>
> Cc: Eduardo Habkost <ehabkost@redhat.com>
> Cc: Cornelia Huck <cohuck@redhat.com>
> Cc: Halil Pasic <pasic@linux.ibm.com>
> Cc: Christian Borntraeger <borntraeger@de.ibm.com>
> Cc: Richard Henderson <rth@twiddle.net>
> Cc: David Hildenbrand <david@redhat.com>
> Cc: Thomas Huth <thuth@redhat.com>
> Cc: Matthew Rosato <mjrosato@linux.ibm.com>
> Cc: Alex Williamson <alex.williamson@redhat.com>
> Cc: qemu-devel@nongnu.org
> Cc: xen-devel@lists.xenproject.org
> Cc: qemu-block@nongnu.org
> Cc: qemu-s390x@nongnu.org
> ---
>   include/hw/qdev-properties.h     |  2 +-
>   backends/tpm/tpm_util.c          |  6 ++--
>   hw/block/xen-block.c             |  4 +--
>   hw/core/qdev-properties-system.c | 50 +++++++++++++-------------
>   hw/core/qdev-properties.c        | 60 ++++++++++++++++----------------
>   hw/s390x/css.c                   |  4 +--
>   hw/s390x/s390-pci-bus.c          |  4 +--
>   hw/vfio/pci-quirks.c             |  4 +--
>   8 files changed, 67 insertions(+), 67 deletions(-)
>
> diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
> index 7f8d5fc206..2bec65c8e5 100644
> --- a/include/hw/qdev-properties.h
> +++ b/include/hw/qdev-properties.h
> @@ -223,7 +223,7 @@ void qdev_prop_set_macaddr(DeviceState *dev, const char *name,
>                              const uint8_t *value);
>   void qdev_prop_set_enum(DeviceState *dev, const char *name, int value);
>   
> -void *qdev_get_prop_ptr(Object *obj, Property *prop);
> +void *object_field_prop_ptr(Object *obj, Property *prop);
>   
>   void qdev_prop_register_global(GlobalProperty *prop);
>   const GlobalProperty *qdev_find_global_prop(Object *obj,
> diff --git a/backends/tpm/tpm_util.c b/backends/tpm/tpm_util.c
> index 0b07cf55ea..bb1ab34a75 100644
> --- a/backends/tpm/tpm_util.c
> +++ b/backends/tpm/tpm_util.c
> @@ -35,7 +35,7 @@
>   static void get_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
>                       Error **errp)
>   {
> -    TPMBackend **be = qdev_get_prop_ptr(obj, opaque);
> +    TPMBackend **be = object_field_prop_ptr(obj, opaque);
>       char *p;
>   
>       p = g_strdup(*be ? (*be)->id : "");
> @@ -47,7 +47,7 @@ static void set_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
>                       Error **errp)
>   {
>       Property *prop = opaque;
> -    TPMBackend *s, **be = qdev_get_prop_ptr(obj, prop);
> +    TPMBackend *s, **be = object_field_prop_ptr(obj, prop);
>       char *str;
>   
>       if (!visit_type_str(v, name, &str, errp)) {
> @@ -67,7 +67,7 @@ static void set_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
>   static void release_tpm(Object *obj, const char *name, void *opaque)
>   {
>       Property *prop = opaque;
> -    TPMBackend **be = qdev_get_prop_ptr(obj, prop);
> +    TPMBackend **be = object_field_prop_ptr(obj, prop);
>   
>       if (*be) {
>           tpm_backend_reset(*be);
> diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
> index bd1aef63a7..718d886e5c 100644
> --- a/hw/block/xen-block.c
> +++ b/hw/block/xen-block.c
> @@ -336,7 +336,7 @@ static void xen_block_get_vdev(Object *obj, Visitor *v, const char *name,
>                                  void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    XenBlockVdev *vdev = qdev_get_prop_ptr(obj, prop);
> +    XenBlockVdev *vdev = object_field_prop_ptr(obj, prop);
>       char *str;
>   
>       switch (vdev->type) {
> @@ -396,7 +396,7 @@ static void xen_block_set_vdev(Object *obj, Visitor *v, const char *name,
>                                  void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    XenBlockVdev *vdev = qdev_get_prop_ptr(obj, prop);
> +    XenBlockVdev *vdev = object_field_prop_ptr(obj, prop);
>       char *str, *p;
>       const char *end;
>   
> diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
> index 96a0bc5109..8781b856d3 100644
> --- a/hw/core/qdev-properties-system.c
> +++ b/hw/core/qdev-properties-system.c
> @@ -62,7 +62,7 @@ static void get_drive(Object *obj, Visitor *v, const char *name, void *opaque,
>                         Error **errp)
>   {
>       Property *prop = opaque;
> -    void **ptr = qdev_get_prop_ptr(obj, prop);
> +    void **ptr = object_field_prop_ptr(obj, prop);
>       const char *value;
>       char *p;
>   
> @@ -88,7 +88,7 @@ static void set_drive_helper(Object *obj, Visitor *v, const char *name,
>   {
>       DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
> -    void **ptr = qdev_get_prop_ptr(obj, prop);
> +    void **ptr = object_field_prop_ptr(obj, prop);
>       char *str;
>       BlockBackend *blk;
>       bool blk_created = false;
> @@ -181,7 +181,7 @@ static void release_drive(Object *obj, const char *name, void *opaque)
>   {
>       DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
> -    BlockBackend **ptr = qdev_get_prop_ptr(obj, prop);
> +    BlockBackend **ptr = object_field_prop_ptr(obj, prop);
>   
>       if (*ptr) {
>           AioContext *ctx = blk_get_aio_context(*ptr);
> @@ -214,7 +214,7 @@ const PropertyInfo qdev_prop_drive_iothread = {
>   static void get_chr(Object *obj, Visitor *v, const char *name, void *opaque,
>                       Error **errp)
>   {
> -    CharBackend *be = qdev_get_prop_ptr(obj, opaque);
> +    CharBackend *be = object_field_prop_ptr(obj, opaque);
>       char *p;
>   
>       p = g_strdup(be->chr && be->chr->label ? be->chr->label : "");
> @@ -226,7 +226,7 @@ static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
>                       Error **errp)
>   {
>       Property *prop = opaque;
> -    CharBackend *be = qdev_get_prop_ptr(obj, prop);
> +    CharBackend *be = object_field_prop_ptr(obj, prop);
>       Chardev *s;
>       char *str;
>   
> @@ -262,7 +262,7 @@ static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
>   static void release_chr(Object *obj, const char *name, void *opaque)
>   {
>       Property *prop = opaque;
> -    CharBackend *be = qdev_get_prop_ptr(obj, prop);
> +    CharBackend *be = object_field_prop_ptr(obj, prop);
>   
>       qemu_chr_fe_deinit(be, false);
>   }
> @@ -286,7 +286,7 @@ static void get_mac(Object *obj, Visitor *v, const char *name, void *opaque,
>                       Error **errp)
>   {
>       Property *prop = opaque;
> -    MACAddr *mac = qdev_get_prop_ptr(obj, prop);
> +    MACAddr *mac = object_field_prop_ptr(obj, prop);
>       char buffer[2 * 6 + 5 + 1];
>       char *p = buffer;
>   
> @@ -301,7 +301,7 @@ static void set_mac(Object *obj, Visitor *v, const char *name, void *opaque,
>                       Error **errp)
>   {
>       Property *prop = opaque;
> -    MACAddr *mac = qdev_get_prop_ptr(obj, prop);
> +    MACAddr *mac = object_field_prop_ptr(obj, prop);
>       int i, pos;
>       char *str;
>       const char *p;
> @@ -363,7 +363,7 @@ static void get_netdev(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    NICPeers *peers_ptr = qdev_get_prop_ptr(obj, prop);
> +    NICPeers *peers_ptr = object_field_prop_ptr(obj, prop);
>       char *p = g_strdup(peers_ptr->ncs[0] ? peers_ptr->ncs[0]->name : "");
>   
>       visit_type_str(v, name, &p, errp);
> @@ -374,7 +374,7 @@ static void set_netdev(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    NICPeers *peers_ptr = qdev_get_prop_ptr(obj, prop);
> +    NICPeers *peers_ptr = object_field_prop_ptr(obj, prop);
>       NetClientState **ncs = peers_ptr->ncs;
>       NetClientState *peers[MAX_QUEUE_NUM];
>       int queues, err = 0, i = 0;
> @@ -436,7 +436,7 @@ static void get_audiodev(Object *obj, Visitor *v, const char* name,
>                            void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    QEMUSoundCard *card = qdev_get_prop_ptr(obj, prop);
> +    QEMUSoundCard *card = object_field_prop_ptr(obj, prop);
>       char *p = g_strdup(audio_get_id(card));
>   
>       visit_type_str(v, name, &p, errp);
> @@ -447,7 +447,7 @@ static void set_audiodev(Object *obj, Visitor *v, const char* name,
>                            void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    QEMUSoundCard *card = qdev_get_prop_ptr(obj, prop);
> +    QEMUSoundCard *card = object_field_prop_ptr(obj, prop);
>       AudioState *state;
>       int err = 0;
>       char *str;
> @@ -549,7 +549,7 @@ static void set_blocksize(Object *obj, Visitor *v, const char *name,
>   {
>       DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
> -    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint32_t *ptr = object_field_prop_ptr(obj, prop);
>       uint64_t value;
>       Error *local_err = NULL;
>   
> @@ -637,7 +637,7 @@ static void get_reserved_region(Object *obj, Visitor *v, const char *name,
>                                   void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    ReservedRegion *rr = qdev_get_prop_ptr(obj, prop);
> +    ReservedRegion *rr = object_field_prop_ptr(obj, prop);
>       char buffer[64];
>       char *p = buffer;
>       int rc;
> @@ -653,7 +653,7 @@ static void set_reserved_region(Object *obj, Visitor *v, const char *name,
>                                   void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    ReservedRegion *rr = qdev_get_prop_ptr(obj, prop);
> +    ReservedRegion *rr = object_field_prop_ptr(obj, prop);
>       Error *local_err = NULL;
>       const char *endptr;
>       char *str;
> @@ -715,7 +715,7 @@ static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
>                             void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    int32_t value, *ptr = qdev_get_prop_ptr(obj, prop);
> +    int32_t value, *ptr = object_field_prop_ptr(obj, prop);
>       unsigned int slot, fn, n;
>       char *str;
>   
> @@ -753,7 +753,7 @@ invalid:
>   static int print_pci_devfn(Object *obj, Property *prop, char *dest,
>                              size_t len)
>   {
> -    int32_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    int32_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       if (*ptr == -1) {
>           return snprintf(dest, len, "<unset>");
> @@ -777,7 +777,7 @@ static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
>                                    void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(obj, prop);
> +    PCIHostDeviceAddress *addr = object_field_prop_ptr(obj, prop);
>       char buffer[] = "ffff:ff:ff.f";
>       char *p = buffer;
>       int rc = 0;
> @@ -803,7 +803,7 @@ static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
>                                    void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(obj, prop);
> +    PCIHostDeviceAddress *addr = object_field_prop_ptr(obj, prop);
>       char *str, *p;
>       const char *e;
>       unsigned long val;
> @@ -892,7 +892,7 @@ static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
>                                      void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    PCIExpLinkSpeed *p = qdev_get_prop_ptr(obj, prop);
> +    PCIExpLinkSpeed *p = object_field_prop_ptr(obj, prop);
>       int speed;
>   
>       switch (*p) {
> @@ -920,7 +920,7 @@ static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
>                                      void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    PCIExpLinkSpeed *p = qdev_get_prop_ptr(obj, prop);
> +    PCIExpLinkSpeed *p = object_field_prop_ptr(obj, prop);
>       int speed;
>   
>       if (!visit_type_enum(v, name, &speed, prop->info->enum_table,
> @@ -962,7 +962,7 @@ static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
>                                      void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    PCIExpLinkWidth *p = qdev_get_prop_ptr(obj, prop);
> +    PCIExpLinkWidth *p = object_field_prop_ptr(obj, prop);
>       int width;
>   
>       switch (*p) {
> @@ -999,7 +999,7 @@ static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
>                                      void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    PCIExpLinkWidth *p = qdev_get_prop_ptr(obj, prop);
> +    PCIExpLinkWidth *p = object_field_prop_ptr(obj, prop);
>       int width;
>   
>       if (!visit_type_enum(v, name, &width, prop->info->enum_table,
> @@ -1050,7 +1050,7 @@ static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
>                        Error **errp)
>   {
>       Property *prop = opaque;
> -    QemuUUID *uuid = qdev_get_prop_ptr(obj, prop);
> +    QemuUUID *uuid = object_field_prop_ptr(obj, prop);
>       char buffer[UUID_FMT_LEN + 1];
>       char *p = buffer;
>   
> @@ -1065,7 +1065,7 @@ static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
>                       Error **errp)
>   {
>       Property *prop = opaque;
> -    QemuUUID *uuid = qdev_get_prop_ptr(obj, prop);
> +    QemuUUID *uuid = object_field_prop_ptr(obj, prop);
>       char *str;
>   
>       if (!visit_type_str(v, name, &str, errp)) {
> diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
> index aeab4ae9b6..9aebd7b8a9 100644
> --- a/hw/core/qdev-properties.c
> +++ b/hw/core/qdev-properties.c
> @@ -50,7 +50,7 @@ void qdev_prop_allow_set_link_before_realize(const Object *obj,
>       }
>   }
>   
> -void *qdev_get_prop_ptr(Object *obj, Property *prop)
> +void *object_field_prop_ptr(Object *obj, Property *prop)
>   {
>       void *ptr = obj;
>       ptr += prop->offset;
> @@ -96,7 +96,7 @@ void field_prop_get_enum(Object *obj, Visitor *v, const char *name,
>                            void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    int *ptr = qdev_get_prop_ptr(obj, prop);
> +    int *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
>   }
> @@ -105,7 +105,7 @@ void field_prop_set_enum(Object *obj, Visitor *v, const char *name,
>                            void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    int *ptr = qdev_get_prop_ptr(obj, prop);
> +    int *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
>   }
> @@ -134,7 +134,7 @@ static uint32_t qdev_get_prop_mask(Property *prop)
>   
>   static void bit_prop_set(Object *obj, Property *props, bool val)
>   {
> -    uint32_t *p = qdev_get_prop_ptr(obj, props);
> +    uint32_t *p = object_field_prop_ptr(obj, props);
>       uint32_t mask = qdev_get_prop_mask(props);
>       if (val) {
>           *p |= mask;
> @@ -147,7 +147,7 @@ static void prop_get_bit(Object *obj, Visitor *v, const char *name,
>                            void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    uint32_t *p = qdev_get_prop_ptr(obj, prop);
> +    uint32_t *p = object_field_prop_ptr(obj, prop);
>       bool value = (*p & qdev_get_prop_mask(prop)) != 0;
>   
>       visit_type_bool(v, name, &value, errp);
> @@ -188,7 +188,7 @@ static uint64_t qdev_get_prop_mask64(Property *prop)
>   
>   static void bit64_prop_set(Object *obj, Property *props, bool val)
>   {
> -    uint64_t *p = qdev_get_prop_ptr(obj, props);
> +    uint64_t *p = object_field_prop_ptr(obj, props);
>       uint64_t mask = qdev_get_prop_mask64(props);
>       if (val) {
>           *p |= mask;
> @@ -201,7 +201,7 @@ static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
>                              void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    uint64_t *p = qdev_get_prop_ptr(obj, prop);
> +    uint64_t *p = object_field_prop_ptr(obj, prop);
>       bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
>   
>       visit_type_bool(v, name, &value, errp);
> @@ -233,7 +233,7 @@ static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
>                        Error **errp)
>   {
>       Property *prop = opaque;
> -    bool *ptr = qdev_get_prop_ptr(obj, prop);
> +    bool *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_bool(v, name, ptr, errp);
>   }
> @@ -242,7 +242,7 @@ static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
>                        Error **errp)
>   {
>       Property *prop = opaque;
> -    bool *ptr = qdev_get_prop_ptr(obj, prop);
> +    bool *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_bool(v, name, ptr, errp);
>   }
> @@ -260,7 +260,7 @@ static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
>                         Error **errp)
>   {
>       Property *prop = opaque;
> -    uint8_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint8_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_uint8(v, name, ptr, errp);
>   }
> @@ -269,7 +269,7 @@ static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
>                         Error **errp)
>   {
>       Property *prop = opaque;
> -    uint8_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint8_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_uint8(v, name, ptr, errp);
>   }
> @@ -299,7 +299,7 @@ static void get_uint16(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    uint16_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint16_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_uint16(v, name, ptr, errp);
>   }
> @@ -308,7 +308,7 @@ static void set_uint16(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    uint16_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint16_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_uint16(v, name, ptr, errp);
>   }
> @@ -326,7 +326,7 @@ static void get_uint32(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint32_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_uint32(v, name, ptr, errp);
>   }
> @@ -335,7 +335,7 @@ static void set_uint32(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint32_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_uint32(v, name, ptr, errp);
>   }
> @@ -344,7 +344,7 @@ void field_prop_get_int32(Object *obj, Visitor *v, const char *name,
>                             void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    int32_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    int32_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_int32(v, name, ptr, errp);
>   }
> @@ -353,7 +353,7 @@ static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
>                         Error **errp)
>   {
>       Property *prop = opaque;
> -    int32_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    int32_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_int32(v, name, ptr, errp);
>   }
> @@ -378,7 +378,7 @@ static void get_uint64(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint64_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_uint64(v, name, ptr, errp);
>   }
> @@ -387,7 +387,7 @@ static void set_uint64(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint64_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_uint64(v, name, ptr, errp);
>   }
> @@ -396,7 +396,7 @@ static void get_int64(Object *obj, Visitor *v, const char *name,
>                         void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    int64_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    int64_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_int64(v, name, ptr, errp);
>   }
> @@ -405,7 +405,7 @@ static void set_int64(Object *obj, Visitor *v, const char *name,
>                         void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    int64_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    int64_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_int64(v, name, ptr, errp);
>   }
> @@ -429,14 +429,14 @@ const PropertyInfo qdev_prop_int64 = {
>   static void release_string(Object *obj, const char *name, void *opaque)
>   {
>       Property *prop = opaque;
> -    g_free(*(char **)qdev_get_prop_ptr(obj, prop));
> +    g_free(*(char **)object_field_prop_ptr(obj, prop));
>   }
>   
>   static void get_string(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    char **ptr = qdev_get_prop_ptr(obj, prop);
> +    char **ptr = object_field_prop_ptr(obj, prop);
>   
>       if (!*ptr) {
>           char *str = (char *)"";
> @@ -450,7 +450,7 @@ static void set_string(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    char **ptr = qdev_get_prop_ptr(obj, prop);
> +    char **ptr = object_field_prop_ptr(obj, prop);
>       char *str;
>   
>       if (!visit_type_str(v, name, &str, errp)) {
> @@ -484,7 +484,7 @@ void field_prop_get_size32(Object *obj, Visitor *v, const char *name,
>                              void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint32_t *ptr = object_field_prop_ptr(obj, prop);
>       uint64_t value = *ptr;
>   
>       visit_type_size(v, name, &value, errp);
> @@ -494,7 +494,7 @@ static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
>                          Error **errp)
>   {
>       Property *prop = opaque;
> -    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint32_t *ptr = object_field_prop_ptr(obj, prop);
>       uint64_t value;
>   
>       if (!visit_type_size(v, name, &value, errp)) {
> @@ -531,7 +531,7 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
>        */
>       Property *prop = opaque;
>       ObjectProperty *op = object_property_find_err(obj, name, &error_abort);
> -    uint32_t *alenptr = qdev_get_prop_ptr(obj, prop);
> +    uint32_t *alenptr = object_field_prop_ptr(obj, prop);
>       void **arrayptr = (void *)obj + prop->arrayoffset;
>       void *eltptr;
>       const char *arrayname;
> @@ -570,7 +570,7 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
>            * being inside the device struct.
>            */
>           arrayprop->offset = eltptr - (void *)obj;
> -        assert(qdev_get_prop_ptr(obj, arrayprop) == eltptr);
> +        assert(object_field_prop_ptr(obj, arrayprop) == eltptr);
>           object_property_add_field(obj, propname, arrayprop, op->allow_set);
>       }
>   }
> @@ -760,7 +760,7 @@ static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
>                        Error **errp)
>   {
>       Property *prop = opaque;
> -    uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint64_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_size(v, name, ptr, errp);
>   }
> @@ -769,7 +769,7 @@ static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
>                        Error **errp)
>   {
>       Property *prop = opaque;
> -    uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint64_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_size(v, name, ptr, errp);
>   }
> diff --git a/hw/s390x/css.c b/hw/s390x/css.c
> index 496e2c5801..fe47751df4 100644
> --- a/hw/s390x/css.c
> +++ b/hw/s390x/css.c
> @@ -2344,7 +2344,7 @@ static void get_css_devid(Object *obj, Visitor *v, const char *name,
>                             void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    CssDevId *dev_id = qdev_get_prop_ptr(obj, prop);
> +    CssDevId *dev_id = object_field_prop_ptr(obj, prop);
>       char buffer[] = "xx.x.xxxx";
>       char *p = buffer;
>       int r;
> @@ -2373,7 +2373,7 @@ static void set_css_devid(Object *obj, Visitor *v, const char *name,
>                             void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    CssDevId *dev_id = qdev_get_prop_ptr(obj, prop);
> +    CssDevId *dev_id = object_field_prop_ptr(obj, prop);
>       char *str;
>       int num, n1, n2;
>       unsigned int cssid, ssid, devid;
> diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
> index 54fac3851d..99b18d56ba 100644
> --- a/hw/s390x/s390-pci-bus.c
> +++ b/hw/s390x/s390-pci-bus.c
> @@ -1323,7 +1323,7 @@ static void s390_pci_get_fid(Object *obj, Visitor *v, const char *name,
>                            void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint32_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_uint32(v, name, ptr, errp);
>   }
> @@ -1333,7 +1333,7 @@ static void s390_pci_set_fid(Object *obj, Visitor *v, const char *name,
>   {
>       S390PCIBusDevice *zpci = S390_PCI_DEVICE(obj);
>       Property *prop = opaque;
> -    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint32_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       if (!visit_type_uint32(v, name, ptr, errp)) {
>           return;
> diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
> index 802979635c..fc8d63c850 100644
> --- a/hw/vfio/pci-quirks.c
> +++ b/hw/vfio/pci-quirks.c
> @@ -1489,7 +1489,7 @@ static void get_nv_gpudirect_clique_id(Object *obj, Visitor *v,
>                                          Error **errp)
>   {
>       Property *prop = opaque;
> -    uint8_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint8_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_uint8(v, name, ptr, errp);
>   }
> @@ -1499,7 +1499,7 @@ static void set_nv_gpudirect_clique_id(Object *obj, Visitor *v,
>                                          Error **errp)
>   {
>       Property *prop = opaque;
> -    uint8_t value, *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint8_t value, *ptr = object_field_prop_ptr(obj, prop);
>   
>       if (!visit_type_uint8(v, name, &value, errp)) {
>           return;




^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 36/44] qdev: Rename qdev_get_prop_ptr() to object_field_prop_ptr()
@ 2020-11-05 18:49     ` Stefan Berger
  0 siblings, 0 replies; 77+ messages in thread
From: Stefan Berger @ 2020-11-05 18:49 UTC (permalink / raw)
  To: Eduardo Habkost, qemu-devel
  Cc: Daniel P. Berrange, Paolo Bonzini, Igor Mammedov, Eric Blake,
	Markus Armbruster, Marc-André Lureau, John Snow,
	Philippe Mathieu-Daudé,
	Stefan Berger, Stefano Stabellini, Anthony Perard, Paul Durrant,
	Kevin Wolf, Max Reitz, Cornelia Huck, Halil Pasic,
	Christian Borntraeger, Richard Henderson, David Hildenbrand,
	Thomas Huth, Matthew Rosato, Alex Williamson, xen-devel,
	qemu-block, qemu-s390x

On 11/4/20 11:00 AM, Eduardo Habkost wrote:
> The function will be moved to common QOM code, as it is not
> specific to TYPE_DEVICE anymore.
>
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>

Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>


> ---
> Changes v1 -> v2:
> * Rename to object_field_prop_ptr() instead of object_static_prop_ptr()
> ---
> Cc: Stefan Berger <stefanb@linux.vnet.ibm.com>
> Cc: Stefano Stabellini <sstabellini@kernel.org>
> Cc: Anthony Perard <anthony.perard@citrix.com>
> Cc: Paul Durrant <paul@xen.org>
> Cc: Kevin Wolf <kwolf@redhat.com>
> Cc: Max Reitz <mreitz@redhat.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Cc: "Daniel P. Berrangé" <berrange@redhat.com>
> Cc: Eduardo Habkost <ehabkost@redhat.com>
> Cc: Cornelia Huck <cohuck@redhat.com>
> Cc: Halil Pasic <pasic@linux.ibm.com>
> Cc: Christian Borntraeger <borntraeger@de.ibm.com>
> Cc: Richard Henderson <rth@twiddle.net>
> Cc: David Hildenbrand <david@redhat.com>
> Cc: Thomas Huth <thuth@redhat.com>
> Cc: Matthew Rosato <mjrosato@linux.ibm.com>
> Cc: Alex Williamson <alex.williamson@redhat.com>
> Cc: qemu-devel@nongnu.org
> Cc: xen-devel@lists.xenproject.org
> Cc: qemu-block@nongnu.org
> Cc: qemu-s390x@nongnu.org
> ---
>   include/hw/qdev-properties.h     |  2 +-
>   backends/tpm/tpm_util.c          |  6 ++--
>   hw/block/xen-block.c             |  4 +--
>   hw/core/qdev-properties-system.c | 50 +++++++++++++-------------
>   hw/core/qdev-properties.c        | 60 ++++++++++++++++----------------
>   hw/s390x/css.c                   |  4 +--
>   hw/s390x/s390-pci-bus.c          |  4 +--
>   hw/vfio/pci-quirks.c             |  4 +--
>   8 files changed, 67 insertions(+), 67 deletions(-)
>
> diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
> index 7f8d5fc206..2bec65c8e5 100644
> --- a/include/hw/qdev-properties.h
> +++ b/include/hw/qdev-properties.h
> @@ -223,7 +223,7 @@ void qdev_prop_set_macaddr(DeviceState *dev, const char *name,
>                              const uint8_t *value);
>   void qdev_prop_set_enum(DeviceState *dev, const char *name, int value);
>   
> -void *qdev_get_prop_ptr(Object *obj, Property *prop);
> +void *object_field_prop_ptr(Object *obj, Property *prop);
>   
>   void qdev_prop_register_global(GlobalProperty *prop);
>   const GlobalProperty *qdev_find_global_prop(Object *obj,
> diff --git a/backends/tpm/tpm_util.c b/backends/tpm/tpm_util.c
> index 0b07cf55ea..bb1ab34a75 100644
> --- a/backends/tpm/tpm_util.c
> +++ b/backends/tpm/tpm_util.c
> @@ -35,7 +35,7 @@
>   static void get_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
>                       Error **errp)
>   {
> -    TPMBackend **be = qdev_get_prop_ptr(obj, opaque);
> +    TPMBackend **be = object_field_prop_ptr(obj, opaque);
>       char *p;
>   
>       p = g_strdup(*be ? (*be)->id : "");
> @@ -47,7 +47,7 @@ static void set_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
>                       Error **errp)
>   {
>       Property *prop = opaque;
> -    TPMBackend *s, **be = qdev_get_prop_ptr(obj, prop);
> +    TPMBackend *s, **be = object_field_prop_ptr(obj, prop);
>       char *str;
>   
>       if (!visit_type_str(v, name, &str, errp)) {
> @@ -67,7 +67,7 @@ static void set_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
>   static void release_tpm(Object *obj, const char *name, void *opaque)
>   {
>       Property *prop = opaque;
> -    TPMBackend **be = qdev_get_prop_ptr(obj, prop);
> +    TPMBackend **be = object_field_prop_ptr(obj, prop);
>   
>       if (*be) {
>           tpm_backend_reset(*be);
> diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
> index bd1aef63a7..718d886e5c 100644
> --- a/hw/block/xen-block.c
> +++ b/hw/block/xen-block.c
> @@ -336,7 +336,7 @@ static void xen_block_get_vdev(Object *obj, Visitor *v, const char *name,
>                                  void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    XenBlockVdev *vdev = qdev_get_prop_ptr(obj, prop);
> +    XenBlockVdev *vdev = object_field_prop_ptr(obj, prop);
>       char *str;
>   
>       switch (vdev->type) {
> @@ -396,7 +396,7 @@ static void xen_block_set_vdev(Object *obj, Visitor *v, const char *name,
>                                  void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    XenBlockVdev *vdev = qdev_get_prop_ptr(obj, prop);
> +    XenBlockVdev *vdev = object_field_prop_ptr(obj, prop);
>       char *str, *p;
>       const char *end;
>   
> diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
> index 96a0bc5109..8781b856d3 100644
> --- a/hw/core/qdev-properties-system.c
> +++ b/hw/core/qdev-properties-system.c
> @@ -62,7 +62,7 @@ static void get_drive(Object *obj, Visitor *v, const char *name, void *opaque,
>                         Error **errp)
>   {
>       Property *prop = opaque;
> -    void **ptr = qdev_get_prop_ptr(obj, prop);
> +    void **ptr = object_field_prop_ptr(obj, prop);
>       const char *value;
>       char *p;
>   
> @@ -88,7 +88,7 @@ static void set_drive_helper(Object *obj, Visitor *v, const char *name,
>   {
>       DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
> -    void **ptr = qdev_get_prop_ptr(obj, prop);
> +    void **ptr = object_field_prop_ptr(obj, prop);
>       char *str;
>       BlockBackend *blk;
>       bool blk_created = false;
> @@ -181,7 +181,7 @@ static void release_drive(Object *obj, const char *name, void *opaque)
>   {
>       DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
> -    BlockBackend **ptr = qdev_get_prop_ptr(obj, prop);
> +    BlockBackend **ptr = object_field_prop_ptr(obj, prop);
>   
>       if (*ptr) {
>           AioContext *ctx = blk_get_aio_context(*ptr);
> @@ -214,7 +214,7 @@ const PropertyInfo qdev_prop_drive_iothread = {
>   static void get_chr(Object *obj, Visitor *v, const char *name, void *opaque,
>                       Error **errp)
>   {
> -    CharBackend *be = qdev_get_prop_ptr(obj, opaque);
> +    CharBackend *be = object_field_prop_ptr(obj, opaque);
>       char *p;
>   
>       p = g_strdup(be->chr && be->chr->label ? be->chr->label : "");
> @@ -226,7 +226,7 @@ static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
>                       Error **errp)
>   {
>       Property *prop = opaque;
> -    CharBackend *be = qdev_get_prop_ptr(obj, prop);
> +    CharBackend *be = object_field_prop_ptr(obj, prop);
>       Chardev *s;
>       char *str;
>   
> @@ -262,7 +262,7 @@ static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
>   static void release_chr(Object *obj, const char *name, void *opaque)
>   {
>       Property *prop = opaque;
> -    CharBackend *be = qdev_get_prop_ptr(obj, prop);
> +    CharBackend *be = object_field_prop_ptr(obj, prop);
>   
>       qemu_chr_fe_deinit(be, false);
>   }
> @@ -286,7 +286,7 @@ static void get_mac(Object *obj, Visitor *v, const char *name, void *opaque,
>                       Error **errp)
>   {
>       Property *prop = opaque;
> -    MACAddr *mac = qdev_get_prop_ptr(obj, prop);
> +    MACAddr *mac = object_field_prop_ptr(obj, prop);
>       char buffer[2 * 6 + 5 + 1];
>       char *p = buffer;
>   
> @@ -301,7 +301,7 @@ static void set_mac(Object *obj, Visitor *v, const char *name, void *opaque,
>                       Error **errp)
>   {
>       Property *prop = opaque;
> -    MACAddr *mac = qdev_get_prop_ptr(obj, prop);
> +    MACAddr *mac = object_field_prop_ptr(obj, prop);
>       int i, pos;
>       char *str;
>       const char *p;
> @@ -363,7 +363,7 @@ static void get_netdev(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    NICPeers *peers_ptr = qdev_get_prop_ptr(obj, prop);
> +    NICPeers *peers_ptr = object_field_prop_ptr(obj, prop);
>       char *p = g_strdup(peers_ptr->ncs[0] ? peers_ptr->ncs[0]->name : "");
>   
>       visit_type_str(v, name, &p, errp);
> @@ -374,7 +374,7 @@ static void set_netdev(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    NICPeers *peers_ptr = qdev_get_prop_ptr(obj, prop);
> +    NICPeers *peers_ptr = object_field_prop_ptr(obj, prop);
>       NetClientState **ncs = peers_ptr->ncs;
>       NetClientState *peers[MAX_QUEUE_NUM];
>       int queues, err = 0, i = 0;
> @@ -436,7 +436,7 @@ static void get_audiodev(Object *obj, Visitor *v, const char* name,
>                            void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    QEMUSoundCard *card = qdev_get_prop_ptr(obj, prop);
> +    QEMUSoundCard *card = object_field_prop_ptr(obj, prop);
>       char *p = g_strdup(audio_get_id(card));
>   
>       visit_type_str(v, name, &p, errp);
> @@ -447,7 +447,7 @@ static void set_audiodev(Object *obj, Visitor *v, const char* name,
>                            void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    QEMUSoundCard *card = qdev_get_prop_ptr(obj, prop);
> +    QEMUSoundCard *card = object_field_prop_ptr(obj, prop);
>       AudioState *state;
>       int err = 0;
>       char *str;
> @@ -549,7 +549,7 @@ static void set_blocksize(Object *obj, Visitor *v, const char *name,
>   {
>       DeviceState *dev = DEVICE(obj);
>       Property *prop = opaque;
> -    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint32_t *ptr = object_field_prop_ptr(obj, prop);
>       uint64_t value;
>       Error *local_err = NULL;
>   
> @@ -637,7 +637,7 @@ static void get_reserved_region(Object *obj, Visitor *v, const char *name,
>                                   void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    ReservedRegion *rr = qdev_get_prop_ptr(obj, prop);
> +    ReservedRegion *rr = object_field_prop_ptr(obj, prop);
>       char buffer[64];
>       char *p = buffer;
>       int rc;
> @@ -653,7 +653,7 @@ static void set_reserved_region(Object *obj, Visitor *v, const char *name,
>                                   void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    ReservedRegion *rr = qdev_get_prop_ptr(obj, prop);
> +    ReservedRegion *rr = object_field_prop_ptr(obj, prop);
>       Error *local_err = NULL;
>       const char *endptr;
>       char *str;
> @@ -715,7 +715,7 @@ static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
>                             void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    int32_t value, *ptr = qdev_get_prop_ptr(obj, prop);
> +    int32_t value, *ptr = object_field_prop_ptr(obj, prop);
>       unsigned int slot, fn, n;
>       char *str;
>   
> @@ -753,7 +753,7 @@ invalid:
>   static int print_pci_devfn(Object *obj, Property *prop, char *dest,
>                              size_t len)
>   {
> -    int32_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    int32_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       if (*ptr == -1) {
>           return snprintf(dest, len, "<unset>");
> @@ -777,7 +777,7 @@ static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
>                                    void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(obj, prop);
> +    PCIHostDeviceAddress *addr = object_field_prop_ptr(obj, prop);
>       char buffer[] = "ffff:ff:ff.f";
>       char *p = buffer;
>       int rc = 0;
> @@ -803,7 +803,7 @@ static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
>                                    void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(obj, prop);
> +    PCIHostDeviceAddress *addr = object_field_prop_ptr(obj, prop);
>       char *str, *p;
>       const char *e;
>       unsigned long val;
> @@ -892,7 +892,7 @@ static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
>                                      void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    PCIExpLinkSpeed *p = qdev_get_prop_ptr(obj, prop);
> +    PCIExpLinkSpeed *p = object_field_prop_ptr(obj, prop);
>       int speed;
>   
>       switch (*p) {
> @@ -920,7 +920,7 @@ static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
>                                      void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    PCIExpLinkSpeed *p = qdev_get_prop_ptr(obj, prop);
> +    PCIExpLinkSpeed *p = object_field_prop_ptr(obj, prop);
>       int speed;
>   
>       if (!visit_type_enum(v, name, &speed, prop->info->enum_table,
> @@ -962,7 +962,7 @@ static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
>                                      void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    PCIExpLinkWidth *p = qdev_get_prop_ptr(obj, prop);
> +    PCIExpLinkWidth *p = object_field_prop_ptr(obj, prop);
>       int width;
>   
>       switch (*p) {
> @@ -999,7 +999,7 @@ static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
>                                      void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    PCIExpLinkWidth *p = qdev_get_prop_ptr(obj, prop);
> +    PCIExpLinkWidth *p = object_field_prop_ptr(obj, prop);
>       int width;
>   
>       if (!visit_type_enum(v, name, &width, prop->info->enum_table,
> @@ -1050,7 +1050,7 @@ static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
>                        Error **errp)
>   {
>       Property *prop = opaque;
> -    QemuUUID *uuid = qdev_get_prop_ptr(obj, prop);
> +    QemuUUID *uuid = object_field_prop_ptr(obj, prop);
>       char buffer[UUID_FMT_LEN + 1];
>       char *p = buffer;
>   
> @@ -1065,7 +1065,7 @@ static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
>                       Error **errp)
>   {
>       Property *prop = opaque;
> -    QemuUUID *uuid = qdev_get_prop_ptr(obj, prop);
> +    QemuUUID *uuid = object_field_prop_ptr(obj, prop);
>       char *str;
>   
>       if (!visit_type_str(v, name, &str, errp)) {
> diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
> index aeab4ae9b6..9aebd7b8a9 100644
> --- a/hw/core/qdev-properties.c
> +++ b/hw/core/qdev-properties.c
> @@ -50,7 +50,7 @@ void qdev_prop_allow_set_link_before_realize(const Object *obj,
>       }
>   }
>   
> -void *qdev_get_prop_ptr(Object *obj, Property *prop)
> +void *object_field_prop_ptr(Object *obj, Property *prop)
>   {
>       void *ptr = obj;
>       ptr += prop->offset;
> @@ -96,7 +96,7 @@ void field_prop_get_enum(Object *obj, Visitor *v, const char *name,
>                            void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    int *ptr = qdev_get_prop_ptr(obj, prop);
> +    int *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
>   }
> @@ -105,7 +105,7 @@ void field_prop_set_enum(Object *obj, Visitor *v, const char *name,
>                            void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    int *ptr = qdev_get_prop_ptr(obj, prop);
> +    int *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
>   }
> @@ -134,7 +134,7 @@ static uint32_t qdev_get_prop_mask(Property *prop)
>   
>   static void bit_prop_set(Object *obj, Property *props, bool val)
>   {
> -    uint32_t *p = qdev_get_prop_ptr(obj, props);
> +    uint32_t *p = object_field_prop_ptr(obj, props);
>       uint32_t mask = qdev_get_prop_mask(props);
>       if (val) {
>           *p |= mask;
> @@ -147,7 +147,7 @@ static void prop_get_bit(Object *obj, Visitor *v, const char *name,
>                            void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    uint32_t *p = qdev_get_prop_ptr(obj, prop);
> +    uint32_t *p = object_field_prop_ptr(obj, prop);
>       bool value = (*p & qdev_get_prop_mask(prop)) != 0;
>   
>       visit_type_bool(v, name, &value, errp);
> @@ -188,7 +188,7 @@ static uint64_t qdev_get_prop_mask64(Property *prop)
>   
>   static void bit64_prop_set(Object *obj, Property *props, bool val)
>   {
> -    uint64_t *p = qdev_get_prop_ptr(obj, props);
> +    uint64_t *p = object_field_prop_ptr(obj, props);
>       uint64_t mask = qdev_get_prop_mask64(props);
>       if (val) {
>           *p |= mask;
> @@ -201,7 +201,7 @@ static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
>                              void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    uint64_t *p = qdev_get_prop_ptr(obj, prop);
> +    uint64_t *p = object_field_prop_ptr(obj, prop);
>       bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
>   
>       visit_type_bool(v, name, &value, errp);
> @@ -233,7 +233,7 @@ static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
>                        Error **errp)
>   {
>       Property *prop = opaque;
> -    bool *ptr = qdev_get_prop_ptr(obj, prop);
> +    bool *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_bool(v, name, ptr, errp);
>   }
> @@ -242,7 +242,7 @@ static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
>                        Error **errp)
>   {
>       Property *prop = opaque;
> -    bool *ptr = qdev_get_prop_ptr(obj, prop);
> +    bool *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_bool(v, name, ptr, errp);
>   }
> @@ -260,7 +260,7 @@ static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
>                         Error **errp)
>   {
>       Property *prop = opaque;
> -    uint8_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint8_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_uint8(v, name, ptr, errp);
>   }
> @@ -269,7 +269,7 @@ static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
>                         Error **errp)
>   {
>       Property *prop = opaque;
> -    uint8_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint8_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_uint8(v, name, ptr, errp);
>   }
> @@ -299,7 +299,7 @@ static void get_uint16(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    uint16_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint16_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_uint16(v, name, ptr, errp);
>   }
> @@ -308,7 +308,7 @@ static void set_uint16(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    uint16_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint16_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_uint16(v, name, ptr, errp);
>   }
> @@ -326,7 +326,7 @@ static void get_uint32(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint32_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_uint32(v, name, ptr, errp);
>   }
> @@ -335,7 +335,7 @@ static void set_uint32(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint32_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_uint32(v, name, ptr, errp);
>   }
> @@ -344,7 +344,7 @@ void field_prop_get_int32(Object *obj, Visitor *v, const char *name,
>                             void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    int32_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    int32_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_int32(v, name, ptr, errp);
>   }
> @@ -353,7 +353,7 @@ static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
>                         Error **errp)
>   {
>       Property *prop = opaque;
> -    int32_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    int32_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_int32(v, name, ptr, errp);
>   }
> @@ -378,7 +378,7 @@ static void get_uint64(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint64_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_uint64(v, name, ptr, errp);
>   }
> @@ -387,7 +387,7 @@ static void set_uint64(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint64_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_uint64(v, name, ptr, errp);
>   }
> @@ -396,7 +396,7 @@ static void get_int64(Object *obj, Visitor *v, const char *name,
>                         void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    int64_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    int64_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_int64(v, name, ptr, errp);
>   }
> @@ -405,7 +405,7 @@ static void set_int64(Object *obj, Visitor *v, const char *name,
>                         void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    int64_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    int64_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_int64(v, name, ptr, errp);
>   }
> @@ -429,14 +429,14 @@ const PropertyInfo qdev_prop_int64 = {
>   static void release_string(Object *obj, const char *name, void *opaque)
>   {
>       Property *prop = opaque;
> -    g_free(*(char **)qdev_get_prop_ptr(obj, prop));
> +    g_free(*(char **)object_field_prop_ptr(obj, prop));
>   }
>   
>   static void get_string(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    char **ptr = qdev_get_prop_ptr(obj, prop);
> +    char **ptr = object_field_prop_ptr(obj, prop);
>   
>       if (!*ptr) {
>           char *str = (char *)"";
> @@ -450,7 +450,7 @@ static void set_string(Object *obj, Visitor *v, const char *name,
>                          void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    char **ptr = qdev_get_prop_ptr(obj, prop);
> +    char **ptr = object_field_prop_ptr(obj, prop);
>       char *str;
>   
>       if (!visit_type_str(v, name, &str, errp)) {
> @@ -484,7 +484,7 @@ void field_prop_get_size32(Object *obj, Visitor *v, const char *name,
>                              void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint32_t *ptr = object_field_prop_ptr(obj, prop);
>       uint64_t value = *ptr;
>   
>       visit_type_size(v, name, &value, errp);
> @@ -494,7 +494,7 @@ static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
>                          Error **errp)
>   {
>       Property *prop = opaque;
> -    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint32_t *ptr = object_field_prop_ptr(obj, prop);
>       uint64_t value;
>   
>       if (!visit_type_size(v, name, &value, errp)) {
> @@ -531,7 +531,7 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
>        */
>       Property *prop = opaque;
>       ObjectProperty *op = object_property_find_err(obj, name, &error_abort);
> -    uint32_t *alenptr = qdev_get_prop_ptr(obj, prop);
> +    uint32_t *alenptr = object_field_prop_ptr(obj, prop);
>       void **arrayptr = (void *)obj + prop->arrayoffset;
>       void *eltptr;
>       const char *arrayname;
> @@ -570,7 +570,7 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
>            * being inside the device struct.
>            */
>           arrayprop->offset = eltptr - (void *)obj;
> -        assert(qdev_get_prop_ptr(obj, arrayprop) == eltptr);
> +        assert(object_field_prop_ptr(obj, arrayprop) == eltptr);
>           object_property_add_field(obj, propname, arrayprop, op->allow_set);
>       }
>   }
> @@ -760,7 +760,7 @@ static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
>                        Error **errp)
>   {
>       Property *prop = opaque;
> -    uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint64_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_size(v, name, ptr, errp);
>   }
> @@ -769,7 +769,7 @@ static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
>                        Error **errp)
>   {
>       Property *prop = opaque;
> -    uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint64_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_size(v, name, ptr, errp);
>   }
> diff --git a/hw/s390x/css.c b/hw/s390x/css.c
> index 496e2c5801..fe47751df4 100644
> --- a/hw/s390x/css.c
> +++ b/hw/s390x/css.c
> @@ -2344,7 +2344,7 @@ static void get_css_devid(Object *obj, Visitor *v, const char *name,
>                             void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    CssDevId *dev_id = qdev_get_prop_ptr(obj, prop);
> +    CssDevId *dev_id = object_field_prop_ptr(obj, prop);
>       char buffer[] = "xx.x.xxxx";
>       char *p = buffer;
>       int r;
> @@ -2373,7 +2373,7 @@ static void set_css_devid(Object *obj, Visitor *v, const char *name,
>                             void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    CssDevId *dev_id = qdev_get_prop_ptr(obj, prop);
> +    CssDevId *dev_id = object_field_prop_ptr(obj, prop);
>       char *str;
>       int num, n1, n2;
>       unsigned int cssid, ssid, devid;
> diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
> index 54fac3851d..99b18d56ba 100644
> --- a/hw/s390x/s390-pci-bus.c
> +++ b/hw/s390x/s390-pci-bus.c
> @@ -1323,7 +1323,7 @@ static void s390_pci_get_fid(Object *obj, Visitor *v, const char *name,
>                            void *opaque, Error **errp)
>   {
>       Property *prop = opaque;
> -    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint32_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_uint32(v, name, ptr, errp);
>   }
> @@ -1333,7 +1333,7 @@ static void s390_pci_set_fid(Object *obj, Visitor *v, const char *name,
>   {
>       S390PCIBusDevice *zpci = S390_PCI_DEVICE(obj);
>       Property *prop = opaque;
> -    uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint32_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       if (!visit_type_uint32(v, name, ptr, errp)) {
>           return;
> diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
> index 802979635c..fc8d63c850 100644
> --- a/hw/vfio/pci-quirks.c
> +++ b/hw/vfio/pci-quirks.c
> @@ -1489,7 +1489,7 @@ static void get_nv_gpudirect_clique_id(Object *obj, Visitor *v,
>                                          Error **errp)
>   {
>       Property *prop = opaque;
> -    uint8_t *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint8_t *ptr = object_field_prop_ptr(obj, prop);
>   
>       visit_type_uint8(v, name, ptr, errp);
>   }
> @@ -1499,7 +1499,7 @@ static void set_nv_gpudirect_clique_id(Object *obj, Visitor *v,
>                                          Error **errp)
>   {
>       Property *prop = opaque;
> -    uint8_t value, *ptr = qdev_get_prop_ptr(obj, prop);
> +    uint8_t value, *ptr = object_field_prop_ptr(obj, prop);
>   
>       if (!visit_type_uint8(v, name, &value, errp)) {
>           return;




^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 37/44] qdev: Move qdev_prop_tpm declaration to tpm_prop.h
  2020-11-04 16:00 ` [PATCH v2 37/44] qdev: Move qdev_prop_tpm declaration to tpm_prop.h Eduardo Habkost
@ 2020-11-05 18:50   ` Stefan Berger
  0 siblings, 0 replies; 77+ messages in thread
From: Stefan Berger @ 2020-11-05 18:50 UTC (permalink / raw)
  To: Eduardo Habkost, qemu-devel
  Cc: Daniel P. Berrange, Igor Mammedov, John Snow, Stefan Berger,
	Markus Armbruster, Philippe Mathieu-Daudé,
	Marc-André Lureau, Paolo Bonzini

On 11/4/20 11:00 AM, Eduardo Habkost wrote:
> Move the variable declaration close to the macro that uses it.
>
> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>


Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>


> ---
> Cc: Stefan Berger <stefanb@linux.vnet.ibm.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Cc: "Daniel P. Berrangé" <berrange@redhat.com>
> Cc: Eduardo Habkost <ehabkost@redhat.com>
> Cc: qemu-devel@nongnu.org
> ---
>   hw/tpm/tpm_prop.h            | 2 ++
>   include/hw/qdev-properties.h | 1 -
>   2 files changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/hw/tpm/tpm_prop.h b/hw/tpm/tpm_prop.h
> index 85e1ae5718..871af584b7 100644
> --- a/hw/tpm/tpm_prop.h
> +++ b/hw/tpm/tpm_prop.h
> @@ -25,6 +25,8 @@
>   #include "sysemu/tpm_backend.h"
>   #include "hw/qdev-properties.h"
>   
> +extern const PropertyInfo qdev_prop_tpm;
> +
>   #define DEFINE_PROP_TPMBE(_n, _s, _f)                     \
>       DEFINE_PROP(_n, _s, _f, qdev_prop_tpm, TPMBackend *)
>   
> diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
> index 2bec65c8e5..c3eaf5e3c5 100644
> --- a/include/hw/qdev-properties.h
> +++ b/include/hw/qdev-properties.h
> @@ -63,7 +63,6 @@ extern const PropertyInfo qdev_prop_uint64;
>   extern const PropertyInfo qdev_prop_int64;
>   extern const PropertyInfo qdev_prop_size;
>   extern const PropertyInfo qdev_prop_string;
> -extern const PropertyInfo qdev_prop_tpm;
>   extern const PropertyInfo qdev_prop_on_off_auto;
>   extern const PropertyInfo qdev_prop_size32;
>   extern const PropertyInfo qdev_prop_arraylen;




^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 00/44] Make qdev static property API usable by any QOM type
  2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
                   ` (44 preceding siblings ...)
  2020-11-04 16:36 ` [PATCH v2 00/44] Make qdev static property API usable by any QOM type no-reply
@ 2020-11-06  9:45 ` Kevin Wolf
  2020-11-06 15:50   ` Eduardo Habkost
  45 siblings, 1 reply; 77+ messages in thread
From: Kevin Wolf @ 2020-11-06  9:45 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: Daniel P. Berrange, Philippe Mathieu-Daudé,
	qemu-devel, Markus Armbruster, Paolo Bonzini, Igor Mammedov,
	Marc-André Lureau, John Snow, Stefan Berger

Am 04.11.2020 um 16:59 hat Eduardo Habkost geschrieben:
> This series refactor the qdev property code so the static
> property system can be used by any QOM type.  As an example, at
> the end of the series some properties in TYPE_MACHINE are
> converted to static properties to demonstrate the new API.
> 
> Changes v1 -> v2
> ----------------
> 
> * Rename functions and source files to call the new feature
>   "field property" instead of "static property"
> 
> * Change the API signature from an array-based interface similar
>   to device_class_set_props() to a object_property_add()-like
>   interface.
> 
>   This means instead of doing this:
> 
>     object_class_property_add_static_props(oc, my_array_of_props);
> 
>   properties are registered like this:
> 
>     object_class_property_add_field(oc, "property-name"
>                                     PROP_XXX(MyState, my_field),
>                                     prop_allow_set_always);
> 
>   where PROP_XXX is a PROP_* macro like PROP_STRING, PROP_BOOL,
>   etc.

In comparison, I really like the resulting code from the array based
interface in v1 better.

I think it's mostly for two reasons: First, the array is much more
compact and easier to read. And maybe even more importantly, you know
it's static data and only static data. The function based interface can
be mixed with other code or the parameter list can contain calls to
other functions with side effects, so there are a lot more opportunities
for surprises.

What I didn't like about the v1 interface is that there is still a
separate object_class_property_set_description() for each property, but
I think that could have been fixed by moving the description to the
definitions in the array, too.

On Fri, Oct 30, 2020 at 06:10:34PM +0100, Paolo Bonzini wrote:
> On 29/10/20 23:02, Eduardo Habkost wrote:
> > +static Property machine_props[] = {
> > +    DEFINE_PROP_STRING("kernel", MachineState, kernel_filename),
> > +    DEFINE_PROP_STRING("initrd", MachineState, initrd_filename),
> > +    DEFINE_PROP_STRING("append", MachineState, kernel_cmdline),
> > +    DEFINE_PROP_STRING("dtb", MachineState, dtb),
> > +    DEFINE_PROP_STRING("dumpdtb", MachineState, dumpdtb),
> > +    DEFINE_PROP_STRING("dt-compatible", MachineState, dt_compatible),
> > +    DEFINE_PROP_STRING("firmware", MachineState, firmware),
> > +    DEFINE_PROP_STRING("memory-backend", MachineState, ram_memdev_id),
> > +    DEFINE_PROP_END_OF_LIST(),
> > +};
> > +
>
> While I think generalizing the _code_ for static properties is obviously
> a good idea, I am not sure about generalizing the interface for adding them.
>
> The reason is that we already have a place for adding properties in
> class_init, and having a second makes things "less local", so to speak.

As long as you have the function call to apply the properites array in
.class_init, it should be obvious enough what you're doing.

Of course, I think we should refrain from mixing both styles in a single
object, but generally speaking the array feels so much better that I
don't think we should reject it just because QOM only had a different
interface so far (and the property array is preexisting in qdev, too, so
we already have differences between objects - in fact, the majority of
objects is probably qdev today).

Kevin



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 00/44] Make qdev static property API usable by any QOM type
  2020-11-06  9:45 ` Kevin Wolf
@ 2020-11-06 15:50   ` Eduardo Habkost
  2020-11-06 21:10     ` Eduardo Habkost
  0 siblings, 1 reply; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-06 15:50 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Daniel P. Berrange, Philippe Mathieu-Daudé,
	qemu-devel, Markus Armbruster, Paolo Bonzini, Igor Mammedov,
	Marc-André Lureau, John Snow, Stefan Berger

On Fri, Nov 06, 2020 at 10:45:11AM +0100, Kevin Wolf wrote:
> Am 04.11.2020 um 16:59 hat Eduardo Habkost geschrieben:
> > This series refactor the qdev property code so the static
> > property system can be used by any QOM type.  As an example, at
> > the end of the series some properties in TYPE_MACHINE are
> > converted to static properties to demonstrate the new API.
> > 
> > Changes v1 -> v2
> > ----------------
> > 
> > * Rename functions and source files to call the new feature
> >   "field property" instead of "static property"
> > 
> > * Change the API signature from an array-based interface similar
> >   to device_class_set_props() to a object_property_add()-like
> >   interface.
> > 
> >   This means instead of doing this:
> > 
> >     object_class_property_add_static_props(oc, my_array_of_props);
> > 
> >   properties are registered like this:
> > 
> >     object_class_property_add_field(oc, "property-name"
> >                                     PROP_XXX(MyState, my_field),
> >                                     prop_allow_set_always);
> > 
> >   where PROP_XXX is a PROP_* macro like PROP_STRING, PROP_BOOL,
> >   etc.
> 
> In comparison, I really like the resulting code from the array based
> interface in v1 better.
> 
> I think it's mostly for two reasons: First, the array is much more
> compact and easier to read. And maybe even more importantly, you know
> it's static data and only static data. The function based interface can
> be mixed with other code or the parameter list can contain calls to
> other functions with side effects, so there are a lot more opportunities
> for surprises.

This is a really good point, and I strongly agree with it.
Letting code do funny tricks at runtime is one of the reasons QOM
properties became hard to introspect.

> 
> What I didn't like about the v1 interface is that there is still a
> separate object_class_property_set_description() for each property, but
> I think that could have been fixed by moving the description to the
> definitions in the array, too.

This would be very easy to implement.

> 
> On Fri, Oct 30, 2020 at 06:10:34PM +0100, Paolo Bonzini wrote:
> > On 29/10/20 23:02, Eduardo Habkost wrote:
> > > +static Property machine_props[] = {
> > > +    DEFINE_PROP_STRING("kernel", MachineState, kernel_filename),
> > > +    DEFINE_PROP_STRING("initrd", MachineState, initrd_filename),
> > > +    DEFINE_PROP_STRING("append", MachineState, kernel_cmdline),
> > > +    DEFINE_PROP_STRING("dtb", MachineState, dtb),
> > > +    DEFINE_PROP_STRING("dumpdtb", MachineState, dumpdtb),
> > > +    DEFINE_PROP_STRING("dt-compatible", MachineState, dt_compatible),
> > > +    DEFINE_PROP_STRING("firmware", MachineState, firmware),
> > > +    DEFINE_PROP_STRING("memory-backend", MachineState, ram_memdev_id),
> > > +    DEFINE_PROP_END_OF_LIST(),
> > > +};
> > > +
> >
> > While I think generalizing the _code_ for static properties is obviously
> > a good idea, I am not sure about generalizing the interface for adding them.
> >
> > The reason is that we already have a place for adding properties in
> > class_init, and having a second makes things "less local", so to speak.
> 
> As long as you have the function call to apply the properites array in
> .class_init, it should be obvious enough what you're doing.
> 
> Of course, I think we should refrain from mixing both styles in a single
> object, but generally speaking the array feels so much better that I
> don't think we should reject it just because QOM only had a different
> interface so far (and the property array is preexisting in qdev, too, so
> we already have differences between objects - in fact, the majority of
> objects is probably qdev today).

This is also a strong argument.  The QEMU code base has ~500
matches for "object*_property_add*" calls, and ~2100 for
"DEFINE_PROP*".

Converting qdev arrays to object_class_property_add_*() calls
would be a huge effort with no gains.  The end result would be
two different APIs for registering class field properties
coexisting for a long time, and people still confused on what's
the preferred API.

-- 
Eduardo



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 00/44] Make qdev static property API usable by any QOM type
  2020-11-06 15:50   ` Eduardo Habkost
@ 2020-11-06 21:10     ` Eduardo Habkost
  2020-11-08 14:05       ` Paolo Bonzini
  0 siblings, 1 reply; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-06 21:10 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Daniel P. Berrange, Philippe Mathieu-Daudé,
	qemu-devel, Markus Armbruster, Paolo Bonzini, Igor Mammedov,
	Marc-André Lureau, John Snow, Stefan Berger

On Fri, Nov 06, 2020 at 10:50:19AM -0500, Eduardo Habkost wrote:
> On Fri, Nov 06, 2020 at 10:45:11AM +0100, Kevin Wolf wrote:
> > Am 04.11.2020 um 16:59 hat Eduardo Habkost geschrieben:
> > > This series refactor the qdev property code so the static
> > > property system can be used by any QOM type.  As an example, at
> > > the end of the series some properties in TYPE_MACHINE are
> > > converted to static properties to demonstrate the new API.
> > > 
> > > Changes v1 -> v2
> > > ----------------
> > > 
> > > * Rename functions and source files to call the new feature
> > >   "field property" instead of "static property"
> > > 
> > > * Change the API signature from an array-based interface similar
> > >   to device_class_set_props() to a object_property_add()-like
> > >   interface.
> > > 
> > >   This means instead of doing this:
> > > 
> > >     object_class_property_add_static_props(oc, my_array_of_props);
> > > 
> > >   properties are registered like this:
> > > 
> > >     object_class_property_add_field(oc, "property-name"
> > >                                     PROP_XXX(MyState, my_field),
> > >                                     prop_allow_set_always);
> > > 
> > >   where PROP_XXX is a PROP_* macro like PROP_STRING, PROP_BOOL,
> > >   etc.
> > 
> > In comparison, I really like the resulting code from the array based
> > interface in v1 better.
> > 
> > I think it's mostly for two reasons: First, the array is much more
> > compact and easier to read. And maybe even more importantly, you know
> > it's static data and only static data. The function based interface can
> > be mixed with other code or the parameter list can contain calls to
> > other functions with side effects, so there are a lot more opportunities
> > for surprises.
> 
> This is a really good point, and I strongly agree with it.
> Letting code do funny tricks at runtime is one of the reasons QOM
> properties became hard to introspect.
> 
> > 
> > What I didn't like about the v1 interface is that there is still a
> > separate object_class_property_set_description() for each property, but
> > I think that could have been fixed by moving the description to the
> > definitions in the array, too.
> 
> This would be very easy to implement.

This was implemented at:
https://gitlab.com/ehabkost/qemu/-/commits/work/qdev-make-generic

This is the interface I'd like to submit as v3:

static Property machine_props[] = {
    DEFINE_PROP_STRING("kernel", MachineState, kernel_filename,
                       .description = "Linux kernel image file"),
    DEFINE_PROP_STRING("initrd", MachineState, initrd_filename,
                       .description = "Linux initial ramdisk file"),
    DEFINE_PROP_STRING("append", MachineState, kernel_cmdline,
                       .description = "Linux kernel command line"),
    DEFINE_PROP_STRING("dtb", MachineState, dtb,
                       .description = "Linux kernel device tree file"),
    DEFINE_PROP_STRING("dumpdtb", MachineState, dumpdtb,
                       .description = "Dump current dtb to a file and quit"),
    DEFINE_PROP_STRING("dt-compatible", MachineState, dt_compatible,
                       .description = "Overrides the \"compatible\" "
                                      "property of the dt root node"),
    DEFINE_PROP_STRING("firmware", MachineState, firmware,
                       .description = "Firmware image"),
    DEFINE_PROP_STRING("memory-backend", MachineState, ram_memdev_id,
                       .description = "ID of memory backend object"),
    DEFINE_PROP_BOOL("dump-guest-core", MachineState, dump_guest_core, true,
                     .description = "Include guest memory in a core dump"),
    DEFINE_PROP_BOOL("mem-merge", MachineState, mem_merge, true,
                     .description = "Enable/disable memory merge support"),
    DEFINE_PROP_BOOL("graphics", MachineState, enable_graphics, true,
                     .description = "Set on/off to enable/disable graphics emulation"),
    DEFINE_PROP_BOOL("suppress-vmdesc", MachineState, suppress_vmdesc, false,
                     .description = "Set on to disable self-describing migration"),
    DEFINE_PROP_UINT32("phandle-start", MachineState, phandle_start, 0,
                       .description = "The first phandle ID we may generate dynamically"),
    DEFINE_PROP_END_OF_LIST(),
};

static void machine_class_init(ObjectClass *oc, void *data)
{
    ...
    object_class_add_field_properties(oc, machine_props, prop_allow_set_always);
    ...
}



> 
> > 
> > On Fri, Oct 30, 2020 at 06:10:34PM +0100, Paolo Bonzini wrote:
> > > On 29/10/20 23:02, Eduardo Habkost wrote:
> > > > +static Property machine_props[] = {
> > > > +    DEFINE_PROP_STRING("kernel", MachineState, kernel_filename),
> > > > +    DEFINE_PROP_STRING("initrd", MachineState, initrd_filename),
> > > > +    DEFINE_PROP_STRING("append", MachineState, kernel_cmdline),
> > > > +    DEFINE_PROP_STRING("dtb", MachineState, dtb),
> > > > +    DEFINE_PROP_STRING("dumpdtb", MachineState, dumpdtb),
> > > > +    DEFINE_PROP_STRING("dt-compatible", MachineState, dt_compatible),
> > > > +    DEFINE_PROP_STRING("firmware", MachineState, firmware),
> > > > +    DEFINE_PROP_STRING("memory-backend", MachineState, ram_memdev_id),
> > > > +    DEFINE_PROP_END_OF_LIST(),
> > > > +};
> > > > +
> > >
> > > While I think generalizing the _code_ for static properties is obviously
> > > a good idea, I am not sure about generalizing the interface for adding them.
> > >
> > > The reason is that we already have a place for adding properties in
> > > class_init, and having a second makes things "less local", so to speak.
> > 
> > As long as you have the function call to apply the properites array in
> > .class_init, it should be obvious enough what you're doing.
> > 
> > Of course, I think we should refrain from mixing both styles in a single
> > object, but generally speaking the array feels so much better that I
> > don't think we should reject it just because QOM only had a different
> > interface so far (and the property array is preexisting in qdev, too, so
> > we already have differences between objects - in fact, the majority of
> > objects is probably qdev today).
> 
> This is also a strong argument.  The QEMU code base has ~500
> matches for "object*_property_add*" calls, and ~2100 for
> "DEFINE_PROP*".
> 
> Converting qdev arrays to object_class_property_add_*() calls
> would be a huge effort with no gains.  The end result would be
> two different APIs for registering class field properties
> coexisting for a long time, and people still confused on what's
> the preferred API.
> 
> -- 
> Eduardo

-- 
Eduardo



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 00/44] Make qdev static property API usable by any QOM type
  2020-11-06 21:10     ` Eduardo Habkost
@ 2020-11-08 14:05       ` Paolo Bonzini
  2020-11-09 11:34         ` Kevin Wolf
  0 siblings, 1 reply; 77+ messages in thread
From: Paolo Bonzini @ 2020-11-08 14:05 UTC (permalink / raw)
  To: Eduardo Habkost, Kevin Wolf
  Cc: Daniel P. Berrange, Philippe Mathieu-Daudé,
	qemu-devel, Markus Armbruster, Igor Mammedov,
	Marc-André Lureau, John Snow, Stefan Berger

On 06/11/20 22:10, Eduardo Habkost wrote:
> This was implemented at:
> https://gitlab.com/ehabkost/qemu/-/commits/work/qdev-make-generic
> 
> This is the interface I'd like to submit as v3:
> 
> static Property machine_props[] = {
>      DEFINE_PROP_STRING("kernel", MachineState, kernel_filename,
>                         .description = "Linux kernel image file"),
>      DEFINE_PROP_STRING("initrd", MachineState, initrd_filename,
>                         .description = "Linux initial ramdisk file"),
>      DEFINE_PROP_STRING("append", MachineState, kernel_cmdline,
>                         .description = "Linux kernel command line"),
>      DEFINE_PROP_STRING("dtb", MachineState, dtb,
>                         .description = "Linux kernel device tree file"),
>      DEFINE_PROP_STRING("dumpdtb", MachineState, dumpdtb,
>                         .description = "Dump current dtb to a file and quit"),
>      DEFINE_PROP_STRING("dt-compatible", MachineState, dt_compatible,
>                         .description = "Overrides the \"compatible\" "
>                                        "property of the dt root node"),
>      DEFINE_PROP_STRING("firmware", MachineState, firmware,
>                         .description = "Firmware image"),
>      DEFINE_PROP_STRING("memory-backend", MachineState, ram_memdev_id,
>                         .description = "ID of memory backend object"),
>      DEFINE_PROP_BOOL("dump-guest-core", MachineState, dump_guest_core, true,
>                       .description = "Include guest memory in a core dump"),
>      DEFINE_PROP_BOOL("mem-merge", MachineState, mem_merge, true,
>                       .description = "Enable/disable memory merge support"),
>      DEFINE_PROP_BOOL("graphics", MachineState, enable_graphics, true,
>                       .description = "Set on/off to enable/disable graphics emulation"),
>      DEFINE_PROP_BOOL("suppress-vmdesc", MachineState, suppress_vmdesc, false,
>                       .description = "Set on to disable self-describing migration"),
>      DEFINE_PROP_UINT32("phandle-start", MachineState, phandle_start, 0,
>                         .description = "The first phandle ID we may generate dynamically"),
>      DEFINE_PROP_END_OF_LIST(),
> };
> 
> static void machine_class_init(ObjectClass *oc, void *data)
> {
>      ...
>      object_class_add_field_properties(oc, machine_props, prop_allow_set_always);
>      ...
> }

If all properties were like this, it would be okay.  But the API in v2 
is the one that is most consistent with QOM in general. Here is how this 
change would be a loss in term of consistency:

- you have the field properties split in two (with the property itself 
in one place and the allow-set function in a different place), and also 
you'd have some properties listed as array and some as function calls.

- we would have different ways to handle device field properties (with 
dc->props) compared to object properties.

- while it's true that the QEMU code base has ~500 matches for 
"object*_property_add*" calls, and ~2100 for "DEFINE_PROP*", the new 
field properties would pretty much be used only in places that use 
object_class_property_add*.  (And converting DEFINE_PROP* to PROP* would 
be relatively easy to script, unlike having an array-based definition 
for all uses of object_class_property*).

The choice to describe class properties as function calls was made in 
2016 (commit 16bf7f522a, "qom: Allow properties to be registered against 
classes", 2016-01-18); so far I don't see that it has been misused.

Also, I don't think it's any easier to write an introspection code 
generator with DEFINE_PROP_*.  You would still have to parse the class 
init function to find the reference to the array (and likewise the 
TypeInfo struct to find the class init function).

Paolo



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 00/44] Make qdev static property API usable by any QOM type
  2020-11-08 14:05       ` Paolo Bonzini
@ 2020-11-09 11:34         ` Kevin Wolf
  2020-11-09 14:15           ` Paolo Bonzini
  0 siblings, 1 reply; 77+ messages in thread
From: Kevin Wolf @ 2020-11-09 11:34 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Daniel P. Berrange, Eduardo Habkost, Philippe Mathieu-Daudé,
	Markus Armbruster, qemu-devel, Igor Mammedov,
	Marc-André Lureau, John Snow, Stefan Berger

Am 08.11.2020 um 15:05 hat Paolo Bonzini geschrieben:
> On 06/11/20 22:10, Eduardo Habkost wrote:
> > This was implemented at:
> > https://gitlab.com/ehabkost/qemu/-/commits/work/qdev-make-generic
> > 
> > This is the interface I'd like to submit as v3:
> > 
> > static Property machine_props[] = {
> >      DEFINE_PROP_STRING("kernel", MachineState, kernel_filename,
> >                         .description = "Linux kernel image file"),
> >      DEFINE_PROP_STRING("initrd", MachineState, initrd_filename,
> >                         .description = "Linux initial ramdisk file"),
> >      DEFINE_PROP_STRING("append", MachineState, kernel_cmdline,
> >                         .description = "Linux kernel command line"),
> >      DEFINE_PROP_STRING("dtb", MachineState, dtb,
> >                         .description = "Linux kernel device tree file"),
> >      DEFINE_PROP_STRING("dumpdtb", MachineState, dumpdtb,
> >                         .description = "Dump current dtb to a file and quit"),
> >      DEFINE_PROP_STRING("dt-compatible", MachineState, dt_compatible,
> >                         .description = "Overrides the \"compatible\" "
> >                                        "property of the dt root node"),
> >      DEFINE_PROP_STRING("firmware", MachineState, firmware,
> >                         .description = "Firmware image"),
> >      DEFINE_PROP_STRING("memory-backend", MachineState, ram_memdev_id,
> >                         .description = "ID of memory backend object"),
> >      DEFINE_PROP_BOOL("dump-guest-core", MachineState, dump_guest_core, true,
> >                       .description = "Include guest memory in a core dump"),
> >      DEFINE_PROP_BOOL("mem-merge", MachineState, mem_merge, true,
> >                       .description = "Enable/disable memory merge support"),
> >      DEFINE_PROP_BOOL("graphics", MachineState, enable_graphics, true,
> >                       .description = "Set on/off to enable/disable graphics emulation"),
> >      DEFINE_PROP_BOOL("suppress-vmdesc", MachineState, suppress_vmdesc, false,
> >                       .description = "Set on to disable self-describing migration"),
> >      DEFINE_PROP_UINT32("phandle-start", MachineState, phandle_start, 0,
> >                         .description = "The first phandle ID we may generate dynamically"),
> >      DEFINE_PROP_END_OF_LIST(),
> > };
> > 
> > static void machine_class_init(ObjectClass *oc, void *data)
> > {
> >      ...
> >      object_class_add_field_properties(oc, machine_props, prop_allow_set_always);
> >      ...
> > }
> 
> If all properties were like this, it would be okay.  But the API in v2 is
> the one that is most consistent with QOM in general. Here is how this change
> would be a loss in term of consistency:
> 
> - you have the field properties split in two (with the property itself in
> one place and the allow-set function in a different place), and also you'd
> have some properties listed as array and some as function calls.

Why would you have properties defined as function calls for the same
object that uses the array?

I'm not entirely sure what you mean with allow-set. The only things I
can find are related to link properties, specifically the check()
callback of object_class_property_add_link(). If it's this, what would
be the problem with just adding it to DEFINE_PROP_LINK instead of
using a separate function call to define link properties?

> - we would have different ways to handle device field properties (with
> dc->props) compared to object properties.

You mean dynamic per-object properties, i.e. not class properties?

I think having different ways for different things (class vs. object) is
better than having different ways for the same things (class in qdev vs.
class in non-qdev).

> - while it's true that the QEMU code base has ~500 matches for
> "object*_property_add*" calls, and ~2100 for "DEFINE_PROP*", the new field
> properties would pretty much be used only in places that use
> object_class_property_add*.  (And converting DEFINE_PROP* to PROP* would be
> relatively easy to script, unlike having an array-based definition for all
> uses of object_class_property*).
> 
> The choice to describe class properties as function calls was made in 2016
> (commit 16bf7f522a, "qom: Allow properties to be registered against
> classes", 2016-01-18); so far I don't see that it has been misused.

This was the obvious incremental step forward at the time because you
just had to replace one function call with another function call. The
commit message doesn't explain that not using data was a conscious
decision. I think it would probably have been out of scope then.

> Also, I don't think it's any easier to write an introspection code generator
> with DEFINE_PROP_*.  You would still have to parse the class init function
> to find the reference to the array (and likewise the TypeInfo struct to find
> the class init function).

I don't think we should parse any C code. In my opinion, both
introspection and the array should eventually be generated by the QAPI
generator from the schema.

Kevin



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 00/44] Make qdev static property API usable by any QOM type
  2020-11-09 11:34         ` Kevin Wolf
@ 2020-11-09 14:15           ` Paolo Bonzini
  2020-11-09 15:21             ` Eduardo Habkost
  0 siblings, 1 reply; 77+ messages in thread
From: Paolo Bonzini @ 2020-11-09 14:15 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Daniel P. Berrange, Eduardo Habkost, Philippe Mathieu-Daudé,
	Markus Armbruster, qemu-devel, Igor Mammedov,
	Marc-André Lureau, John Snow, Stefan Berger

On 09/11/20 12:34, Kevin Wolf wrote:
>> If all properties were like this, it would be okay.  But the API in v2 is
>> the one that is most consistent with QOM in general. Here is how this change
>> would be a loss in term of consistency:
>>
>> - you have the field properties split in two (with the property itself in
>> one place and the allow-set function in a different place), and also you'd
>> have some properties listed as array and some as function calls.
> 
> Why would you have properties defined as function calls for the same
> object that uses the array?

Because some properties would not be field properties, for example.  For 
example, any non-scalar property would need to invoke 
visit_SomeQapiStruct manually and would not be a field property.

> I'm not entirely sure what you mean with allow-set. The only things I
> can find are related to link properties, specifically the check()
> callback of object_class_property_add_link(). If it's this, what would
> be the problem with just adding it to DEFINE_PROP_LINK instead of
> using a separate function call to define link properties?

Eduardo's series is adding allow-set functions to field properties as 
well.  If it's be specified in the function call to 
object_class_add_field_properties, you'd have part of the property 
described in the array and part in the object_class_add_field_properties.

>> - we would have different ways to handle device field properties (with
>> dc->props) compared to object properties.
> 
> You mean dynamic per-object properties, i.e. not class properties?

No, I mean that device properties would be handled as

    dc->props = foo;

while object properties would be handled as

    object_class_add_field_properties(oc, foo, prop_allow_set_always);

There would be two different preferred ways to do field properties in 
qdev vs. non-qdev.

> I think having different ways for different things (class vs. object) is
> better than having different ways for the same things (class in qdev vs.
> class in non-qdev).

Right, but qdev's DEFINE_PROP_STRING would be easy to change to 
something like

- DEFINE_PROP_STRING("name", ...),
+ device_class_add_field_property(dc, "name", PROP_STRING(...));

>> The choice to describe class properties as function calls was made in 2016
>> (commit 16bf7f522a, "qom: Allow properties to be registered against
>> classes", 2016-01-18); so far I don't see that it has been misused.
> 
> This was the obvious incremental step forward at the time because you
> just had to replace one function call with another function call. The
> commit message doesn't explain that not using data was a conscious
> decision. I think it would probably have been out of scope then.
> 
>> Also, I don't think it's any easier to write an introspection code generator
>> with DEFINE_PROP_*.  You would still have to parse the class init function
>> to find the reference to the array (and likewise the TypeInfo struct to find
>> the class init function).
> 
> I don't think we should parse any C code. In my opinion, both
> introspection and the array should eventually be generated by the QAPI
> generator from the schema.

That'd be a good plan, and I'd add generating the property description 
from the doc comment.  (Though there's still the issue of how to add 
non-field properties to the introspection.  Those would be harder to 
move to the QAPI generator).

But at that point the array vs. function call would not change anything 
(if anything the function call would be a tiny bit better), so that's 
another reason to stay with the API that Eduardo has in v2.

Paolo



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 00/44] Make qdev static property API usable by any QOM type
  2020-11-09 14:15           ` Paolo Bonzini
@ 2020-11-09 15:21             ` Eduardo Habkost
  2020-11-09 16:34               ` Paolo Bonzini
  0 siblings, 1 reply; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-09 15:21 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Kevin Wolf, Daniel P. Berrange, Philippe Mathieu-Daudé,
	qemu-devel, Markus Armbruster, Igor Mammedov,
	Marc-André Lureau, John Snow, Stefan Berger

On Mon, Nov 09, 2020 at 03:15:26PM +0100, Paolo Bonzini wrote:
> On 09/11/20 12:34, Kevin Wolf wrote:
> > > If all properties were like this, it would be okay.  But the API in v2 is
> > > the one that is most consistent with QOM in general. Here is how this change
> > > would be a loss in term of consistency:
> > > 
> > > - you have the field properties split in two (with the property itself in
> > > one place and the allow-set function in a different place), and also you'd
> > > have some properties listed as array and some as function calls.
> > 
> > Why would you have properties defined as function calls for the same
> > object that uses the array?
> 
> Because some properties would not be field properties, for example.  For
> example, any non-scalar property would need to invoke visit_SomeQapiStruct
> manually and would not be a field property.

Nothing prevents us from describing those properties inside the
same property array.

> 
> > I'm not entirely sure what you mean with allow-set. The only things I
> > can find are related to link properties, specifically the check()
> > callback of object_class_property_add_link(). If it's this, what would
> > be the problem with just adding it to DEFINE_PROP_LINK instead of
> > using a separate function call to define link properties?
> 
> Eduardo's series is adding allow-set functions to field properties as well.
> If it's be specified in the function call to
> object_class_add_field_properties, you'd have part of the property described
> in the array and part in the object_class_add_field_properties.
> 
> > > - we would have different ways to handle device field properties (with
> > > dc->props) compared to object properties.
> > 
> > You mean dynamic per-object properties, i.e. not class properties?
> 
> No, I mean that device properties would be handled as
> 
>    dc->props = foo;

More precisely, it is
  device_class_set_props(dc, foo);

which is supposed to become a one-line wrapper to
object_class_add_field_properties().

> 
> while object properties would be handled as
> 
>    object_class_add_field_properties(oc, foo, prop_allow_set_always);
> 
> There would be two different preferred ways to do field properties in qdev
> vs. non-qdev.

They should become exactly the same method, just with a different
allow_set function.

(There's also the possibility we let the class provide a default
allow_set function, and both would become 100% the same)

> 
> > I think having different ways for different things (class vs. object) is
> > better than having different ways for the same things (class in qdev vs.
> > class in non-qdev).
> 
> Right, but qdev's DEFINE_PROP_STRING would be easy to change to something
> like
> 
> - DEFINE_PROP_STRING("name", ...),
> + device_class_add_field_property(dc, "name", PROP_STRING(...));

I'm not worried about this direction of conversion (which is
easy).  I'm worried about the function call => QAPI schema
conversion.  Function calls are too flexible and requires parsing
and executing C code.  Requiring all property descriptions to be
evaluated at compilation time is an intentional feature of the
new API.

> 
> > > The choice to describe class properties as function calls was made in 2016
> > > (commit 16bf7f522a, "qom: Allow properties to be registered against
> > > classes", 2016-01-18); so far I don't see that it has been misused.
> > 
> > This was the obvious incremental step forward at the time because you
> > just had to replace one function call with another function call. The
> > commit message doesn't explain that not using data was a conscious
> > decision. I think it would probably have been out of scope then.
> > 
> > > Also, I don't think it's any easier to write an introspection code generator
> > > with DEFINE_PROP_*.  You would still have to parse the class init function
> > > to find the reference to the array (and likewise the TypeInfo struct to find
> > > the class init function).
> > 
> > I don't think we should parse any C code. In my opinion, both
> > introspection and the array should eventually be generated by the QAPI
> > generator from the schema.
> 
> That'd be a good plan, and I'd add generating the property description from
> the doc comment.  (Though there's still the issue of how to add non-field
> properties to the introspection.  Those would be harder to move to the QAPI
> generator).
> 
> But at that point the array vs. function call would not change anything (if
> anything the function call would be a tiny bit better), so that's another
> reason to stay with the API that Eduardo has in v2.

I don't agree the function call is a tiny bit better.  In the
best case, I find it a tiny bit worse.

-- 
Eduardo



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 00/44] Make qdev static property API usable by any QOM type
  2020-11-09 15:21             ` Eduardo Habkost
@ 2020-11-09 16:34               ` Paolo Bonzini
  2020-11-09 17:16                 ` Eduardo Habkost
  0 siblings, 1 reply; 77+ messages in thread
From: Paolo Bonzini @ 2020-11-09 16:34 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: Kevin Wolf, Daniel P. Berrange, Philippe Mathieu-Daudé,
	qemu-devel, Markus Armbruster, Igor Mammedov,
	Marc-André Lureau, John Snow, Stefan Berger

On 09/11/20 16:21, Eduardo Habkost wrote:
> On Mon, Nov 09, 2020 at 03:15:26PM +0100, Paolo Bonzini wrote:
>> On 09/11/20 12:34, Kevin Wolf wrote:
>>>> If all properties were like this, it would be okay.  But the API in v2 is
>>>> the one that is most consistent with QOM in general. Here is how this change
>>>> would be a loss in term of consistency:
>>>>
>>>> - you have the field properties split in two (with the property itself in
>>>> one place and the allow-set function in a different place), and also you'd
>>>> have some properties listed as array and some as function calls.
>>>
>>> Why would you have properties defined as function calls for the same
>>> object that uses the array?
>>
>> Because some properties would not be field properties, for example.  For
>> example, any non-scalar property would need to invoke visit_SomeQapiStruct
>> manually and would not be a field property.
> 
> Nothing prevents us from describing those properties inside the
> same property array.

Do you mean adding PropertyInfos for them?  Adding a once-only 
PropertyInfo is worse than writing a custom getter/setter pair, because:

- without (DEFINE_)PROP_* you lose the type safety.

- with (DEFINE_)PROP_* you have much more boilerplate to write

> More precisely, it is
>    device_class_set_props(dc, foo);
> 
> which is supposed to become a one-line wrapper to
> object_class_add_field_properties().

You're right, I'm a few years late.  So that objection is withdrawn.

> (There's also the possibility we let the class provide a default
> allow_set function, and both would become 100% the same)

That's a possibility too.  Though if we ever have a need for multiple 
allow_set functions it would be somewhat complicated to add it back.

Instead of class-wide allow_set, we might as well have a "bool 
constructed" field in Object and remove the function pointer altogether: 
just replace prop->allow_set(obj) with just "!obj->constructed".

>>> I think having different ways for different things (class vs. object) is
>>> better than having different ways for the same things (class in qdev vs.
>>> class in non-qdev).
>>
>> Right, but qdev's DEFINE_PROP_STRING would be easy to change to something
>> like
>>
>> - DEFINE_PROP_STRING("name", ...),
>> + device_class_add_field_property(dc, "name", PROP_STRING(...));
> 
> I'm not worried about this direction of conversion (which is
> easy).  I'm worried about the function call => QAPI schema
> conversion.  Function calls are too flexible and requires parsing
> and executing C code.

Converting DEFINE_PROP_STRING to a schema also requires parsing C code, 
since you can have handwritten Property literals (especially for custom 
PropertyInfo).  Converting DEFINE_PROP_STRING it also requires matching 
the array against calls to object_class_add_field_properties (which 
could be hidden behind helpers such as device_class_set_props).  (Plus 
matching class_init functions against TypeInfo).

So, you don't save any parsing by using arrays.  (In fact I would 
probably skip the parsing, and use your suggestion of *executing* C 
code: write the QAPI schema generator in C, link into QEMU and run it 
just once to generate the QOM schema).

QOM has been using function calls for many years, are there any cases of 
misuse of that flexibility that you have in mind?  I can only think of 
two *uses*, in fact.  One is eepro100_register_types is the only case I 
can remember where types are registered dynamically.  The other is S390 
CPU features.  In fact,

   $ git grep \ object_class_property_add|grep -v '([a-z0-9_]*, \"'

shows some cases where property names are macros (an mst-ism :), but no 
other case where properties are being defined dynamically.

Paolo



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 00/44] Make qdev static property API usable by any QOM type
  2020-11-09 16:34               ` Paolo Bonzini
@ 2020-11-09 17:16                 ` Eduardo Habkost
  2020-11-09 17:33                   ` Paolo Bonzini
  0 siblings, 1 reply; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-09 17:16 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Kevin Wolf, Daniel P. Berrange, Philippe Mathieu-Daudé,
	qemu-devel, Markus Armbruster, Igor Mammedov,
	Marc-André Lureau, John Snow, Stefan Berger

On Mon, Nov 09, 2020 at 05:34:01PM +0100, Paolo Bonzini wrote:
> On 09/11/20 16:21, Eduardo Habkost wrote:
> > On Mon, Nov 09, 2020 at 03:15:26PM +0100, Paolo Bonzini wrote:
> > > On 09/11/20 12:34, Kevin Wolf wrote:
> > > > > If all properties were like this, it would be okay.  But the API in v2 is
> > > > > the one that is most consistent with QOM in general. Here is how this change
> > > > > would be a loss in term of consistency:
> > > > > 
> > > > > - you have the field properties split in two (with the property itself in
> > > > > one place and the allow-set function in a different place), and also you'd
> > > > > have some properties listed as array and some as function calls.
> > > > 
> > > > Why would you have properties defined as function calls for the same
> > > > object that uses the array?
> > > 
> > > Because some properties would not be field properties, for example.  For
> > > example, any non-scalar property would need to invoke visit_SomeQapiStruct
> > > manually and would not be a field property.
> > 
> > Nothing prevents us from describing those properties inside the
> > same property array.
> 
> Do you mean adding PropertyInfos for them?  Adding a once-only PropertyInfo
> is worse than writing a custom getter/setter pair, because:
> 
> - without (DEFINE_)PROP_* you lose the type safety.
> 
> - with (DEFINE_)PROP_* you have much more boilerplate to write

I mean extending the API to let custom setters and getters appear
on the Property array, not using the existing API.

> 
> > More precisely, it is
> >    device_class_set_props(dc, foo);
> > 
> > which is supposed to become a one-line wrapper to
> > object_class_add_field_properties().
> 
> You're right, I'm a few years late.  So that objection is withdrawn.
> 
> > (There's also the possibility we let the class provide a default
> > allow_set function, and both would become 100% the same)
> 
> That's a possibility too.  Though if we ever have a need for multiple
> allow_set functions it would be somewhat complicated to add it back.
> 
> Instead of class-wide allow_set, we might as well have a "bool constructed"
> field in Object and remove the function pointer altogether: just replace
> prop->allow_set(obj) with just "!obj->constructed".

That's a possibility, and maybe that could be the default
allow_set behavior.  It may be a bit tricky to convert the
existing backend objects to the new behavior in a gradual way,
though.

> 
> > > > I think having different ways for different things (class vs. object) is
> > > > better than having different ways for the same things (class in qdev vs.
> > > > class in non-qdev).
> > > 
> > > Right, but qdev's DEFINE_PROP_STRING would be easy to change to something
> > > like
> > > 
> > > - DEFINE_PROP_STRING("name", ...),
> > > + device_class_add_field_property(dc, "name", PROP_STRING(...));
> > 
> > I'm not worried about this direction of conversion (which is
> > easy).  I'm worried about the function call => QAPI schema
> > conversion.  Function calls are too flexible and requires parsing
> > and executing C code.
> 
> Converting DEFINE_PROP_STRING to a schema also requires parsing C code,
> since you can have handwritten Property literals (especially for custom
> PropertyInfo).  Converting DEFINE_PROP_STRING it also requires matching the
> array against calls to object_class_add_field_properties (which could be
> hidden behind helpers such as device_class_set_props).  (Plus matching
> class_init functions against TypeInfo).

Parsing an array containing a handful of macros (a tiny subset of
C) isn't even comparable to parsing and executing C code where
object*_property_add*() calls can be buried deep in many levels
of C function calls (which may or may not be conditional).

(Also, I don't think we should allow handwritten Property literals.)

> 
> So, you don't save any parsing by using arrays.  (In fact I would probably
> skip the parsing, and use your suggestion of *executing* C code: write the
> QAPI schema generator in C, link into QEMU and run it just once to generate
> the QOM schema).

If we do that with the existing code, we can't be sure the
generated schema doesn't depend on configure flags or run time
checks inside class_init.  Even locating the cases where this is
happening is being a challenge because the API is too flexible.

However, if we require the property list to be always evaluated
at compile time, we can be sure that this method will be
reliable.

> 
> QOM has been using function calls for many years, are there any cases of
> misuse of that flexibility that you have in mind?  I can only think of two
> *uses*, in fact.  One is eepro100_register_types is the only case I can
> remember where types are registered dynamically.  The other is S390 CPU
> features.  [...]

The list of tricky dynamic properties is large and I don't think
we even found all cases yet.  John documented many of them here:

https://gitlab.com/jsnow/qemu/-/blob/cli_audit/docs/cli_audit.md

Look, for example, for the sections named "Features" for CPU
options.


>     [...]  In fact,
> 
>   $ git grep \ object_class_property_add|grep -v '([a-z0-9_]*, \"'
> 
> shows some cases where property names are macros (an mst-ism :), but no
> other case where properties are being defined dynamically.

You are excluding instance-level object_property_add*() calls.
Most of them are supposed to be class properties but were never
converted.

You are also ignoring the complexity of the code path that leads
to the object*_property_add*() calls, which is the main problem
on most cases.

-- 
Eduardo



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 00/44] Make qdev static property API usable by any QOM type
  2020-11-09 17:16                 ` Eduardo Habkost
@ 2020-11-09 17:33                   ` Paolo Bonzini
  2020-11-09 18:55                     ` Eduardo Habkost
  0 siblings, 1 reply; 77+ messages in thread
From: Paolo Bonzini @ 2020-11-09 17:33 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: Kevin Wolf, Daniel P. Berrange, Philippe Mathieu-Daudé,
	qemu-devel, Markus Armbruster, Igor Mammedov,
	Marc-André Lureau, John Snow, Stefan Berger

On 09/11/20 18:16, Eduardo Habkost wrote:
> On Mon, Nov 09, 2020 at 05:34:01PM +0100, Paolo Bonzini wrote:
>> On 09/11/20 16:21, Eduardo Habkost wrote:
>>> Nothing prevents us from describing those properties inside the
>>> same property array.
>>
>> Do you mean adding PropertyInfos for them?  Adding a once-only PropertyInfo
>> is worse than writing a custom getter/setter pair, because:
>>
>> - without (DEFINE_)PROP_* you lose the type safety.
>>
>> - with (DEFINE_)PROP_* you have much more boilerplate to write
> 
> I mean extending the API to let custom setters and getters appear
> on the Property array, not using the existing API.

That seems like conflicting goals.  The field property API is based on 
getters and setters hidden in PropertyInfo.  The "other" property API is 
based on getters and setters in plain sight in the declaration of the 
property.

>>>>> I think having different ways for different things (class vs. object) is
>>>>> better than having different ways for the same things (class in qdev vs.
>>>>> class in non-qdev).
>>>>
>>>> Right, but qdev's DEFINE_PROP_STRING would be easy to change to something
>>>> like
>>>>
>>>> - DEFINE_PROP_STRING("name", ...),
>>>> + device_class_add_field_property(dc, "name", PROP_STRING(...));
>>>
>>> I'm not worried about this direction of conversion (which is
>>> easy).  I'm worried about the function call => QAPI schema
>>> conversion.  Function calls are too flexible and requires parsing
>>> and executing C code.
>>
>> Converting DEFINE_PROP_STRING to a schema also requires parsing C code,
>> since you can have handwritten Property literals (especially for custom
>> PropertyInfo).  Converting DEFINE_PROP_STRING it also requires matching the
>> array against calls to object_class_add_field_properties (which could be
>> hidden behind helpers such as device_class_set_props).  (Plus matching
>> class_init functions against TypeInfo).
> 
> Parsing an array containing a handful of macros (a tiny subset of
> C) isn't even comparable to parsing and executing C code where
> object*_property_add*() calls can be buried deep in many levels
> of C function calls (which may or may not be conditional).

Finding the array would also require finding calls buried deep in C 
code, wouldn't they?

> (Also, I don't think we should allow handwritten Property literals.)

How would you do custom setters and getters then---without separate 
PropertyInfos, without Property literals, and without an exploding 
number of macros?

>> So, you don't save any parsing by using arrays.  (In fact I would probably
>> skip the parsing, and use your suggestion of *executing* C code: write the
>> QAPI schema generator in C, link into QEMU and run it just once to generate
>> the QOM schema).
> 
> If we do that with the existing code, we can't be sure the
> generated schema doesn't depend on configure flags or run time
> checks inside class_init.

We can use grep or Coccinelle or manual code review to identify 
problematic cases.

> Even locating the cases where this is
> happening is being a challenge because the API is too flexible.
> 
> However, if we require the property list to be always evaluated
> at compile time, we can be sure that this method will be
> reliable.
> 
>> QOM has been using function calls for many years, are there any cases of
>> misuse of that flexibility that you have in mind?  I can only think of two
>> *uses*, in fact.  One is eepro100_register_types is the only case I can
>> remember where types are registered dynamically.  The other is S390 CPU
>> features.  [...]
> 
> The list of tricky dynamic properties is large and I don't think
> we even found all cases yet.  John documented many of them here:
> 
> https://gitlab.com/jsnow/qemu/-/blob/cli_audit/docs/cli_audit.md
> 
> Look, for example, for the sections named "Features" for CPU
> options.

Yes, I'm only considering object_class_property calls.  Those are the 
ones that I claim aren't being misused enough for this to be a problem.

Making instance-level properties appear in the schema is a completely 
different kind of conversion, because there is plenty of manual work 
(and unsolved problems for e.g. subobject property aliases).

> You are also ignoring the complexity of the code path that leads
> to the object*_property_add*() calls, which is the main problem
> on most cases.

I would like an example of the complexity of those code paths.  I don't 
see much complexity, as long as the object exists at all, and I don't 
see how it would be simpler to find the code paths that lead to 
object_class_add_field_properties.

Paolo



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 00/44] Make qdev static property API usable by any QOM type
  2020-11-09 17:33                   ` Paolo Bonzini
@ 2020-11-09 18:55                     ` Eduardo Habkost
  2020-11-09 19:27                       ` Paolo Bonzini
  0 siblings, 1 reply; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-09 18:55 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Kevin Wolf, Daniel P. Berrange, Philippe Mathieu-Daudé,
	qemu-devel, Markus Armbruster, Igor Mammedov,
	Marc-André Lureau, John Snow, Stefan Berger

On Mon, Nov 09, 2020 at 06:33:04PM +0100, Paolo Bonzini wrote:
> On 09/11/20 18:16, Eduardo Habkost wrote:
> > On Mon, Nov 09, 2020 at 05:34:01PM +0100, Paolo Bonzini wrote:
> > > On 09/11/20 16:21, Eduardo Habkost wrote:
> > > > Nothing prevents us from describing those properties inside the
> > > > same property array.
> > > 
> > > Do you mean adding PropertyInfos for them?  Adding a once-only PropertyInfo
> > > is worse than writing a custom getter/setter pair, because:
> > > 
> > > - without (DEFINE_)PROP_* you lose the type safety.
> > > 
> > > - with (DEFINE_)PROP_* you have much more boilerplate to write
> > 
> > I mean extending the API to let custom setters and getters appear
> > on the Property array, not using the existing API.
> 
> That seems like conflicting goals.  The field property API is based on
> getters and setters hidden in PropertyInfo.  The "other" property API is
> based on getters and setters in plain sight in the declaration of the
> property.

There's nothing that prevents a
  void object_class_add_properties(oc, Property *props);
function from supporting both.

> 
> > > > > > I think having different ways for different things (class vs. object) is
> > > > > > better than having different ways for the same things (class in qdev vs.
> > > > > > class in non-qdev).
> > > > > 
> > > > > Right, but qdev's DEFINE_PROP_STRING would be easy to change to something
> > > > > like
> > > > > 
> > > > > - DEFINE_PROP_STRING("name", ...),
> > > > > + device_class_add_field_property(dc, "name", PROP_STRING(...));
> > > > 
> > > > I'm not worried about this direction of conversion (which is
> > > > easy).  I'm worried about the function call => QAPI schema
> > > > conversion.  Function calls are too flexible and requires parsing
> > > > and executing C code.
> > > 
> > > Converting DEFINE_PROP_STRING to a schema also requires parsing C code,
> > > since you can have handwritten Property literals (especially for custom
> > > PropertyInfo).  Converting DEFINE_PROP_STRING it also requires matching the
> > > array against calls to object_class_add_field_properties (which could be
> > > hidden behind helpers such as device_class_set_props).  (Plus matching
> > > class_init functions against TypeInfo).
> > 
> > Parsing an array containing a handful of macros (a tiny subset of
> > C) isn't even comparable to parsing and executing C code where
> > object*_property_add*() calls can be buried deep in many levels
> > of C function calls (which may or may not be conditional).
> 
> Finding the array would also require finding calls buried deep in C code,
> wouldn't they?

Yes, but I don't expect this to happen if the API doesn't
encourage that.

> 
> > (Also, I don't think we should allow handwritten Property literals.)
> 
> How would you do custom setters and getters then---without separate
> PropertyInfos, without Property literals, and without an exploding number of
> macros?

Property with struct field:

  /* We call this DEFINE_PROP_UINT32 today.  We can keep the
   * existing name just to reduce churn.
   */
  DEFINE_PROP_UINT32_FIELD("myproperty", MyState, my_field)


Prop with struct field but custom setter:

  DEFINE_PROP_UINT32_FIELD("myproperty", MyState, my_field,
                           .custom_setter = my_custom_setter)

Prop with no struct field, and custom setter/getter:

  DEFINE_PROP("myproperty", prop_type_uint32,
              .custom_getter = my_getter,
              .custom_setter = my_setter)


Definitions for above:

#define DEFINE_PROP(_name, _typeinfo, ...) \
    { .name = _name,
      .info = &_typeinfo,
      __VA_ARGS__
    }

#define DEFINE_FIELD_PROP(name, typeinfo, type, state, field, ...) \
    DEFINE_PROP(name, typeinfo,
                .offset = offsetof(state, field) +
                          type_check(typeof_field(state, field), type),
                __VA_ARGS__)

#define DEFINE_PROP_UINT32_FIELD(name, state, field, ...) \
    DEFINE_FIELD_PROP(name, prop_type_uint32, uint32_t, state, field, __VA_ARGS__)


Alternative DEFINE_FIELD_PROP definition if we implement some
macro magic to declare the expected type for each typeinfo
variable:

/* Will make ACTUAL_C_TYPE(prop_type_uint32) expand to uint32_t */
DECLARE_QOM_TYPE(prop_type_uint32, uint32_t)
/* Will make ACTUAL_C_TYPE(prop_type_uint64) expand to uint64_t) 
DECLARE_QOM_TYPE(prop_type_uint64, uint64_t)

#define DEFINE_FIELD_PROP(name, typeinfo, state, field, ...) \
    DEFINE_PROP(name, typeinfo,
                .offset = offsetof(state, field) +
                          type_check(typeof_field(state, field),
                                     ACTUAL_C_TYPE(typeinfo)),
                __VA_ARGS__)


> 
> > > So, you don't save any parsing by using arrays.  (In fact I would probably
> > > skip the parsing, and use your suggestion of *executing* C code: write the
> > > QAPI schema generator in C, link into QEMU and run it just once to generate
> > > the QOM schema).
> > 
> > If we do that with the existing code, we can't be sure the
> > generated schema doesn't depend on configure flags or run time
> > checks inside class_init.
> 
> We can use grep or Coccinelle or manual code review to identify problematic
> cases.

We can, but I believe it is better and simpler to have an API
that enforces (or at least encourages) this.

> 
> > Even locating the cases where this is
> > happening is being a challenge because the API is too flexible.
> > 
> > However, if we require the property list to be always evaluated
> > at compile time, we can be sure that this method will be
> > reliable.
> > 
> > > QOM has been using function calls for many years, are there any cases of
> > > misuse of that flexibility that you have in mind?  I can only think of two
> > > *uses*, in fact.  One is eepro100_register_types is the only case I can
> > > remember where types are registered dynamically.  The other is S390 CPU
> > > features.  [...]
> > 
> > The list of tricky dynamic properties is large and I don't think
> > we even found all cases yet.  John documented many of them here:
> > 
> > https://gitlab.com/jsnow/qemu/-/blob/cli_audit/docs/cli_audit.md
> > 
> > Look, for example, for the sections named "Features" for CPU
> > options.
> 
> Yes, I'm only considering object_class_property calls.  Those are the ones
> that I claim aren't being misused enough for this to be a problem.
> 

instance-level properties are where most of the complexity was
introduced because the class API didn't exist yet.  I don't think
we should ignore them, or we risk having the same issues when
converting them to class properties.


> Making instance-level properties appear in the schema is a completely
> different kind of conversion, because there is plenty of manual work (and
> unsolved problems for e.g. subobject property aliases).

I'd like us to convert instance-level properties to an API that
is easy to use and where the same problems won't happen again.

> 
> > You are also ignoring the complexity of the code path that leads
> > to the object*_property_add*() calls, which is the main problem
> > on most cases.
> 
> I would like an example of the complexity of those code paths.  I don't see
> much complexity, as long as the object exists at all, and I don't see how it
> would be simpler to find the code paths that lead to
> object_class_add_field_properties.

Possibly the most complex case is x86_cpu_register_bit_prop().
The qdev_property_add_static() calls at arm_cpu_post_init() are
tricky too.

If object*_property_add*() is hidden behind a function call or a
`if` statement, it's already too much complexity to me.  I don't
want us to need a second audit like the one John made when we
decide to represent QOM class properties in a QAPI schema.

-- 
Eduardo



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 00/44] Make qdev static property API usable by any QOM type
  2020-11-09 18:55                     ` Eduardo Habkost
@ 2020-11-09 19:27                       ` Paolo Bonzini
  2020-11-09 20:28                         ` Eduardo Habkost
  0 siblings, 1 reply; 77+ messages in thread
From: Paolo Bonzini @ 2020-11-09 19:27 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: Kevin Wolf, Daniel P. Berrange, Philippe Mathieu-Daudé,
	qemu-devel, Markus Armbruster, Igor Mammedov,
	Marc-André Lureau, John Snow, Stefan Berger

On 09/11/20 19:55, Eduardo Habkost wrote:
> On Mon, Nov 09, 2020 at 06:33:04PM +0100, Paolo Bonzini wrote:
>> On 09/11/20 18:16, Eduardo Habkost wrote:
>>> I mean extending the API to let custom setters and getters appear
>>> on the Property array, not using the existing API.
>>
>> That seems like conflicting goals.  The field property API is based on
>> getters and setters hidden in PropertyInfo.  The "other" property API is
>> based on getters and setters in plain sight in the declaration of the
>> property.
> 
> There's nothing that prevents a
>    void object_class_add_properties(oc, Property *props);
> function from supporting both.

Sorry but I don't believe this until I see it.  The two APIs are just 
too different.  And at some point the complexity of DEFINE_PROP becomes:

1) harder to document

2) just as hard to parse and build a QAPI schema from

And in the final desired result where QAPI generators are what generates 
the list of properties, it's pointless to shoehorn both kinds of 
properties in the same array if different things can just generate 
calls to different functions.

>>> Parsing an array containing a handful of macros (a tiny subset of
>>> C) isn't even comparable to parsing and executing C code where
>>> object*_property_add*() calls can be buried deep in many levels
>>> of C function calls (which may or may not be conditional).
>>
>> Finding the array would also require finding calls buried deep in C code,
>> wouldn't they?
> 
> Yes, but I don't expect this to happen if the API doesn't
> encourage that.

Out of 700 calls to object_class_property_add*, there are maybe 5 that 
are dynamic.  So on one hand I understand why you want an API that makes 
those things harder, but on the other hand I don't see such a big risk 
of misuse, and it won't even matter at all if we later end up with 
properties described in a QAPI schema.

>>> (Also, I don't think we should allow handwritten Property literals.)
>>
>> How would you do custom setters and getters then---without separate
>> PropertyInfos, without Property literals, and without an exploding number of
>> macros?
> 
> Prop with no struct field, and custom setter/getter:
> 
>    DEFINE_PROP("myproperty", prop_type_uint32,
>                .custom_getter = my_getter,
>                .custom_setter = my_setter)

It would have to use all the Visitor crap and would be even harder to 
use than object_class_property_add_str.  Thanks but no thanks. :)

>>> we can't be sure the [set of QOM properties]
>>> doesn't depend on configure flags or run time
>>> checks inside class_init.
>>
>> We can use grep or Coccinelle or manual code review to identify problematic
>> cases.
> 
> We can, but I believe it is better and simpler to have an API
> that enforces (or at least encourages) this.

I don't see how

     if (...) {
         object_class_add_field_properties(oc, props);
     }

is discouraged any more than

     if (...) {
         object_class_add_field_property(oc, "prop1",
                                         PROP_STRING(...));
         object_class_add_field_property(oc, "prop2",
                                         PROP_STRING(...));
         object_class_add_field_property(oc, "prop3",
                                         PROP_STRING(...));
         object_class_add_field_property(oc, "prop4",
                                         PROP_STRING(...));
     }

(If anything, the former is more natural and less ugly than the latter).

> I'd like us to convert instance-level properties to an API that
> is easy to use and where the same problems won't happen again.

I agree.  I just don't think that arrays are enough to make sure the 
same problems won't happen again.

>>> You are also ignoring the complexity of the code path that leads
>>> to the object*_property_add*() calls, which is the main problem
>>> on most cases.
>>
>> I would like an example of the complexity of those code paths.  I don't see
>> much complexity, as long as the object exists at all, and I don't see how it
>> would be simpler to find the code paths that lead to
>> object_class_add_field_properties.
> 
> Possibly the most complex case is x86_cpu_register_bit_prop().
> The qdev_property_add_static() calls at arm_cpu_post_init() are
> tricky too.

The problem with those code paths is that there's a reason why they look 
like they do.  For x86_cpu_register_feature_bit_props, for example 
either you introduce duplication between QOM property definitions and 
feat_names array, or you resort to run-time logic like that.

If you want to make those properties introspectable (i.e. known at 
compilation time) you wouldn't anyway use DEFINE_PROP*, because it would 
cause duplication.  Instead, you could have a plug-in parser for 
qapi-gen, reading files akin to target/s390x/cpu_features_def.h.inc. 
The parser would generate both QAPI schema and calls to 
x86_cpu_register_bit_prop().

To sum up: for users where properties are heavily dependent on run-time 
logic, the solution doesn't come from providing a more limited API.  A 
crippled API will simply not solve the problem that prompted the usage 
of run-time logic, and therefore won't be used.

(I don't know enough of the ARM case to say something meaningful about it).

> If object*_property_add*() is hidden behind a function call or a
> `if` statement, it's already too much complexity to me.

You want to remove hiding behind a function call, but why is it any 
better to hide behind layers of macros?  Just the example you had in 
your email included DEFINE_PROP, DEFINE_FIELD_PROP, DEFINE_PROP_UINT32. 
  It's still impossible to figure out without either parsing or 
executing C code.

Paolo



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 00/44] Make qdev static property API usable by any QOM type
  2020-11-09 19:27                       ` Paolo Bonzini
@ 2020-11-09 20:28                         ` Eduardo Habkost
  2020-11-10 10:38                           ` Kevin Wolf
  2020-11-10 10:58                           ` Paolo Bonzini
  0 siblings, 2 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-09 20:28 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Kevin Wolf, Daniel P. Berrange, Philippe Mathieu-Daudé,
	qemu-devel, Markus Armbruster, Igor Mammedov,
	Marc-André Lureau, John Snow, Stefan Berger

On Mon, Nov 09, 2020 at 08:27:21PM +0100, Paolo Bonzini wrote:
> On 09/11/20 19:55, Eduardo Habkost wrote:
> > On Mon, Nov 09, 2020 at 06:33:04PM +0100, Paolo Bonzini wrote:
> > > On 09/11/20 18:16, Eduardo Habkost wrote:
> > > > I mean extending the API to let custom setters and getters appear
> > > > on the Property array, not using the existing API.
> > > 
> > > That seems like conflicting goals.  The field property API is based on
> > > getters and setters hidden in PropertyInfo.  The "other" property API is
> > > based on getters and setters in plain sight in the declaration of the
> > > property.
> > 
> > There's nothing that prevents a
> >    void object_class_add_properties(oc, Property *props);
> > function from supporting both.
> 
> Sorry but I don't believe this until I see it.  The two APIs are just too
> different.  And at some point the complexity of DEFINE_PROP becomes:
> 
> 1) harder to document
> 
> 2) just as hard to parse and build a QAPI schema from
> 
> And in the final desired result where QAPI generators are what generates the
> list of properties, it's pointless to shoehorn both kinds of properties in
> the same array if different things can just generate calls to different
> functions.
> 
> > > > Parsing an array containing a handful of macros (a tiny subset of
> > > > C) isn't even comparable to parsing and executing C code where
> > > > object*_property_add*() calls can be buried deep in many levels
> > > > of C function calls (which may or may not be conditional).
> > > 
> > > Finding the array would also require finding calls buried deep in C code,
> > > wouldn't they?
> > 
> > Yes, but I don't expect this to happen if the API doesn't
> > encourage that.
> 
> Out of 700 calls to object_class_property_add*, there are maybe 5 that are
> dynamic.  So on one hand I understand why you want an API that makes those
> things harder, but on the other hand I don't see such a big risk of misuse,
> and it won't even matter at all if we later end up with properties described
> in a QAPI schema.
> 
> > > > (Also, I don't think we should allow handwritten Property literals.)
> > > 
> > > How would you do custom setters and getters then---without separate
> > > PropertyInfos, without Property literals, and without an exploding number of
> > > macros?
> > 
> > Prop with no struct field, and custom setter/getter:
> > 
> >    DEFINE_PROP("myproperty", prop_type_uint32,
> >                .custom_getter = my_getter,
> >                .custom_setter = my_setter)
> 
> It would have to use all the Visitor crap and would be even harder to use
> than object_class_property_add_str.  Thanks but no thanks. :)

Point taken, I dislike the visitor API too.

> 
> > > > we can't be sure the [set of QOM properties]
> > > > doesn't depend on configure flags or run time
> > > > checks inside class_init.
> > > 
> > > We can use grep or Coccinelle or manual code review to identify problematic
> > > cases.
> > 
> > We can, but I believe it is better and simpler to have an API
> > that enforces (or at least encourages) this.
> 
> I don't see how
> 
>     if (...) {
>         object_class_add_field_properties(oc, props);
>     }
> 
> is discouraged any more than
> 
>     if (...) {
>         object_class_add_field_property(oc, "prop1",
>                                         PROP_STRING(...));
>         object_class_add_field_property(oc, "prop2",
>                                         PROP_STRING(...));
>         object_class_add_field_property(oc, "prop3",
>                                         PROP_STRING(...));
>         object_class_add_field_property(oc, "prop4",
>                                         PROP_STRING(...));
>     }
> 
> (If anything, the former is more natural and less ugly than the latter).

On the former, "adding a new property" means adding an entry to a
const array.  On the latter, it means adding a new function call.

On the former, a conditional property would require defining a
new array.  A non-constant property name or type would require
making the array non-const and modifying it at runtime.

On the latter, adding a if statement on the front of that
function call or a non-constant expression as argument to the
function is trivial.

> 
> > I'd like us to convert instance-level properties to an API that
> > is easy to use and where the same problems won't happen again.
> 
> I agree.  I just don't think that arrays are enough to make sure the same
> problems won't happen again.
> 
> > > > You are also ignoring the complexity of the code path that leads
> > > > to the object*_property_add*() calls, which is the main problem
> > > > on most cases.
> > > 
> > > I would like an example of the complexity of those code paths.  I don't see
> > > much complexity, as long as the object exists at all, and I don't see how it
> > > would be simpler to find the code paths that lead to
> > > object_class_add_field_properties.
> > 
> > Possibly the most complex case is x86_cpu_register_bit_prop().
> > The qdev_property_add_static() calls at arm_cpu_post_init() are
> > tricky too.
> 
> The problem with those code paths is that there's a reason why they look
> like they do.  For x86_cpu_register_feature_bit_props, for example either
> you introduce duplication between QOM property definitions and feat_names
> array, or you resort to run-time logic like that.
> 
> If you want to make those properties introspectable (i.e. known at
> compilation time) you wouldn't anyway use DEFINE_PROP*, because it would
> cause duplication.  Instead, you could have a plug-in parser for qapi-gen,
> reading files akin to target/s390x/cpu_features_def.h.inc. The parser would
> generate both QAPI schema and calls to x86_cpu_register_bit_prop().
> 
> To sum up: for users where properties are heavily dependent on run-time
> logic, the solution doesn't come from providing a more limited API.  A
> crippled API will simply not solve the problem that prompted the usage of
> run-time logic, and therefore won't be used.

I don't know yet what's the best solution for the x86 feature
case.  Maybe duplicating the list of feature names would be a
small price to pay to get a static list of properties defined at
compilation time?  Maybe we can replace
FeatureWordInfo.feat_names[] with property introspection code
that will find the property name for a given struct field?

In either case, we need something that works for x86 and other
complex cases, or it won't be used.  Point taken.

> 
> (I don't know enough of the ARM case to say something meaningful about it).
> 
> > If object*_property_add*() is hidden behind a function call or a
> > `if` statement, it's already too much complexity to me.
> 
> You want to remove hiding behind a function call, but why is it any better
> to hide behind layers of macros?  Just the example you had in your email
> included DEFINE_PROP, DEFINE_FIELD_PROP, DEFINE_PROP_UINT32.  It's still
> impossible to figure out without either parsing or executing C code.

Because we can be absolutely sure the macros (and the property
array) will be constant expressions evaluated at compilation
time.

                             * * *

Anyway, If we are the only ones discussing this, I will just
defer to your suggestions as QOM maintainer.  I hope we hear from
others.

-- 
Eduardo



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 00/44] Make qdev static property API usable by any QOM type
  2020-11-09 20:28                         ` Eduardo Habkost
@ 2020-11-10 10:38                           ` Kevin Wolf
  2020-11-11 18:39                             ` Eduardo Habkost
  2020-11-10 10:58                           ` Paolo Bonzini
  1 sibling, 1 reply; 77+ messages in thread
From: Kevin Wolf @ 2020-11-10 10:38 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: Daniel P. Berrange, Igor Mammedov, Philippe Mathieu-Daudé,
	qemu-devel, Markus Armbruster, Marc-André Lureau,
	Paolo Bonzini, John Snow, Stefan Berger

Am 09.11.2020 um 21:28 hat Eduardo Habkost geschrieben:
> On Mon, Nov 09, 2020 at 08:27:21PM +0100, Paolo Bonzini wrote:
> > On 09/11/20 19:55, Eduardo Habkost wrote:
> > > On Mon, Nov 09, 2020 at 06:33:04PM +0100, Paolo Bonzini wrote:
> > > > On 09/11/20 18:16, Eduardo Habkost wrote:
> > > > > I mean extending the API to let custom setters and getters appear
> > > > > on the Property array, not using the existing API.
> > > > 
> > > > That seems like conflicting goals.  The field property API is based on
> > > > getters and setters hidden in PropertyInfo.  The "other" property API is
> > > > based on getters and setters in plain sight in the declaration of the
> > > > property.
> > > 
> > > There's nothing that prevents a
> > >    void object_class_add_properties(oc, Property *props);
> > > function from supporting both.
> > 
> > Sorry but I don't believe this until I see it.  The two APIs are just too
> > different.  And at some point the complexity of DEFINE_PROP becomes:
> > 
> > 1) harder to document
> > 
> > 2) just as hard to parse and build a QAPI schema from

I don't think that automatically generating a reasonable QAPI schema is
possible. This is not only because the code is hard to parse, but
because it just doesn't contain all the information - most QOM objects
are undocumented, but the QAPI schema wants documentation.

When I wrote a QAPI schema for a simple user creatable object, iothread,
I spent basically no time in copying over the fields and data types and
considerable more time finding appropriate documentation for it.

This is manual work no matter what we do.

> > And in the final desired result where QAPI generators are what generates the
> > list of properties, it's pointless to shoehorn both kinds of properties in
> > the same array if different things can just generate calls to different
> > functions.
> > 
> > > > > Parsing an array containing a handful of macros (a tiny subset of
> > > > > C) isn't even comparable to parsing and executing C code where
> > > > > object*_property_add*() calls can be buried deep in many levels
> > > > > of C function calls (which may or may not be conditional).
> > > > 
> > > > Finding the array would also require finding calls buried deep in C code,
> > > > wouldn't they?
> > > 
> > > Yes, but I don't expect this to happen if the API doesn't
> > > encourage that.
> > 
> > Out of 700 calls to object_class_property_add*, there are maybe 5 that are
> > dynamic.  So on one hand I understand why you want an API that makes those
> > things harder, but on the other hand I don't see such a big risk of misuse,
> > and it won't even matter at all if we later end up with properties described
> > in a QAPI schema.
> > 
> > > > > (Also, I don't think we should allow handwritten Property literals.)
> > > > 
> > > > How would you do custom setters and getters then---without separate
> > > > PropertyInfos, without Property literals, and without an exploding number of
> > > > macros?
> > > 
> > > Prop with no struct field, and custom setter/getter:
> > > 
> > >    DEFINE_PROP("myproperty", prop_type_uint32,
> > >                .custom_getter = my_getter,
> > >                .custom_setter = my_setter)
> > 
> > It would have to use all the Visitor crap and would be even harder to use
> > than object_class_property_add_str.  Thanks but no thanks. :)
> 
> Point taken, I dislike the visitor API too.

QAPI is the tool that hides the visitor API in generated code and
instead passes native C types to manually written code. But we'll have
to make one step after another.

And anyway, while not having to use the visitor API would be a bit
nicer, getting or setting the value is just one line in the function. So
it's probably the least of our problems.

> > > > > we can't be sure the [set of QOM properties]
> > > > > doesn't depend on configure flags or run time
> > > > > checks inside class_init.
> > > > 
> > > > We can use grep or Coccinelle or manual code review to identify problematic
> > > > cases.
> > > 
> > > We can, but I believe it is better and simpler to have an API
> > > that enforces (or at least encourages) this.
> > 
> > I don't see how
> > 
> >     if (...) {
> >         object_class_add_field_properties(oc, props);
> >     }
> > 
> > is discouraged any more than
> > 
> >     if (...) {
> >         object_class_add_field_property(oc, "prop1",
> >                                         PROP_STRING(...));
> >         object_class_add_field_property(oc, "prop2",
> >                                         PROP_STRING(...));
> >         object_class_add_field_property(oc, "prop3",
> >                                         PROP_STRING(...));
> >         object_class_add_field_property(oc, "prop4",
> >                                         PROP_STRING(...));
> >     }
> > 
> > (If anything, the former is more natural and less ugly than the latter).
> 
> On the former, "adding a new property" means adding an entry to a
> const array.  On the latter, it means adding a new function call.
> 
> On the former, a conditional property would require defining a
> new array.  A non-constant property name or type would require
> making the array non-const and modifying it at runtime.
> 
> On the latter, adding a if statement on the front of that
> function call or a non-constant expression as argument to the
> function is trivial.
> 
> > 
> > > I'd like us to convert instance-level properties to an API that
> > > is easy to use and where the same problems won't happen again.
> > 
> > I agree.  I just don't think that arrays are enough to make sure the same
> > problems won't happen again.
> > 
> > > > > You are also ignoring the complexity of the code path that leads
> > > > > to the object*_property_add*() calls, which is the main problem
> > > > > on most cases.
> > > > 
> > > > I would like an example of the complexity of those code paths.  I don't see
> > > > much complexity, as long as the object exists at all, and I don't see how it
> > > > would be simpler to find the code paths that lead to
> > > > object_class_add_field_properties.
> > > 
> > > Possibly the most complex case is x86_cpu_register_bit_prop().
> > > The qdev_property_add_static() calls at arm_cpu_post_init() are
> > > tricky too.
> > 
> > The problem with those code paths is that there's a reason why they look
> > like they do.  For x86_cpu_register_feature_bit_props, for example either
> > you introduce duplication between QOM property definitions and feat_names
> > array, or you resort to run-time logic like that.
> > 
> > If you want to make those properties introspectable (i.e. known at
> > compilation time) you wouldn't anyway use DEFINE_PROP*, because it would
> > cause duplication.  Instead, you could have a plug-in parser for qapi-gen,
> > reading files akin to target/s390x/cpu_features_def.h.inc. The parser would
> > generate both QAPI schema and calls to x86_cpu_register_bit_prop().
> > 
> > To sum up: for users where properties are heavily dependent on run-time
> > logic, the solution doesn't come from providing a more limited API.  A
> > crippled API will simply not solve the problem that prompted the usage of
> > run-time logic, and therefore won't be used.
> 
> I don't know yet what's the best solution for the x86 feature
> case.  Maybe duplicating the list of feature names would be a
> small price to pay to get a static list of properties defined at
> compilation time?  Maybe we can replace
> FeatureWordInfo.feat_names[] with property introspection code
> that will find the property name for a given struct field?
> 
> In either case, we need something that works for x86 and other
> complex cases, or it won't be used.  Point taken.
> 
> > 
> > (I don't know enough of the ARM case to say something meaningful about it).
> > 
> > > If object*_property_add*() is hidden behind a function call or a
> > > `if` statement, it's already too much complexity to me.
> > 
> > You want to remove hiding behind a function call, but why is it any better
> > to hide behind layers of macros?  Just the example you had in your email
> > included DEFINE_PROP, DEFINE_FIELD_PROP, DEFINE_PROP_UINT32.  It's still
> > impossible to figure out without either parsing or executing C code.
> 
> Because we can be absolutely sure the macros (and the property
> array) will be constant expressions evaluated at compilation
> time.
> 
>                              * * *
> 
> Anyway, If we are the only ones discussing this, I will just
> defer to your suggestions as QOM maintainer.  I hope we hear from
> others.

Well, I expressed my preference for what you're arguing for now, but my
expertise is more on the QAPI side than on the QOM side, so I can't
really contribute more arguments in the details than you are already
doing.

In the end, as soon as it's generated code, it won't matter much any
more what it looks like. But I'm not sure how soon we will be there and
for the meantime I'll always prefer static data to runtime code.

Kevin



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 00/44] Make qdev static property API usable by any QOM type
  2020-11-09 20:28                         ` Eduardo Habkost
  2020-11-10 10:38                           ` Kevin Wolf
@ 2020-11-10 10:58                           ` Paolo Bonzini
  2020-11-10 17:03                             ` Eduardo Habkost
  1 sibling, 1 reply; 77+ messages in thread
From: Paolo Bonzini @ 2020-11-10 10:58 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: Kevin Wolf, Daniel P. Berrange, Philippe Mathieu-Daudé,
	qemu-devel, Markus Armbruster, Igor Mammedov,
	Marc-André Lureau, John Snow, Stefan Berger

On 09/11/20 21:28, Eduardo Habkost wrote:
> I don't know yet what's the best solution for the x86 feature
> case.  Maybe duplicating the list of feature names would be a
> small price to pay to get a static list of properties defined at
> compilation time?  Maybe we can replace
> FeatureWordInfo.feat_names[] with property introspection code
> that will find the property name for a given struct field?

The problem is associating the names with the metadata (feature 
word/bit).  Right now we do that by placing the names in the 
feat_names[] arrays, which are indexed by feature word and bit.

>>> If object*_property_add*() is hidden behind a function call or a
>>> `if` statement, it's already too much complexity to me.
>> You want to remove hiding behind a function call, but why is it any better
>> to hide behind layers of macros?  Just the example you had in your email
>> included DEFINE_PROP, DEFINE_FIELD_PROP, DEFINE_PROP_UINT32.  It's still
>> impossible to figure out without either parsing or executing C code.
>
> Because we can be absolutely sure the macros (and the property
> array) will be constant expressions evaluated at compilation
> time.

That's not entirely true.  You can always build Property objects 
manually in a for loop.  (Though at that point you might as well use the 
existing API and not the new one).

I think we agree on where _to go_ (schema described outside C code, and 
possibly integrated with the QAPI schema).  I think neither of us has a 
clear idea of how to get there. :)  I don't see this series as a step 
towards that; I see it more as a worthwhile way to remove boilerplate 
from QOM objects.

In my opinion the next steps for QOM (in general, not necessarily 
related to the goal) should be to:

1) audit the code and ensure that there are no conditional properties

2) figure out if it makes sense to provide run-time (not compile-time) 
introspection of QOM class properties, as either a stable or an 
experimental interface, and how it works together with the QAPI 
introspection.  In particular, whether compound QAPI types can be 
matched across QOM and QAPI introspection.

3) figure out if there are any instance properties that can be easily 
extended to class properties.  In particular, figure out if we can do 
class-level property aliasing.

Paolo



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 00/44] Make qdev static property API usable by any QOM type
  2020-11-10 10:58                           ` Paolo Bonzini
@ 2020-11-10 17:03                             ` Eduardo Habkost
  0 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-10 17:03 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Kevin Wolf, Daniel P. Berrange, Philippe Mathieu-Daudé,
	qemu-devel, Markus Armbruster, Igor Mammedov,
	Marc-André Lureau, John Snow, Stefan Berger

On Tue, Nov 10, 2020 at 11:58:29AM +0100, Paolo Bonzini wrote:
> On 09/11/20 21:28, Eduardo Habkost wrote:
> > I don't know yet what's the best solution for the x86 feature
> > case.  Maybe duplicating the list of feature names would be a
> > small price to pay to get a static list of properties defined at
> > compilation time?  Maybe we can replace
> > FeatureWordInfo.feat_names[] with property introspection code
> > that will find the property name for a given struct field?
> 
> The problem is associating the names with the metadata (feature word/bit).
> Right now we do that by placing the names in the feat_names[] arrays, which
> are indexed by feature word and bit.

Right, that would require an introspection interface letting us
get the property name for a given struct field + bit.

Anyway, let's get back to this later.

> 
> > > > If object*_property_add*() is hidden behind a function call or a
> > > > `if` statement, it's already too much complexity to me.
> > > You want to remove hiding behind a function call, but why is it any better
> > > to hide behind layers of macros?  Just the example you had in your email
> > > included DEFINE_PROP, DEFINE_FIELD_PROP, DEFINE_PROP_UINT32.  It's still
> > > impossible to figure out without either parsing or executing C code.
> > 
> > Because we can be absolutely sure the macros (and the property
> > array) will be constant expressions evaluated at compilation
> > time.
> 
> That's not entirely true.  You can always build Property objects manually in
> a for loop.  (Though at that point you might as well use the existing API
> and not the new one).

This is true if the property array is always declared as static
const.

> 
> I think we agree on where _to go_ (schema described outside C code, and
> possibly integrated with the QAPI schema).  I think neither of us has a
> clear idea of how to get there. :)  I don't see this series as a step
> towards that; I see it more as a worthwhile way to remove boilerplate from
> QOM objects.

My first goal here is to facilitate (3) below, and allow it to be
done with less effort and less churn.  This series is not
essential to do (3), but I'd like to avoid porting the same code
to a different API 2 or 3 times because we keep introducing new
mechanisms.

> 
> In my opinion the next steps for QOM (in general, not necessarily related to
> the goal) should be to:
> 
> 1) audit the code and ensure that there are no conditional properties
> 
> 2) figure out if it makes sense to provide run-time (not compile-time)
> introspection of QOM class properties, as either a stable or an experimental
> interface, and how it works together with the QAPI introspection.  In
> particular, whether compound QAPI types can be matched across QOM and QAPI
> introspection.

Can you clarify this item?  Do you mean an external interface, or
internal APIs?

> 
> 3) figure out if there are any instance properties that can be easily
> extended to class properties.  In particular, figure out if we can do
> class-level property aliasing.

Most of them need to be moved to class properties somehow,
because they are externally visible.  The only exceptions I see
are read-only link properties and child properties.

The trickiest ones are object_property_add_alias() (no
class-level equivalent) and object_property_add_*_ptr() (no
usable class-level equivalent).

object_property_add_*_ptr() is what prompted the creation of this
series.  See
https://lore.kernel.org/qemu-devel/20201009160122.1662082-1-ehabkost@redhat.com

-- 
Eduardo



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 00/44] Make qdev static property API usable by any QOM type
  2020-11-10 10:38                           ` Kevin Wolf
@ 2020-11-11 18:39                             ` Eduardo Habkost
  2020-11-12  8:11                               ` Paolo Bonzini
  0 siblings, 1 reply; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-11 18:39 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Daniel P. Berrange, Igor Mammedov, Philippe Mathieu-Daudé,
	qemu-devel, Markus Armbruster, Marc-André Lureau,
	Paolo Bonzini, John Snow, Stefan Berger

On Tue, Nov 10, 2020 at 11:38:04AM +0100, Kevin Wolf wrote:
> Am 09.11.2020 um 21:28 hat Eduardo Habkost geschrieben:
[...]
> > Anyway, If we are the only ones discussing this, I will just
> > defer to your suggestions as QOM maintainer.  I hope we hear from
> > others.
> 
> Well, I expressed my preference for what you're arguing for now, but my
> expertise is more on the QAPI side than on the QOM side, so I can't
> really contribute more arguments in the details than you are already
> doing.

Sorry, I didn't mean to ignore the feedback you had already sent.

Let me rephrase: I was hoping we hear more from you and others.

> 
> In the end, as soon as it's generated code, it won't matter much any
> more what it looks like. But I'm not sure how soon we will be there and
> for the meantime I'll always prefer static data to runtime code.

Agreed.  I really hope we can convince Paolo that properties as
static const data are a desirable feature, and not a crippled
API.

Paolo convinced me that we still need object_class_add_field()
for cases like x86, but I still believe static const arrays of
properties should be the rule for all the rest.

In the meantime, I'll do the following:

I will submit v3 of this series with both
object_class_property_add_field() and
object_class_add_field_properties() as internal QOM APIs.
object_class_add_field_properties() will be used to implement
device_class_set_props().

After that, solving this controversy would be just a matter of
deciding if we want to make object_class_add_field_properties() a
public function or not.

-- 
Eduardo



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 00/44] Make qdev static property API usable by any QOM type
  2020-11-11 18:39                             ` Eduardo Habkost
@ 2020-11-12  8:11                               ` Paolo Bonzini
  2020-11-12 14:53                                 ` Eduardo Habkost
  0 siblings, 1 reply; 77+ messages in thread
From: Paolo Bonzini @ 2020-11-12  8:11 UTC (permalink / raw)
  To: Eduardo Habkost, Kevin Wolf
  Cc: Daniel P. Berrange, Philippe Mathieu-Daudé,
	qemu-devel, Markus Armbruster, Igor Mammedov,
	Marc-André Lureau, John Snow, Stefan Berger

On 11/11/20 19:39, Eduardo Habkost wrote:
> I will submit v3 of this series with both
> object_class_property_add_field() and
> object_class_add_field_properties() as internal QOM APIs.
> object_class_add_field_properties() will be used to implement
> device_class_set_props().

I have no problem making both of them public APIs.  If an object can use 
only a single array of static^Wfield properties that's totally fine; I'm 
just not sure about splitting properties between class_init and static 
arrays, which is the less consistent case.

Paolo



^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH v2 00/44] Make qdev static property API usable by any QOM type
  2020-11-12  8:11                               ` Paolo Bonzini
@ 2020-11-12 14:53                                 ` Eduardo Habkost
  0 siblings, 0 replies; 77+ messages in thread
From: Eduardo Habkost @ 2020-11-12 14:53 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Kevin Wolf, Daniel P. Berrange, Philippe Mathieu-Daudé,
	qemu-devel, Markus Armbruster, Igor Mammedov,
	Marc-André Lureau, John Snow, Stefan Berger

On Thu, Nov 12, 2020 at 09:11:48AM +0100, Paolo Bonzini wrote:
> On 11/11/20 19:39, Eduardo Habkost wrote:
> > I will submit v3 of this series with both
> > object_class_property_add_field() and
> > object_class_add_field_properties() as internal QOM APIs.
> > object_class_add_field_properties() will be used to implement
> > device_class_set_props().
> 
> I have no problem making both of them public APIs.  If an object can use
> only a single array of static^Wfield properties that's totally fine; I'm
> just not sure about splitting properties between class_init and static
> arrays, which is the less consistent case.

I agree that using a static array for a couple of properties and
object_class_property_add*() for all the rest isn't desirable.
Making both APIs public sounds like a good plan.

I'd like us to make almost every object use only an array (just
like almost every device already use only an array, today), but
maybe we'll hit too many obstacles trying to do that.  We'll see.

-- 
Eduardo



^ permalink raw reply	[flat|nested] 77+ messages in thread

end of thread, other threads:[~2020-11-12 14:55 UTC | newest]

Thread overview: 77+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 01/44] cs4231: Get rid of empty property array Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 02/44] cpu: Move cpu_common_props to hw/core/cpu.c Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 03/44] qdev: Move property code to qdev-properties.[ch] Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 04/44] qdev: Check dev->realized at set_size() Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 05/44] sparc: Check dev->realized at sparc_set_nwindows() Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 06/44] qdev: Don't use dev->id on set_size32() error message Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 07/44] qdev: Make PropertyInfo.print method get Object* argument Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 08/44] qdev: Make bit_prop_set() " Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 09/44] qdev: Make qdev_get_prop_ptr() get Object* arg Eduardo Habkost
2020-11-04 15:59   ` Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 10/44] qdev: Make qdev_find_global_prop() get Object* argument Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 11/44] qdev: Make check_prop_still_unset() " Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 12/44] qdev: Make error_set_from_qdev_prop_error() " Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 13/44] qdev: Move UUID property to qdev-properties-system.c Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 14/44] qdev: Move softmmu properties to qdev-properties-system.h Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 15/44] qdev: Reuse DEFINE_PROP in all DEFINE_PROP_* macros Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 16/44] sparc: Use DEFINE_PROP for nwindows property Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 17/44] qdev: Get just property name at error_set_from_qdev_prop_error() Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 18/44] qdev: Avoid using prop->name unnecessarily Eduardo Habkost
2020-11-04 17:25   ` Stefan Berger
2020-11-04 15:59 ` [PATCH v2 19/44] qdev: Add name parameter to qdev_class_add_property() Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 20/44] qdev: Add name argument to PropertyInfo.create method Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 21/44] qdev: Wrap getters and setters in separate helpers Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 22/44] qdev: Move dev->realized check to qdev_property_set() Eduardo Habkost
2020-11-04 15:59   ` Eduardo Habkost
2020-11-04 17:28   ` Stefan Berger
2020-11-04 17:28     ` Stefan Berger
2020-11-04 16:00 ` [PATCH v2 23/44] qdev: Make PropertyInfo.create return ObjectProperty* Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 24/44] qdev: Make qdev_class_add_property() more flexible Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 25/44] qdev: Separate generic and device-specific property registration Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 26/44] qdev: Rename Property.name to Property.qdev_prop_name Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 27/44] qdev: Don't set qdev_prop_name for array elements Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 28/44] qdev: Avoid unnecessary DeviceState* variable at set_prop_arraylen() Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 29/44] qdev: Remove ArrayElementProperty.propname field Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 30/44] qdev: Get rid of ArrayElementProperty struct Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 31/44] qdev: Reuse object_property_add_field() when adding array elements Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 32/44] qom: Add allow_set callback to ObjectProperty Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 33/44] qdev: Make qdev_prop_allow_set() a ObjectProperty.allow_set callback Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 34/44] qdev: Make qdev_propinfo_get_uint16() static Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 35/44] qdev: Rename qdev_propinfo_* to field_prop_* Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 36/44] qdev: Rename qdev_get_prop_ptr() to object_field_prop_ptr() Eduardo Habkost
2020-11-04 16:00   ` Eduardo Habkost
2020-11-05 18:49   ` Stefan Berger
2020-11-05 18:49     ` Stefan Berger
2020-11-04 16:00 ` [PATCH v2 37/44] qdev: Move qdev_prop_tpm declaration to tpm_prop.h Eduardo Habkost
2020-11-05 18:50   ` Stefan Berger
2020-11-04 16:00 ` [PATCH v2 38/44] qdev: Rename qdev_prop_* to prop_info_* Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 39/44] qdev: PROP_* macros Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 40/44] qdev: Move core field property code to QOM Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 41/44] qdev: Move base property types to qom/property-types.c Eduardo Habkost
2020-11-04 16:36   ` Paolo Bonzini
2020-11-04 20:50     ` Eduardo Habkost
2020-11-05  9:36       ` Paolo Bonzini
2020-11-04 16:00 ` [PATCH v2 42/44] qom: Include static property API reference in documentation Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 43/44] tests: Use field properties at check-qom-proplist test case Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 44/44] machine: Register most properties as field properties Eduardo Habkost
2020-11-04 16:36 ` [PATCH v2 00/44] Make qdev static property API usable by any QOM type no-reply
2020-11-06  9:45 ` Kevin Wolf
2020-11-06 15:50   ` Eduardo Habkost
2020-11-06 21:10     ` Eduardo Habkost
2020-11-08 14:05       ` Paolo Bonzini
2020-11-09 11:34         ` Kevin Wolf
2020-11-09 14:15           ` Paolo Bonzini
2020-11-09 15:21             ` Eduardo Habkost
2020-11-09 16:34               ` Paolo Bonzini
2020-11-09 17:16                 ` Eduardo Habkost
2020-11-09 17:33                   ` Paolo Bonzini
2020-11-09 18:55                     ` Eduardo Habkost
2020-11-09 19:27                       ` Paolo Bonzini
2020-11-09 20:28                         ` Eduardo Habkost
2020-11-10 10:38                           ` Kevin Wolf
2020-11-11 18:39                             ` Eduardo Habkost
2020-11-12  8:11                               ` Paolo Bonzini
2020-11-12 14:53                                 ` Eduardo Habkost
2020-11-10 10:58                           ` Paolo Bonzini
2020-11-10 17:03                             ` Eduardo Habkost

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.