All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] qom: Field properties type safety
@ 2020-11-04 17:25 Eduardo Habkost
  2020-11-04 17:25 ` [PATCH 1/7] sparc: Fix property/field size mismatch for iu-version Eduardo Habkost
                   ` (6 more replies)
  0 siblings, 7 replies; 16+ messages in thread
From: Eduardo Habkost @ 2020-11-04 17:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: Igor Mammedov, Daniel P. Berrange, Paolo Bonzini

Based-on: 20201104160021.2342108-1-ehabkost@redhat.com
Git branch: https://gitlab.com/ehabkost/qemu/-/commits/work/qdev-size-validation

This adds additional validation to field properties, to ensure
the field property usage and implementation agree about the
struct field size.

The first patch in the series fixes one bug found using the new
safety mechanism.  I hope it's the only one.

Eduardo Habkost (7):
  sparc: Fix property/field size mismatch for iu-version
  qom: Save size of struct field in Property struct
  qdev: Don't register unreadable legacy properties
  qom: Replace void* parameter with Property* on field getters/setters
  qom: Replace void* parameter with Property* on PropertyInfo.release
  qom: Add FIELD_PTR, a type-safe wrapper for object_field_prop_ptr()
  sparc: Use FIELD_PTR at nwindows getter/setter

 include/qom/field-property-internal.h |   8 +-
 include/qom/field-property.h          |  61 ++++++++--
 include/qom/property-types.h          |   1 +
 target/sparc/cpu.h                    |   2 +-
 backends/tpm/tpm_util.c               |  18 ++-
 hw/block/xen-block.c                  |  10 +-
 hw/core/qdev-properties-system.c      | 140 +++++++++-------------
 hw/core/qdev-properties.c             |   4 +-
 hw/s390x/css.c                        |  10 +-
 hw/s390x/s390-pci-bus.c               |  10 +-
 hw/vfio/pci-quirks.c                  |  14 +--
 qom/field-property.c                  |  16 ++-
 qom/property-types.c                  | 166 +++++++++++---------------
 target/sparc/cpu.c                    |  17 ++-
 14 files changed, 231 insertions(+), 246 deletions(-)

-- 
2.28.0




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

* [PATCH 1/7] sparc: Fix property/field size mismatch for iu-version
  2020-11-04 17:25 [PATCH 0/7] qom: Field properties type safety Eduardo Habkost
@ 2020-11-04 17:25 ` Eduardo Habkost
  2020-11-10 13:00   ` Mark Cave-Ayland
  2020-11-04 17:25 ` [PATCH 2/7] qom: Save size of struct field in Property struct Eduardo Habkost
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Eduardo Habkost @ 2020-11-04 17:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: Igor Mammedov, Mark Cave-Ayland, Daniel P. Berrange,
	Artyom Tarasenko, Paolo Bonzini

The "iu-version" property is declared as uint64_t but points to a
target_ulong struct field.  On the sparc 32-bit target, This
makes every write of iu-version corrupt the 4 bytes after
sparc_def_t.iu_version (where the fpu_version field is located).

Change the type of the iu_version struct field to uint64_t,
and just use DEFINE_PROP_UINT64.

The only place where env.def.iu_version field is read is the
    env->version = env->def.iu_version;
assignment at sparc_cpu_realizefn().  This means behavior will be
kept exactly the same (except for the memory corruption bug fix).

It would be nice to explicitly validate iu_version against
target_ulong limits, but that would be a new feature (since the
first version of this code, iu-version was parsed as 64-bit value
value).  It can be done later, once we have an appropriate API to
define limits for integer properties.

Fixes: de05005bf785 ("sparc: convert cpu features to qdev properties")
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.h | 2 +-
 target/sparc/cpu.c | 5 ++---
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index b9369398f2..8ed0f4fef3 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -252,7 +252,7 @@ typedef struct trap_state {
 
 struct sparc_def_t {
     const char *name;
-    target_ulong iu_version;
+    uint64_t iu_version;
     uint32_t fpu_version;
     uint32_t mmu_version;
     uint32_t mmu_bm;
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index ec59a13eb8..5a9397f19a 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -576,7 +576,7 @@ void sparc_cpu_list(void)
     unsigned int i;
 
     for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
-        qemu_printf("Sparc %16s IU " TARGET_FMT_lx
+        qemu_printf("Sparc %16s IU %" PRIx64
                     " FPU %08x MMU %08x NWINS %d ",
                     sparc_defs[i].name,
                     sparc_defs[i].iu_version,
@@ -838,8 +838,7 @@ static Property sparc_cpu_properties[] = {
     DEFINE_PROP_BIT("hypv",     SPARCCPU, env.def.features, 11, false),
     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,
-                         prop_info_uint64, target_ulong),
+    DEFINE_PROP_UINT64("iu-version", SPARCCPU, env.def.iu_version, 0),
     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] 16+ messages in thread

* [PATCH 2/7] qom: Save size of struct field in Property struct
  2020-11-04 17:25 [PATCH 0/7] qom: Field properties type safety Eduardo Habkost
  2020-11-04 17:25 ` [PATCH 1/7] sparc: Fix property/field size mismatch for iu-version Eduardo Habkost
@ 2020-11-04 17:25 ` Eduardo Habkost
  2020-11-04 17:25 ` [PATCH 3/7] qdev: Don't register unreadable legacy properties Eduardo Habkost
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Eduardo Habkost @ 2020-11-04 17:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: Igor Mammedov, Daniel P. Berrange, Paolo Bonzini

This will let the code that reads/writes the field ensure it will
never go out of bounds.

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/qom/field-property.h | 3 +++
 include/qom/property-types.h | 1 +
 qom/property-types.c         | 1 +
 3 files changed, 5 insertions(+)

diff --git a/include/qom/field-property.h b/include/qom/field-property.h
index bc866e1c93..e64a2b3c07 100644
--- a/include/qom/field-property.h
+++ b/include/qom/field-property.h
@@ -27,7 +27,10 @@ struct Property {
      */
     const char   *qdev_prop_name;
     const PropertyInfo *info;
+    /** @offset: offset of field in object instance struct */
     ptrdiff_t    offset;
+    /** @size: size of field in object instance struct */
+    size_t       size;
     uint8_t      bitnr;
     /**
      * @set_default: true if the default value should be set from @defval,
diff --git a/include/qom/property-types.h b/include/qom/property-types.h
index 3a36e1fec5..17bf007234 100644
--- a/include/qom/property-types.h
+++ b/include/qom/property-types.h
@@ -28,6 +28,7 @@ extern const PropertyInfo prop_info_link;
         .info      = &(_prop),                                   \
         .offset    = offsetof(_state, _field)                    \
             + type_check(_type, typeof_field(_state, _field)),   \
+        .size      = sizeof(typeof_field(_state, _field)),       \
         __VA_ARGS__                                              \
         }
 
diff --git a/qom/property-types.c b/qom/property-types.c
index f566c05ec2..856b5ae76d 100644
--- a/qom/property-types.c
+++ b/qom/property-types.c
@@ -485,6 +485,7 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
          * being inside the device struct.
          */
         arrayprop->offset = eltptr - (void *)obj;
+        arrayprop->size = prop->arrayfieldsize;
         assert(object_field_prop_ptr(obj, arrayprop) == eltptr);
         object_property_add_field(obj, propname, arrayprop, op->allow_set);
     }
-- 
2.28.0



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

* [PATCH 3/7] qdev: Don't register unreadable legacy properties
  2020-11-04 17:25 [PATCH 0/7] qom: Field properties type safety Eduardo Habkost
  2020-11-04 17:25 ` [PATCH 1/7] sparc: Fix property/field size mismatch for iu-version Eduardo Habkost
  2020-11-04 17:25 ` [PATCH 2/7] qom: Save size of struct field in Property struct Eduardo Habkost
@ 2020-11-04 17:25 ` Eduardo Habkost
  2020-11-04 17:25   ` Eduardo Habkost
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Eduardo Habkost @ 2020-11-04 17:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: Igor Mammedov, Daniel P. Berrange, Paolo Bonzini

The existing code at qdev_class_add_legacy_property() will
register a property if both .print and .get are NULL, which is
useless as it will register a property that can't be read or
written.

The only PropertyInfo struct in the whole tree that has both
.print and .get set to NULL is qdev_prop_link.  This means every
link property in the code had a useless "legacy-" property being
registered.

Fix this by only registering legacy properties if a .print method
exists.

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 | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 5bb4ff5f46..73884a212a 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -264,13 +264,13 @@ 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) {
+    if (!prop->info->print) {
         return;
     }
 
     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,
+        qdev_get_legacy_property,
         NULL, NULL, prop);
 }
 
-- 
2.28.0



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

* [PATCH 4/7] qom: Replace void* parameter with Property* on field getters/setters
  2020-11-04 17:25 [PATCH 0/7] qom: Field properties type safety Eduardo Habkost
@ 2020-11-04 17:25   ` Eduardo Habkost
  2020-11-04 17:25 ` [PATCH 2/7] qom: Save size of struct field in Property struct Eduardo Habkost
                     ` (5 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Eduardo Habkost @ 2020-11-04 17:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: Matthew Rosato, Paul Durrant, Mark Cave-Ayland,
	Stefano Stabellini, qemu-block, Stefan Berger, David Hildenbrand,
	Halil Pasic, Christian Borntraeger, Anthony Perard, xen-devel,
	Artyom Tarasenko, Thomas Huth, qemu-s390x, Igor Mammedov,
	Richard Henderson, Kevin Wolf, Daniel P. Berrange, Cornelia Huck,
	Alex Williamson, Max Reitz, Paolo Bonzini

All field property getters and setters must interpret the fourth
argument as Property*.  Change the function signature of field
property getters and setters to indicate that.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
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: Richard Henderson <rth@twiddle.net>
Cc: David Hildenbrand <david@redhat.com>
Cc: Cornelia Huck <cohuck@redhat.com>
Cc: Thomas Huth <thuth@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: 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
---
 include/qom/field-property-internal.h |   8 +-
 include/qom/field-property.h          |  26 ++++---
 backends/tpm/tpm_util.c               |  11 ++-
 hw/block/xen-block.c                  |   6 +-
 hw/core/qdev-properties-system.c      |  86 +++++++++-------------
 hw/s390x/css.c                        |   6 +-
 hw/s390x/s390-pci-bus.c               |   6 +-
 hw/vfio/pci-quirks.c                  |  10 +--
 qom/property-types.c                  | 102 +++++++++-----------------
 target/sparc/cpu.c                    |   4 +-
 10 files changed, 105 insertions(+), 160 deletions(-)

diff --git a/include/qom/field-property-internal.h b/include/qom/field-property-internal.h
index 7aa27ce836..bc7d25033d 100644
--- a/include/qom/field-property-internal.h
+++ b/include/qom/field-property-internal.h
@@ -9,9 +9,9 @@
 #define QOM_STATIC_PROPERTY_INTERNAL_H
 
 void field_prop_get_enum(Object *obj, Visitor *v, const char *name,
-                         void *opaque, Error **errp);
+                         Property *prop, Error **errp);
 void field_prop_set_enum(Object *obj, Visitor *v, const char *name,
-                         void *opaque, Error **errp);
+                         Property *prop, Error **errp);
 
 void field_prop_set_default_value_enum(ObjectProperty *op,
                                        const Property *prop);
@@ -21,9 +21,9 @@ void field_prop_set_default_value_uint(ObjectProperty *op,
                                        const Property *prop);
 
 void field_prop_get_int32(Object *obj, Visitor *v, const char *name,
-                          void *opaque, Error **errp);
+                          Property *prop, Error **errp);
 void field_prop_get_size32(Object *obj, Visitor *v, const char *name,
-                           void *opaque, Error **errp);
+                           Property *prop, Error **errp);
 
 /**
  * object_property_add_field: Add a field property to an object instance
diff --git a/include/qom/field-property.h b/include/qom/field-property.h
index e64a2b3c07..438bb25896 100644
--- a/include/qom/field-property.h
+++ b/include/qom/field-property.h
@@ -54,6 +54,18 @@ struct Property {
     const char   *link_type;
 };
 
+/**
+ * typedef FieldAccessor: a field property getter or setter function
+ * @obj: the object instance
+ * @v: the visitor that contains the property data
+ * @name: the name of the property
+ * @prop: Field property definition
+ * @errp: pointer to error information
+ */
+typedef void FieldAccessor(Object *obj, Visitor *v,
+                           const char *name, Property *prop,
+                           Error **errp);
+
 /**
  * struct PropertyInfo: information on a specific QOM property type
  */
@@ -71,16 +83,10 @@ struct PropertyInfo {
     /** @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;
+    /** @get: Property getter */
+    FieldAccessor *get;
+    /** @set: Property setter */
+    FieldAccessor *set;
     /**
      * @release: Optional release function, called when the object
      * is destroyed
diff --git a/backends/tpm/tpm_util.c b/backends/tpm/tpm_util.c
index bb1ab34a75..e8837938e5 100644
--- a/backends/tpm/tpm_util.c
+++ b/backends/tpm/tpm_util.c
@@ -32,10 +32,10 @@
 
 /* tpm backend property */
 
-static void get_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
-                    Error **errp)
+static void get_tpm(Object *obj, Visitor *v, const char *name,
+                    Property *prop, Error **errp)
 {
-    TPMBackend **be = object_field_prop_ptr(obj, opaque);
+    TPMBackend **be = object_field_prop_ptr(obj, prop);
     char *p;
 
     p = g_strdup(*be ? (*be)->id : "");
@@ -43,10 +43,9 @@ static void get_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
     g_free(p);
 }
 
-static void set_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
-                    Error **errp)
+static void set_tpm(Object *obj, Visitor *v, const char *name,
+                    Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     TPMBackend *s, **be = object_field_prop_ptr(obj, prop);
     char *str;
 
diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
index 718d886e5c..c1ee634639 100644
--- a/hw/block/xen-block.c
+++ b/hw/block/xen-block.c
@@ -333,9 +333,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)
+                                Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     XenBlockVdev *vdev = object_field_prop_ptr(obj, prop);
     char *str;
 
@@ -393,9 +392,8 @@ 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)
+                                Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     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 8da68f076c..4c649cb4b2 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -58,10 +58,9 @@ static bool check_prop_still_unset(Object *obj, const char *name,
 
 /* --- drive --- */
 
-static void get_drive(Object *obj, Visitor *v, const char *name, void *opaque,
-                      Error **errp)
+static void get_drive(Object *obj, Visitor *v, const char *name,
+                      Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     void **ptr = object_field_prop_ptr(obj, prop);
     const char *value;
     char *p;
@@ -165,16 +164,16 @@ fail:
     g_free(str);
 }
 
-static void set_drive(Object *obj, Visitor *v, const char *name, void *opaque,
+static void set_drive(Object *obj, Visitor *v, const char *name, Property *prop,
                       Error **errp)
 {
-    set_drive_helper(obj, v, name, opaque, false, errp);
+    set_drive_helper(obj, v, name, prop, false, errp);
 }
 
 static void set_drive_iothread(Object *obj, Visitor *v, const char *name,
-                               void *opaque, Error **errp)
+                               Property *prop, Error **errp)
 {
-    set_drive_helper(obj, v, name, opaque, true, errp);
+    set_drive_helper(obj, v, name, prop, true, errp);
 }
 
 static void release_drive(Object *obj, const char *name, void *opaque)
@@ -211,10 +210,10 @@ const PropertyInfo qdev_prop_drive_iothread = {
 
 /* --- character device --- */
 
-static void get_chr(Object *obj, Visitor *v, const char *name, void *opaque,
-                    Error **errp)
+static void get_chr(Object *obj, Visitor *v, const char *name,
+                    Property *prop, Error **errp)
 {
-    CharBackend *be = object_field_prop_ptr(obj, opaque);
+    CharBackend *be = object_field_prop_ptr(obj, prop);
     char *p;
 
     p = g_strdup(be->chr && be->chr->label ? be->chr->label : "");
@@ -222,10 +221,9 @@ static void get_chr(Object *obj, Visitor *v, const char *name, void *opaque,
     g_free(p);
 }
 
-static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
-                    Error **errp)
+static void set_chr(Object *obj, Visitor *v, const char *name,
+                    Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     CharBackend *be = object_field_prop_ptr(obj, prop);
     Chardev *s;
     char *str;
@@ -282,10 +280,9 @@ const PropertyInfo qdev_prop_chr = {
  *   01:02:03:04:05:06
  *   01-02-03-04-05-06
  */
-static void get_mac(Object *obj, Visitor *v, const char *name, void *opaque,
-                    Error **errp)
+static void get_mac(Object *obj, Visitor *v, const char *name,
+                    Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     MACAddr *mac = object_field_prop_ptr(obj, prop);
     char buffer[2 * 6 + 5 + 1];
     char *p = buffer;
@@ -297,10 +294,9 @@ static void get_mac(Object *obj, Visitor *v, const char *name, void *opaque,
     visit_type_str(v, name, &p, errp);
 }
 
-static void set_mac(Object *obj, Visitor *v, const char *name, void *opaque,
-                    Error **errp)
+static void set_mac(Object *obj, Visitor *v, const char *name,
+                    Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     MACAddr *mac = object_field_prop_ptr(obj, prop);
     int i, pos;
     char *str;
@@ -360,9 +356,8 @@ void qdev_prop_set_macaddr(DeviceState *dev, const char *name,
 
 /* --- netdev device --- */
 static void get_netdev(Object *obj, Visitor *v, const char *name,
-                       void *opaque, Error **errp)
+                        Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     NICPeers *peers_ptr = object_field_prop_ptr(obj, prop);
     char *p = g_strdup(peers_ptr->ncs[0] ? peers_ptr->ncs[0]->name : "");
 
@@ -371,9 +366,8 @@ 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)
+                        Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     NICPeers *peers_ptr = object_field_prop_ptr(obj, prop);
     NetClientState **ncs = peers_ptr->ncs;
     NetClientState *peers[MAX_QUEUE_NUM];
@@ -433,9 +427,8 @@ const PropertyInfo qdev_prop_netdev = {
 
 /* --- audiodev --- */
 static void get_audiodev(Object *obj, Visitor *v, const char* name,
-                         void *opaque, Error **errp)
+                          Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     QEMUSoundCard *card = object_field_prop_ptr(obj, prop);
     char *p = g_strdup(audio_get_id(card));
 
@@ -444,9 +437,8 @@ 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)
+                          Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     QEMUSoundCard *card = object_field_prop_ptr(obj, prop);
     AudioState *state;
     int err = 0;
@@ -545,10 +537,9 @@ const PropertyInfo qdev_prop_losttickpolicy = {
 /* --- blocksize --- */
 
 static void set_blocksize(Object *obj, Visitor *v, const char *name,
-                          void *opaque, Error **errp)
+                           Property *prop, Error **errp)
 {
     DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
     uint32_t *ptr = object_field_prop_ptr(obj, prop);
     uint64_t value;
     Error *local_err = NULL;
@@ -634,9 +625,8 @@ const PropertyInfo qdev_prop_multifd_compression = {
  *   and type is a non-negative decimal integer
  */
 static void get_reserved_region(Object *obj, Visitor *v, const char *name,
-                                void *opaque, Error **errp)
+                                 Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     ReservedRegion *rr = object_field_prop_ptr(obj, prop);
     char buffer[64];
     char *p = buffer;
@@ -650,9 +640,8 @@ 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)
+                                 Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     ReservedRegion *rr = object_field_prop_ptr(obj, prop);
     Error *local_err = NULL;
     const char *endptr;
@@ -712,9 +701,8 @@ const PropertyInfo qdev_prop_reserved_region = {
  * bus-local address, i.e. "$slot" or "$slot.$fn"
  */
 static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
-                          void *opaque, Error **errp)
+                           Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     int32_t value, *ptr = object_field_prop_ptr(obj, prop);
     unsigned int slot, fn, n;
     char *str;
@@ -774,9 +762,8 @@ const PropertyInfo qdev_prop_pci_devfn = {
 /* --- pci host address --- */
 
 static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
-                                 void *opaque, Error **errp)
+                                  Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     PCIHostDeviceAddress *addr = object_field_prop_ptr(obj, prop);
     char buffer[] = "ffff:ff:ff.f";
     char *p = buffer;
@@ -800,9 +787,8 @@ static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
  *   if <domain> is not supplied, it's assumed to be 0.
  */
 static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
-                                 void *opaque, Error **errp)
+                                  Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     PCIHostDeviceAddress *addr = object_field_prop_ptr(obj, prop);
     char *str, *p;
     const char *e;
@@ -889,9 +875,8 @@ const PropertyInfo qdev_prop_off_auto_pcibar = {
 /* --- PCIELinkSpeed 2_5/5/8/16 -- */
 
 static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
-                                   void *opaque, Error **errp)
+                                    Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     PCIExpLinkSpeed *p = object_field_prop_ptr(obj, prop);
     int speed;
 
@@ -917,9 +902,8 @@ 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)
+                                    Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     PCIExpLinkSpeed *p = object_field_prop_ptr(obj, prop);
     int speed;
 
@@ -959,9 +943,8 @@ const PropertyInfo qdev_prop_pcie_link_speed = {
 /* --- PCIELinkWidth 1/2/4/8/12/16/32 -- */
 
 static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
-                                   void *opaque, Error **errp)
+                                    Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     PCIExpLinkWidth *p = object_field_prop_ptr(obj, prop);
     int width;
 
@@ -996,9 +979,8 @@ 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)
+                                    Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     PCIExpLinkWidth *p = object_field_prop_ptr(obj, prop);
     int width;
 
@@ -1046,10 +1028,9 @@ const PropertyInfo qdev_prop_pcie_link_width = {
 
 /* --- UUID --- */
 
-static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
-                     Error **errp)
+static void get_uuid(Object *obj, Visitor *v, const char *name,
+                     Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     QemuUUID *uuid = object_field_prop_ptr(obj, prop);
     char buffer[UUID_FMT_LEN + 1];
     char *p = buffer;
@@ -1061,10 +1042,9 @@ static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
 
 #define UUID_VALUE_AUTO        "auto"
 
-static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
-                    Error **errp)
+static void set_uuid(Object *obj, Visitor *v, const char *name,
+                    Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     QemuUUID *uuid = object_field_prop_ptr(obj, prop);
     char *str;
 
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index fe47751df4..1400d80689 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -2341,9 +2341,8 @@ void css_reset(void)
 }
 
 static void get_css_devid(Object *obj, Visitor *v, const char *name,
-                          void *opaque, Error **errp)
+                           Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     CssDevId *dev_id = object_field_prop_ptr(obj, prop);
     char buffer[] = "xx.x.xxxx";
     char *p = buffer;
@@ -2370,9 +2369,8 @@ static void get_css_devid(Object *obj, Visitor *v, const char *name,
  * parse <cssid>.<ssid>.<devid> and assert valid range for cssid/ssid
  */
 static void set_css_devid(Object *obj, Visitor *v, const char *name,
-                          void *opaque, Error **errp)
+                           Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     CssDevId *dev_id = object_field_prop_ptr(obj, prop);
     char *str;
     int num, n1, n2;
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 99b18d56ba..a29bba17b4 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -1320,19 +1320,17 @@ static void s390_pci_device_reset(DeviceState *dev)
 }
 
 static void s390_pci_get_fid(Object *obj, Visitor *v, const char *name,
-                         void *opaque, Error **errp)
+                          Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     uint32_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_uint32(v, name, ptr, errp);
 }
 
 static void s390_pci_set_fid(Object *obj, Visitor *v, const char *name,
-                         void *opaque, Error **errp)
+                          Property *prop, Error **errp)
 {
     S390PCIBusDevice *zpci = S390_PCI_DEVICE(obj);
-    Property *prop = opaque;
     uint32_t *ptr = object_field_prop_ptr(obj, prop);
 
     if (!visit_type_uint32(v, name, ptr, errp)) {
diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
index fc8d63c850..34f5f5dce2 100644
--- a/hw/vfio/pci-quirks.c
+++ b/hw/vfio/pci-quirks.c
@@ -1485,20 +1485,18 @@ void vfio_setup_resetfn_quirk(VFIOPCIDevice *vdev)
  * https://lists.gnu.org/archive/html/qemu-devel/2017-08/pdfUda5iEpgOS.pdf
  */
 static void get_nv_gpudirect_clique_id(Object *obj, Visitor *v,
-                                       const char *name, void *opaque,
-                                       Error **errp)
+                                       const char *name,
+                                       Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     uint8_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_uint8(v, name, ptr, errp);
 }
 
 static void set_nv_gpudirect_clique_id(Object *obj, Visitor *v,
-                                       const char *name, void *opaque,
-                                       Error **errp)
+                                       const char *name,
+                                       Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     uint8_t value, *ptr = object_field_prop_ptr(obj, prop);
 
     if (!visit_type_uint8(v, name, &value, errp)) {
diff --git a/qom/property-types.c b/qom/property-types.c
index 856b5ae76d..82a5932f4a 100644
--- a/qom/property-types.c
+++ b/qom/property-types.c
@@ -8,18 +8,16 @@
 #include "qemu/uuid.h"
 
 void field_prop_get_enum(Object *obj, Visitor *v, const char *name,
-                         void *opaque, Error **errp)
+                          Property *prop, 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, Error **errp)
 {
-    Property *prop = opaque;
     int *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
@@ -59,9 +57,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)
+                          Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     uint32_t *p = object_field_prop_ptr(obj, prop);
     bool value = (*p & qdev_get_prop_mask(prop)) != 0;
 
@@ -69,9 +66,8 @@ 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)
+                          Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     bool value;
 
     if (!visit_type_bool(v, name, &value, errp)) {
@@ -113,9 +109,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)
+                            Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     uint64_t *p = object_field_prop_ptr(obj, prop);
     bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
 
@@ -123,9 +118,8 @@ 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)
+                            Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     bool value;
 
     if (!visit_type_bool(v, name, &value, errp)) {
@@ -144,19 +138,17 @@ const PropertyInfo prop_info_bit64 = {
 
 /* --- bool --- */
 
-static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
-                     Error **errp)
+static void get_bool(Object *obj, Visitor *v, const char *name,
+                     Property *prop, 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)
+static void set_bool(Object *obj, Visitor *v, const char *name,
+                     Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     bool *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_bool(v, name, ptr, errp);
@@ -171,19 +163,17 @@ const PropertyInfo prop_info_bool = {
 
 /* --- 8bit integer --- */
 
-static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
-                      Error **errp)
+static void get_uint8(Object *obj, Visitor *v, const char *name,
+                      Property *prop, 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)
+static void set_uint8(Object *obj, Visitor *v, const char *name,
+                      Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     uint8_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_uint8(v, name, ptr, errp);
@@ -211,18 +201,16 @@ const PropertyInfo prop_info_uint8 = {
 /* --- 16bit integer --- */
 
 static void get_uint16(Object *obj, Visitor *v, const char *name,
-                       void *opaque, Error **errp)
+                        Property *prop, 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, Error **errp)
 {
-    Property *prop = opaque;
     uint16_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_uint16(v, name, ptr, errp);
@@ -238,36 +226,32 @@ const PropertyInfo prop_info_uint16 = {
 /* --- 32bit integer --- */
 
 static void get_uint32(Object *obj, Visitor *v, const char *name,
-                       void *opaque, Error **errp)
+                        Property *prop, 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, 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, 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)
+static void set_int32(Object *obj, Visitor *v, const char *name,
+                      Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     int32_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_int32(v, name, ptr, errp);
@@ -290,36 +274,32 @@ const PropertyInfo prop_info_int32 = {
 /* --- 64bit integer --- */
 
 static void get_uint64(Object *obj, Visitor *v, const char *name,
-                       void *opaque, Error **errp)
+                        Property *prop, 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, 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, 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, Error **errp)
 {
-    Property *prop = opaque;
     int64_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_int64(v, name, ptr, errp);
@@ -348,9 +328,8 @@ static void release_string(Object *obj, const char *name, void *opaque)
 }
 
 static void get_string(Object *obj, Visitor *v, const char *name,
-                       void *opaque, Error **errp)
+                        Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     char **ptr = object_field_prop_ptr(obj, prop);
 
     if (!*ptr) {
@@ -362,9 +341,8 @@ 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)
+                        Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     char **ptr = object_field_prop_ptr(obj, prop);
     char *str;
 
@@ -396,19 +374,17 @@ const PropertyInfo prop_info_on_off_auto = {
 /* --- 32bit unsigned int 'size' type --- */
 
 void field_prop_get_size32(Object *obj, Visitor *v, const char *name,
-                           void *opaque, Error **errp)
+                            Property *prop, 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)
+static void set_size32(Object *obj, Visitor *v, const char *name,
+                       Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     uint32_t *ptr = object_field_prop_ptr(obj, prop);
     uint64_t value;
 
@@ -437,14 +413,8 @@ const PropertyInfo prop_info_size32 = {
 /* --- support for array properties --- */
 
 static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
-                              void *opaque, Error **errp)
+                               Property *prop, 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;
@@ -500,19 +470,17 @@ const PropertyInfo prop_info_arraylen = {
 
 /* --- 64bit unsigned int 'size' type --- */
 
-static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
-                     Error **errp)
+static void get_size(Object *obj, Visitor *v, const char *name,
+                     Property *prop, 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)
+static void set_size(Object *obj, Visitor *v, const char *name,
+                     Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     uint64_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_size(v, name, ptr, errp);
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 5a9397f19a..3acc99c29c 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -787,7 +787,7 @@ static void sparc_cpu_initfn(Object *obj)
 }
 
 static void sparc_get_nwindows(Object *obj, Visitor *v, const char *name,
-                               void *opaque, Error **errp)
+                               Property *prop, Error **errp)
 {
     SPARCCPU *cpu = SPARC_CPU(obj);
     int64_t value = cpu->env.def.nwindows;
@@ -796,7 +796,7 @@ 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)
+                               Property *prop, Error **errp)
 {
     const int64_t min = MIN_NWINDOWS;
     const int64_t max = MAX_NWINDOWS;
-- 
2.28.0



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

* [PATCH 4/7] qom: Replace void* parameter with Property* on field getters/setters
@ 2020-11-04 17:25   ` Eduardo Habkost
  0 siblings, 0 replies; 16+ messages in thread
From: Eduardo Habkost @ 2020-11-04 17:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: Igor Mammedov, Daniel P. Berrange, Paolo Bonzini, Stefan Berger,
	Stefano Stabellini, Anthony Perard, Paul Durrant, Kevin Wolf,
	Max Reitz, Richard Henderson, David Hildenbrand, Cornelia Huck,
	Thomas Huth, Halil Pasic, Christian Borntraeger, Matthew Rosato,
	Alex Williamson, Mark Cave-Ayland, Artyom Tarasenko, xen-devel,
	qemu-block, qemu-s390x

All field property getters and setters must interpret the fourth
argument as Property*.  Change the function signature of field
property getters and setters to indicate that.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
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: Richard Henderson <rth@twiddle.net>
Cc: David Hildenbrand <david@redhat.com>
Cc: Cornelia Huck <cohuck@redhat.com>
Cc: Thomas Huth <thuth@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: 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
---
 include/qom/field-property-internal.h |   8 +-
 include/qom/field-property.h          |  26 ++++---
 backends/tpm/tpm_util.c               |  11 ++-
 hw/block/xen-block.c                  |   6 +-
 hw/core/qdev-properties-system.c      |  86 +++++++++-------------
 hw/s390x/css.c                        |   6 +-
 hw/s390x/s390-pci-bus.c               |   6 +-
 hw/vfio/pci-quirks.c                  |  10 +--
 qom/property-types.c                  | 102 +++++++++-----------------
 target/sparc/cpu.c                    |   4 +-
 10 files changed, 105 insertions(+), 160 deletions(-)

diff --git a/include/qom/field-property-internal.h b/include/qom/field-property-internal.h
index 7aa27ce836..bc7d25033d 100644
--- a/include/qom/field-property-internal.h
+++ b/include/qom/field-property-internal.h
@@ -9,9 +9,9 @@
 #define QOM_STATIC_PROPERTY_INTERNAL_H
 
 void field_prop_get_enum(Object *obj, Visitor *v, const char *name,
-                         void *opaque, Error **errp);
+                         Property *prop, Error **errp);
 void field_prop_set_enum(Object *obj, Visitor *v, const char *name,
-                         void *opaque, Error **errp);
+                         Property *prop, Error **errp);
 
 void field_prop_set_default_value_enum(ObjectProperty *op,
                                        const Property *prop);
@@ -21,9 +21,9 @@ void field_prop_set_default_value_uint(ObjectProperty *op,
                                        const Property *prop);
 
 void field_prop_get_int32(Object *obj, Visitor *v, const char *name,
-                          void *opaque, Error **errp);
+                          Property *prop, Error **errp);
 void field_prop_get_size32(Object *obj, Visitor *v, const char *name,
-                           void *opaque, Error **errp);
+                           Property *prop, Error **errp);
 
 /**
  * object_property_add_field: Add a field property to an object instance
diff --git a/include/qom/field-property.h b/include/qom/field-property.h
index e64a2b3c07..438bb25896 100644
--- a/include/qom/field-property.h
+++ b/include/qom/field-property.h
@@ -54,6 +54,18 @@ struct Property {
     const char   *link_type;
 };
 
+/**
+ * typedef FieldAccessor: a field property getter or setter function
+ * @obj: the object instance
+ * @v: the visitor that contains the property data
+ * @name: the name of the property
+ * @prop: Field property definition
+ * @errp: pointer to error information
+ */
+typedef void FieldAccessor(Object *obj, Visitor *v,
+                           const char *name, Property *prop,
+                           Error **errp);
+
 /**
  * struct PropertyInfo: information on a specific QOM property type
  */
@@ -71,16 +83,10 @@ struct PropertyInfo {
     /** @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;
+    /** @get: Property getter */
+    FieldAccessor *get;
+    /** @set: Property setter */
+    FieldAccessor *set;
     /**
      * @release: Optional release function, called when the object
      * is destroyed
diff --git a/backends/tpm/tpm_util.c b/backends/tpm/tpm_util.c
index bb1ab34a75..e8837938e5 100644
--- a/backends/tpm/tpm_util.c
+++ b/backends/tpm/tpm_util.c
@@ -32,10 +32,10 @@
 
 /* tpm backend property */
 
-static void get_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
-                    Error **errp)
+static void get_tpm(Object *obj, Visitor *v, const char *name,
+                    Property *prop, Error **errp)
 {
-    TPMBackend **be = object_field_prop_ptr(obj, opaque);
+    TPMBackend **be = object_field_prop_ptr(obj, prop);
     char *p;
 
     p = g_strdup(*be ? (*be)->id : "");
@@ -43,10 +43,9 @@ static void get_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
     g_free(p);
 }
 
-static void set_tpm(Object *obj, Visitor *v, const char *name, void *opaque,
-                    Error **errp)
+static void set_tpm(Object *obj, Visitor *v, const char *name,
+                    Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     TPMBackend *s, **be = object_field_prop_ptr(obj, prop);
     char *str;
 
diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
index 718d886e5c..c1ee634639 100644
--- a/hw/block/xen-block.c
+++ b/hw/block/xen-block.c
@@ -333,9 +333,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)
+                                Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     XenBlockVdev *vdev = object_field_prop_ptr(obj, prop);
     char *str;
 
@@ -393,9 +392,8 @@ 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)
+                                Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     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 8da68f076c..4c649cb4b2 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -58,10 +58,9 @@ static bool check_prop_still_unset(Object *obj, const char *name,
 
 /* --- drive --- */
 
-static void get_drive(Object *obj, Visitor *v, const char *name, void *opaque,
-                      Error **errp)
+static void get_drive(Object *obj, Visitor *v, const char *name,
+                      Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     void **ptr = object_field_prop_ptr(obj, prop);
     const char *value;
     char *p;
@@ -165,16 +164,16 @@ fail:
     g_free(str);
 }
 
-static void set_drive(Object *obj, Visitor *v, const char *name, void *opaque,
+static void set_drive(Object *obj, Visitor *v, const char *name, Property *prop,
                       Error **errp)
 {
-    set_drive_helper(obj, v, name, opaque, false, errp);
+    set_drive_helper(obj, v, name, prop, false, errp);
 }
 
 static void set_drive_iothread(Object *obj, Visitor *v, const char *name,
-                               void *opaque, Error **errp)
+                               Property *prop, Error **errp)
 {
-    set_drive_helper(obj, v, name, opaque, true, errp);
+    set_drive_helper(obj, v, name, prop, true, errp);
 }
 
 static void release_drive(Object *obj, const char *name, void *opaque)
@@ -211,10 +210,10 @@ const PropertyInfo qdev_prop_drive_iothread = {
 
 /* --- character device --- */
 
-static void get_chr(Object *obj, Visitor *v, const char *name, void *opaque,
-                    Error **errp)
+static void get_chr(Object *obj, Visitor *v, const char *name,
+                    Property *prop, Error **errp)
 {
-    CharBackend *be = object_field_prop_ptr(obj, opaque);
+    CharBackend *be = object_field_prop_ptr(obj, prop);
     char *p;
 
     p = g_strdup(be->chr && be->chr->label ? be->chr->label : "");
@@ -222,10 +221,9 @@ static void get_chr(Object *obj, Visitor *v, const char *name, void *opaque,
     g_free(p);
 }
 
-static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque,
-                    Error **errp)
+static void set_chr(Object *obj, Visitor *v, const char *name,
+                    Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     CharBackend *be = object_field_prop_ptr(obj, prop);
     Chardev *s;
     char *str;
@@ -282,10 +280,9 @@ const PropertyInfo qdev_prop_chr = {
  *   01:02:03:04:05:06
  *   01-02-03-04-05-06
  */
-static void get_mac(Object *obj, Visitor *v, const char *name, void *opaque,
-                    Error **errp)
+static void get_mac(Object *obj, Visitor *v, const char *name,
+                    Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     MACAddr *mac = object_field_prop_ptr(obj, prop);
     char buffer[2 * 6 + 5 + 1];
     char *p = buffer;
@@ -297,10 +294,9 @@ static void get_mac(Object *obj, Visitor *v, const char *name, void *opaque,
     visit_type_str(v, name, &p, errp);
 }
 
-static void set_mac(Object *obj, Visitor *v, const char *name, void *opaque,
-                    Error **errp)
+static void set_mac(Object *obj, Visitor *v, const char *name,
+                    Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     MACAddr *mac = object_field_prop_ptr(obj, prop);
     int i, pos;
     char *str;
@@ -360,9 +356,8 @@ void qdev_prop_set_macaddr(DeviceState *dev, const char *name,
 
 /* --- netdev device --- */
 static void get_netdev(Object *obj, Visitor *v, const char *name,
-                       void *opaque, Error **errp)
+                        Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     NICPeers *peers_ptr = object_field_prop_ptr(obj, prop);
     char *p = g_strdup(peers_ptr->ncs[0] ? peers_ptr->ncs[0]->name : "");
 
@@ -371,9 +366,8 @@ 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)
+                        Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     NICPeers *peers_ptr = object_field_prop_ptr(obj, prop);
     NetClientState **ncs = peers_ptr->ncs;
     NetClientState *peers[MAX_QUEUE_NUM];
@@ -433,9 +427,8 @@ const PropertyInfo qdev_prop_netdev = {
 
 /* --- audiodev --- */
 static void get_audiodev(Object *obj, Visitor *v, const char* name,
-                         void *opaque, Error **errp)
+                          Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     QEMUSoundCard *card = object_field_prop_ptr(obj, prop);
     char *p = g_strdup(audio_get_id(card));
 
@@ -444,9 +437,8 @@ 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)
+                          Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     QEMUSoundCard *card = object_field_prop_ptr(obj, prop);
     AudioState *state;
     int err = 0;
@@ -545,10 +537,9 @@ const PropertyInfo qdev_prop_losttickpolicy = {
 /* --- blocksize --- */
 
 static void set_blocksize(Object *obj, Visitor *v, const char *name,
-                          void *opaque, Error **errp)
+                           Property *prop, Error **errp)
 {
     DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
     uint32_t *ptr = object_field_prop_ptr(obj, prop);
     uint64_t value;
     Error *local_err = NULL;
@@ -634,9 +625,8 @@ const PropertyInfo qdev_prop_multifd_compression = {
  *   and type is a non-negative decimal integer
  */
 static void get_reserved_region(Object *obj, Visitor *v, const char *name,
-                                void *opaque, Error **errp)
+                                 Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     ReservedRegion *rr = object_field_prop_ptr(obj, prop);
     char buffer[64];
     char *p = buffer;
@@ -650,9 +640,8 @@ 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)
+                                 Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     ReservedRegion *rr = object_field_prop_ptr(obj, prop);
     Error *local_err = NULL;
     const char *endptr;
@@ -712,9 +701,8 @@ const PropertyInfo qdev_prop_reserved_region = {
  * bus-local address, i.e. "$slot" or "$slot.$fn"
  */
 static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
-                          void *opaque, Error **errp)
+                           Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     int32_t value, *ptr = object_field_prop_ptr(obj, prop);
     unsigned int slot, fn, n;
     char *str;
@@ -774,9 +762,8 @@ const PropertyInfo qdev_prop_pci_devfn = {
 /* --- pci host address --- */
 
 static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
-                                 void *opaque, Error **errp)
+                                  Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     PCIHostDeviceAddress *addr = object_field_prop_ptr(obj, prop);
     char buffer[] = "ffff:ff:ff.f";
     char *p = buffer;
@@ -800,9 +787,8 @@ static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
  *   if <domain> is not supplied, it's assumed to be 0.
  */
 static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
-                                 void *opaque, Error **errp)
+                                  Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     PCIHostDeviceAddress *addr = object_field_prop_ptr(obj, prop);
     char *str, *p;
     const char *e;
@@ -889,9 +875,8 @@ const PropertyInfo qdev_prop_off_auto_pcibar = {
 /* --- PCIELinkSpeed 2_5/5/8/16 -- */
 
 static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
-                                   void *opaque, Error **errp)
+                                    Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     PCIExpLinkSpeed *p = object_field_prop_ptr(obj, prop);
     int speed;
 
@@ -917,9 +902,8 @@ 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)
+                                    Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     PCIExpLinkSpeed *p = object_field_prop_ptr(obj, prop);
     int speed;
 
@@ -959,9 +943,8 @@ const PropertyInfo qdev_prop_pcie_link_speed = {
 /* --- PCIELinkWidth 1/2/4/8/12/16/32 -- */
 
 static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
-                                   void *opaque, Error **errp)
+                                    Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     PCIExpLinkWidth *p = object_field_prop_ptr(obj, prop);
     int width;
 
@@ -996,9 +979,8 @@ 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)
+                                    Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     PCIExpLinkWidth *p = object_field_prop_ptr(obj, prop);
     int width;
 
@@ -1046,10 +1028,9 @@ const PropertyInfo qdev_prop_pcie_link_width = {
 
 /* --- UUID --- */
 
-static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
-                     Error **errp)
+static void get_uuid(Object *obj, Visitor *v, const char *name,
+                     Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     QemuUUID *uuid = object_field_prop_ptr(obj, prop);
     char buffer[UUID_FMT_LEN + 1];
     char *p = buffer;
@@ -1061,10 +1042,9 @@ static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
 
 #define UUID_VALUE_AUTO        "auto"
 
-static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
-                    Error **errp)
+static void set_uuid(Object *obj, Visitor *v, const char *name,
+                    Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     QemuUUID *uuid = object_field_prop_ptr(obj, prop);
     char *str;
 
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index fe47751df4..1400d80689 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -2341,9 +2341,8 @@ void css_reset(void)
 }
 
 static void get_css_devid(Object *obj, Visitor *v, const char *name,
-                          void *opaque, Error **errp)
+                           Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     CssDevId *dev_id = object_field_prop_ptr(obj, prop);
     char buffer[] = "xx.x.xxxx";
     char *p = buffer;
@@ -2370,9 +2369,8 @@ static void get_css_devid(Object *obj, Visitor *v, const char *name,
  * parse <cssid>.<ssid>.<devid> and assert valid range for cssid/ssid
  */
 static void set_css_devid(Object *obj, Visitor *v, const char *name,
-                          void *opaque, Error **errp)
+                           Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     CssDevId *dev_id = object_field_prop_ptr(obj, prop);
     char *str;
     int num, n1, n2;
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 99b18d56ba..a29bba17b4 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -1320,19 +1320,17 @@ static void s390_pci_device_reset(DeviceState *dev)
 }
 
 static void s390_pci_get_fid(Object *obj, Visitor *v, const char *name,
-                         void *opaque, Error **errp)
+                          Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     uint32_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_uint32(v, name, ptr, errp);
 }
 
 static void s390_pci_set_fid(Object *obj, Visitor *v, const char *name,
-                         void *opaque, Error **errp)
+                          Property *prop, Error **errp)
 {
     S390PCIBusDevice *zpci = S390_PCI_DEVICE(obj);
-    Property *prop = opaque;
     uint32_t *ptr = object_field_prop_ptr(obj, prop);
 
     if (!visit_type_uint32(v, name, ptr, errp)) {
diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
index fc8d63c850..34f5f5dce2 100644
--- a/hw/vfio/pci-quirks.c
+++ b/hw/vfio/pci-quirks.c
@@ -1485,20 +1485,18 @@ void vfio_setup_resetfn_quirk(VFIOPCIDevice *vdev)
  * https://lists.gnu.org/archive/html/qemu-devel/2017-08/pdfUda5iEpgOS.pdf
  */
 static void get_nv_gpudirect_clique_id(Object *obj, Visitor *v,
-                                       const char *name, void *opaque,
-                                       Error **errp)
+                                       const char *name,
+                                       Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     uint8_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_uint8(v, name, ptr, errp);
 }
 
 static void set_nv_gpudirect_clique_id(Object *obj, Visitor *v,
-                                       const char *name, void *opaque,
-                                       Error **errp)
+                                       const char *name,
+                                       Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     uint8_t value, *ptr = object_field_prop_ptr(obj, prop);
 
     if (!visit_type_uint8(v, name, &value, errp)) {
diff --git a/qom/property-types.c b/qom/property-types.c
index 856b5ae76d..82a5932f4a 100644
--- a/qom/property-types.c
+++ b/qom/property-types.c
@@ -8,18 +8,16 @@
 #include "qemu/uuid.h"
 
 void field_prop_get_enum(Object *obj, Visitor *v, const char *name,
-                         void *opaque, Error **errp)
+                          Property *prop, 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, Error **errp)
 {
-    Property *prop = opaque;
     int *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
@@ -59,9 +57,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)
+                          Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     uint32_t *p = object_field_prop_ptr(obj, prop);
     bool value = (*p & qdev_get_prop_mask(prop)) != 0;
 
@@ -69,9 +66,8 @@ 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)
+                          Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     bool value;
 
     if (!visit_type_bool(v, name, &value, errp)) {
@@ -113,9 +109,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)
+                            Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     uint64_t *p = object_field_prop_ptr(obj, prop);
     bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
 
@@ -123,9 +118,8 @@ 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)
+                            Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     bool value;
 
     if (!visit_type_bool(v, name, &value, errp)) {
@@ -144,19 +138,17 @@ const PropertyInfo prop_info_bit64 = {
 
 /* --- bool --- */
 
-static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
-                     Error **errp)
+static void get_bool(Object *obj, Visitor *v, const char *name,
+                     Property *prop, 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)
+static void set_bool(Object *obj, Visitor *v, const char *name,
+                     Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     bool *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_bool(v, name, ptr, errp);
@@ -171,19 +163,17 @@ const PropertyInfo prop_info_bool = {
 
 /* --- 8bit integer --- */
 
-static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
-                      Error **errp)
+static void get_uint8(Object *obj, Visitor *v, const char *name,
+                      Property *prop, 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)
+static void set_uint8(Object *obj, Visitor *v, const char *name,
+                      Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     uint8_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_uint8(v, name, ptr, errp);
@@ -211,18 +201,16 @@ const PropertyInfo prop_info_uint8 = {
 /* --- 16bit integer --- */
 
 static void get_uint16(Object *obj, Visitor *v, const char *name,
-                       void *opaque, Error **errp)
+                        Property *prop, 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, Error **errp)
 {
-    Property *prop = opaque;
     uint16_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_uint16(v, name, ptr, errp);
@@ -238,36 +226,32 @@ const PropertyInfo prop_info_uint16 = {
 /* --- 32bit integer --- */
 
 static void get_uint32(Object *obj, Visitor *v, const char *name,
-                       void *opaque, Error **errp)
+                        Property *prop, 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, 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, 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)
+static void set_int32(Object *obj, Visitor *v, const char *name,
+                      Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     int32_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_int32(v, name, ptr, errp);
@@ -290,36 +274,32 @@ const PropertyInfo prop_info_int32 = {
 /* --- 64bit integer --- */
 
 static void get_uint64(Object *obj, Visitor *v, const char *name,
-                       void *opaque, Error **errp)
+                        Property *prop, 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, 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, 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, Error **errp)
 {
-    Property *prop = opaque;
     int64_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_int64(v, name, ptr, errp);
@@ -348,9 +328,8 @@ static void release_string(Object *obj, const char *name, void *opaque)
 }
 
 static void get_string(Object *obj, Visitor *v, const char *name,
-                       void *opaque, Error **errp)
+                        Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     char **ptr = object_field_prop_ptr(obj, prop);
 
     if (!*ptr) {
@@ -362,9 +341,8 @@ 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)
+                        Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     char **ptr = object_field_prop_ptr(obj, prop);
     char *str;
 
@@ -396,19 +374,17 @@ const PropertyInfo prop_info_on_off_auto = {
 /* --- 32bit unsigned int 'size' type --- */
 
 void field_prop_get_size32(Object *obj, Visitor *v, const char *name,
-                           void *opaque, Error **errp)
+                            Property *prop, 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)
+static void set_size32(Object *obj, Visitor *v, const char *name,
+                       Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     uint32_t *ptr = object_field_prop_ptr(obj, prop);
     uint64_t value;
 
@@ -437,14 +413,8 @@ const PropertyInfo prop_info_size32 = {
 /* --- support for array properties --- */
 
 static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
-                              void *opaque, Error **errp)
+                               Property *prop, 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;
@@ -500,19 +470,17 @@ const PropertyInfo prop_info_arraylen = {
 
 /* --- 64bit unsigned int 'size' type --- */
 
-static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
-                     Error **errp)
+static void get_size(Object *obj, Visitor *v, const char *name,
+                     Property *prop, 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)
+static void set_size(Object *obj, Visitor *v, const char *name,
+                     Property *prop, Error **errp)
 {
-    Property *prop = opaque;
     uint64_t *ptr = object_field_prop_ptr(obj, prop);
 
     visit_type_size(v, name, ptr, errp);
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 5a9397f19a..3acc99c29c 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -787,7 +787,7 @@ static void sparc_cpu_initfn(Object *obj)
 }
 
 static void sparc_get_nwindows(Object *obj, Visitor *v, const char *name,
-                               void *opaque, Error **errp)
+                               Property *prop, Error **errp)
 {
     SPARCCPU *cpu = SPARC_CPU(obj);
     int64_t value = cpu->env.def.nwindows;
@@ -796,7 +796,7 @@ 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)
+                               Property *prop, Error **errp)
 {
     const int64_t min = MIN_NWINDOWS;
     const int64_t max = MAX_NWINDOWS;
-- 
2.28.0



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

* [PATCH 5/7] qom: Replace void* parameter with Property* on PropertyInfo.release
  2020-11-04 17:25 [PATCH 0/7] qom: Field properties type safety Eduardo Habkost
                   ` (3 preceding siblings ...)
  2020-11-04 17:25   ` Eduardo Habkost
@ 2020-11-04 17:25 ` Eduardo Habkost
  2020-11-04 17:25   ` Eduardo Habkost
  2020-11-04 17:25 ` [PATCH 7/7] sparc: Use FIELD_PTR at nwindows getter/setter Eduardo Habkost
  6 siblings, 0 replies; 16+ messages in thread
From: Eduardo Habkost @ 2020-11-04 17:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: Igor Mammedov, Stefan Berger, Daniel P. Berrange, Paolo Bonzini

The release function must interpret the third argument as
Property*.  Change the signature of PropertyInfo.release to
indicate that.

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
---
 include/qom/field-property.h     | 11 ++++++++++-
 backends/tpm/tpm_util.c          |  3 +--
 hw/core/qdev-properties-system.c |  6 ++----
 qom/field-property.c             | 13 +++++++++++--
 qom/property-types.c             |  3 +--
 5 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/include/qom/field-property.h b/include/qom/field-property.h
index 438bb25896..1d3bf9699b 100644
--- a/include/qom/field-property.h
+++ b/include/qom/field-property.h
@@ -66,6 +66,15 @@ typedef void FieldAccessor(Object *obj, Visitor *v,
                            const char *name, Property *prop,
                            Error **errp);
 
+/**
+ * typedef FieldRelease:
+ * @obj: the object instance
+ * @name: the name of the property
+ * @prop: Field property definition
+ */
+typedef void FieldRelease(Object *obj, const char *name, Property *prop);
+
+
 /**
  * struct PropertyInfo: information on a specific QOM property type
  */
@@ -91,7 +100,7 @@ struct PropertyInfo {
      * @release: Optional release function, called when the object
      * is destroyed
      */
-    ObjectPropertyRelease *release;
+    FieldRelease *release;
 };
 
 /**
diff --git a/backends/tpm/tpm_util.c b/backends/tpm/tpm_util.c
index e8837938e5..556e21388c 100644
--- a/backends/tpm/tpm_util.c
+++ b/backends/tpm/tpm_util.c
@@ -63,9 +63,8 @@ static void set_tpm(Object *obj, Visitor *v, const char *name,
     g_free(str);
 }
 
-static void release_tpm(Object *obj, const char *name, void *opaque)
+static void release_tpm(Object *obj, const char *name, Property *prop)
 {
-    Property *prop = opaque;
     TPMBackend **be = object_field_prop_ptr(obj, prop);
 
     if (*be) {
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 4c649cb4b2..2fdd5863bb 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -176,10 +176,9 @@ static void set_drive_iothread(Object *obj, Visitor *v, const char *name,
     set_drive_helper(obj, v, name, prop, true, errp);
 }
 
-static void release_drive(Object *obj, const char *name, void *opaque)
+static void release_drive(Object *obj, const char *name, Property *prop)
 {
     DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
     BlockBackend **ptr = object_field_prop_ptr(obj, prop);
 
     if (*ptr) {
@@ -257,9 +256,8 @@ static void set_chr(Object *obj, Visitor *v, const char *name,
     g_free(str);
 }
 
-static void release_chr(Object *obj, const char *name, void *opaque)
+static void release_chr(Object *obj, const char *name, Property *prop)
 {
-    Property *prop = opaque;
     CharBackend *be = object_field_prop_ptr(obj, prop);
 
     qemu_chr_fe_deinit(be, false);
diff --git a/qom/field-property.c b/qom/field-property.c
index 25a818bb69..865d4929a3 100644
--- a/qom/field-property.c
+++ b/qom/field-property.c
@@ -47,6 +47,15 @@ static ObjectPropertyAccessor *field_prop_setter(const PropertyInfo *info)
     return info->set ? field_prop_set : NULL;
 }
 
+static void field_prop_release(Object *obj, const char *name, void *opaque)
+{
+    Property *prop = opaque;
+    if (prop->info->release) {
+        prop->info->release(obj, name, prop);
+    }
+}
+
+
 ObjectProperty *
 object_property_add_field(Object *obj, const char *name, Property *prop,
                           ObjectPropertyAllowSet allow_set)
@@ -59,7 +68,7 @@ object_property_add_field(Object *obj, const char *name, Property *prop,
     op = object_property_add(obj, name, prop->info->name,
                              field_prop_getter(prop->info),
                              field_prop_setter(prop->info),
-                             prop->info->release,
+                             field_prop_release,
                              prop);
 
     object_property_set_description(obj, name,
@@ -92,7 +101,7 @@ object_class_property_add_field(ObjectClass *oc, const char *name,
                                        name, prop->info->name,
                                        field_prop_getter(prop->info),
                                        field_prop_setter(prop->info),
-                                       prop->info->release,
+                                       field_prop_release,
                                        prop);
     }
     if (prop->set_default) {
diff --git a/qom/property-types.c b/qom/property-types.c
index 82a5932f4a..0182a73e38 100644
--- a/qom/property-types.c
+++ b/qom/property-types.c
@@ -321,9 +321,8 @@ const PropertyInfo prop_info_int64 = {
 
 /* --- string --- */
 
-static void release_string(Object *obj, const char *name, void *opaque)
+static void release_string(Object *obj, const char *name, Property *prop)
 {
-    Property *prop = opaque;
     g_free(*(char **)object_field_prop_ptr(obj, prop));
 }
 
-- 
2.28.0



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

* [PATCH 6/7] qom: Add FIELD_PTR, a type-safe wrapper for object_field_prop_ptr()
  2020-11-04 17:25 [PATCH 0/7] qom: Field properties type safety Eduardo Habkost
@ 2020-11-04 17:25   ` Eduardo Habkost
  2020-11-04 17:25 ` [PATCH 2/7] qom: Save size of struct field in Property struct Eduardo Habkost
                     ` (5 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Eduardo Habkost @ 2020-11-04 17:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Thomas Huth, Stefano Stabellini, Daniel P. Berrange,
	xen-devel, Matthew Rosato, Stefan Berger, Cornelia Huck,
	Paul Durrant, David Hildenbrand, qemu-s390x, Max Reitz,
	Halil Pasic, Christian Borntraeger, Alex Williamson,
	Paolo Bonzini, Anthony Perard, Igor Mammedov, qemu-block,
	Richard Henderson

Introduce a FIELD_PTR macro that will ensure the size of the area
we are accessing has the correct size, and will return a pointer
of the correct type.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
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: 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: 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/qom/field-property.h     | 21 ++++++++++-
 backends/tpm/tpm_util.c          |  6 ++--
 hw/block/xen-block.c             |  4 +--
 hw/core/qdev-properties-system.c | 50 +++++++++++++-------------
 hw/s390x/css.c                   |  4 +--
 hw/s390x/s390-pci-bus.c          |  4 +--
 hw/vfio/pci-quirks.c             |  4 +--
 qom/field-property.c             |  3 +-
 qom/property-types.c             | 60 +++++++++++++++++---------------
 9 files changed, 89 insertions(+), 67 deletions(-)

diff --git a/include/qom/field-property.h b/include/qom/field-property.h
index 1d3bf9699b..58baaca160 100644
--- a/include/qom/field-property.h
+++ b/include/qom/field-property.h
@@ -125,6 +125,25 @@ object_class_property_add_field(ObjectClass *oc, const char *name,
                                 Property *prop,
                                 ObjectPropertyAllowSet allow_set);
 
-void *object_field_prop_ptr(Object *obj, Property *prop);
+/**
+ * object_field_prop_ptr: Get pointer to property field
+ * @obj: the object instance
+ * @prop: field property definition
+ * @expected_size: expected size of struct field
+ *
+ * Don't use this function directly, use the FIELD_PTR() macro instead.
+ */
+void *object_field_prop_ptr(Object *obj, Property *prop, size_t expected_size);
+
+/**
+ * FIELD_PTR: Get pointer to struct field for property
+ *
+ * This returns a pointer to type @type, pointing to the struct
+ * field containing the property value.
+ *
+ * @type must match the expected type for the property.
+ */
+#define FIELD_PTR(obj, prop, type) \
+    ((type *)object_field_prop_ptr((obj), (prop), sizeof(type)))
 
 #endif
diff --git a/backends/tpm/tpm_util.c b/backends/tpm/tpm_util.c
index 556e21388c..da80379404 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,
                     Property *prop, Error **errp)
 {
-    TPMBackend **be = object_field_prop_ptr(obj, prop);
+    TPMBackend **be = FIELD_PTR(obj, prop, TPMBackend *);
     char *p;
 
     p = g_strdup(*be ? (*be)->id : "");
@@ -46,7 +46,7 @@ static void get_tpm(Object *obj, Visitor *v, const char *name,
 static void set_tpm(Object *obj, Visitor *v, const char *name,
                     Property *prop, Error **errp)
 {
-    TPMBackend *s, **be = object_field_prop_ptr(obj, prop);
+    TPMBackend *s, **be = FIELD_PTR(obj, prop, TPMBackend *);
     char *str;
 
     if (!visit_type_str(v, name, &str, errp)) {
@@ -65,7 +65,7 @@ static void set_tpm(Object *obj, Visitor *v, const char *name,
 
 static void release_tpm(Object *obj, const char *name, Property *prop)
 {
-    TPMBackend **be = object_field_prop_ptr(obj, prop);
+    TPMBackend **be = FIELD_PTR(obj, prop, TPMBackend *);
 
     if (*be) {
         tpm_backend_reset(*be);
diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
index c1ee634639..390bf417ab 100644
--- a/hw/block/xen-block.c
+++ b/hw/block/xen-block.c
@@ -335,7 +335,7 @@ static char *disk_to_vbd_name(unsigned int disk)
 static void xen_block_get_vdev(Object *obj, Visitor *v, const char *name,
                                 Property *prop, Error **errp)
 {
-    XenBlockVdev *vdev = object_field_prop_ptr(obj, prop);
+    XenBlockVdev *vdev = FIELD_PTR(obj, prop, XenBlockVdev);
     char *str;
 
     switch (vdev->type) {
@@ -394,7 +394,7 @@ 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,
                                 Property *prop, Error **errp)
 {
-    XenBlockVdev *vdev = object_field_prop_ptr(obj, prop);
+    XenBlockVdev *vdev = FIELD_PTR(obj, prop, XenBlockVdev);
     char *str, *p;
     const char *end;
 
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 2fdd5863bb..1ec64514b9 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -61,7 +61,7 @@ static bool check_prop_still_unset(Object *obj, const char *name,
 static void get_drive(Object *obj, Visitor *v, const char *name,
                       Property *prop, Error **errp)
 {
-    void **ptr = object_field_prop_ptr(obj, prop);
+    void **ptr = FIELD_PTR(obj, prop, void *);
     const char *value;
     char *p;
 
@@ -87,7 +87,7 @@ static void set_drive_helper(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    void **ptr = object_field_prop_ptr(obj, prop);
+    void **ptr = FIELD_PTR(obj, prop, void *);
     char *str;
     BlockBackend *blk;
     bool blk_created = false;
@@ -179,7 +179,7 @@ static void set_drive_iothread(Object *obj, Visitor *v, const char *name,
 static void release_drive(Object *obj, const char *name, Property *prop)
 {
     DeviceState *dev = DEVICE(obj);
-    BlockBackend **ptr = object_field_prop_ptr(obj, prop);
+    BlockBackend **ptr = FIELD_PTR(obj, prop, BlockBackend *);
 
     if (*ptr) {
         AioContext *ctx = blk_get_aio_context(*ptr);
@@ -212,7 +212,7 @@ const PropertyInfo qdev_prop_drive_iothread = {
 static void get_chr(Object *obj, Visitor *v, const char *name,
                     Property *prop, Error **errp)
 {
-    CharBackend *be = object_field_prop_ptr(obj, prop);
+    CharBackend *be = FIELD_PTR(obj, prop, CharBackend);
     char *p;
 
     p = g_strdup(be->chr && be->chr->label ? be->chr->label : "");
@@ -223,7 +223,7 @@ static void get_chr(Object *obj, Visitor *v, const char *name,
 static void set_chr(Object *obj, Visitor *v, const char *name,
                     Property *prop, Error **errp)
 {
-    CharBackend *be = object_field_prop_ptr(obj, prop);
+    CharBackend *be = FIELD_PTR(obj, prop, CharBackend);
     Chardev *s;
     char *str;
 
@@ -258,7 +258,7 @@ static void set_chr(Object *obj, Visitor *v, const char *name,
 
 static void release_chr(Object *obj, const char *name, Property *prop)
 {
-    CharBackend *be = object_field_prop_ptr(obj, prop);
+    CharBackend *be = FIELD_PTR(obj, prop, CharBackend);
 
     qemu_chr_fe_deinit(be, false);
 }
@@ -281,7 +281,7 @@ const PropertyInfo qdev_prop_chr = {
 static void get_mac(Object *obj, Visitor *v, const char *name,
                     Property *prop, Error **errp)
 {
-    MACAddr *mac = object_field_prop_ptr(obj, prop);
+    MACAddr *mac = FIELD_PTR(obj, prop, MACAddr);
     char buffer[2 * 6 + 5 + 1];
     char *p = buffer;
 
@@ -295,7 +295,7 @@ static void get_mac(Object *obj, Visitor *v, const char *name,
 static void set_mac(Object *obj, Visitor *v, const char *name,
                     Property *prop, Error **errp)
 {
-    MACAddr *mac = object_field_prop_ptr(obj, prop);
+    MACAddr *mac = FIELD_PTR(obj, prop, MACAddr);
     int i, pos;
     char *str;
     const char *p;
@@ -356,7 +356,7 @@ void qdev_prop_set_macaddr(DeviceState *dev, const char *name,
 static void get_netdev(Object *obj, Visitor *v, const char *name,
                         Property *prop, Error **errp)
 {
-    NICPeers *peers_ptr = object_field_prop_ptr(obj, prop);
+    NICPeers *peers_ptr = FIELD_PTR(obj, prop, NICPeers);
     char *p = g_strdup(peers_ptr->ncs[0] ? peers_ptr->ncs[0]->name : "");
 
     visit_type_str(v, name, &p, errp);
@@ -366,7 +366,7 @@ static void get_netdev(Object *obj, Visitor *v, const char *name,
 static void set_netdev(Object *obj, Visitor *v, const char *name,
                         Property *prop, Error **errp)
 {
-    NICPeers *peers_ptr = object_field_prop_ptr(obj, prop);
+    NICPeers *peers_ptr = FIELD_PTR(obj, prop, NICPeers);
     NetClientState **ncs = peers_ptr->ncs;
     NetClientState *peers[MAX_QUEUE_NUM];
     int queues, err = 0, i = 0;
@@ -427,7 +427,7 @@ const PropertyInfo qdev_prop_netdev = {
 static void get_audiodev(Object *obj, Visitor *v, const char* name,
                           Property *prop, Error **errp)
 {
-    QEMUSoundCard *card = object_field_prop_ptr(obj, prop);
+    QEMUSoundCard *card = FIELD_PTR(obj, prop, QEMUSoundCard);
     char *p = g_strdup(audio_get_id(card));
 
     visit_type_str(v, name, &p, errp);
@@ -437,7 +437,7 @@ static void get_audiodev(Object *obj, Visitor *v, const char* name,
 static void set_audiodev(Object *obj, Visitor *v, const char* name,
                           Property *prop, Error **errp)
 {
-    QEMUSoundCard *card = object_field_prop_ptr(obj, prop);
+    QEMUSoundCard *card = FIELD_PTR(obj, prop, QEMUSoundCard);
     AudioState *state;
     int err = 0;
     char *str;
@@ -538,7 +538,7 @@ static void set_blocksize(Object *obj, Visitor *v, const char *name,
                            Property *prop, Error **errp)
 {
     DeviceState *dev = DEVICE(obj);
-    uint32_t *ptr = object_field_prop_ptr(obj, prop);
+    uint32_t *ptr = FIELD_PTR(obj, prop, uint32_t);
     uint64_t value;
     Error *local_err = NULL;
 
@@ -625,7 +625,7 @@ const PropertyInfo qdev_prop_multifd_compression = {
 static void get_reserved_region(Object *obj, Visitor *v, const char *name,
                                  Property *prop, Error **errp)
 {
-    ReservedRegion *rr = object_field_prop_ptr(obj, prop);
+    ReservedRegion *rr = FIELD_PTR(obj, prop, ReservedRegion);
     char buffer[64];
     char *p = buffer;
     int rc;
@@ -640,7 +640,7 @@ static void get_reserved_region(Object *obj, Visitor *v, const char *name,
 static void set_reserved_region(Object *obj, Visitor *v, const char *name,
                                  Property *prop, Error **errp)
 {
-    ReservedRegion *rr = object_field_prop_ptr(obj, prop);
+    ReservedRegion *rr = FIELD_PTR(obj, prop, ReservedRegion);
     Error *local_err = NULL;
     const char *endptr;
     char *str;
@@ -701,7 +701,7 @@ const PropertyInfo qdev_prop_reserved_region = {
 static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
                            Property *prop, Error **errp)
 {
-    int32_t value, *ptr = object_field_prop_ptr(obj, prop);
+    int32_t value, *ptr = FIELD_PTR(obj, prop, int32_t);
     unsigned int slot, fn, n;
     char *str;
 
@@ -739,7 +739,7 @@ invalid:
 static int print_pci_devfn(Object *obj, Property *prop, char *dest,
                            size_t len)
 {
-    int32_t *ptr = object_field_prop_ptr(obj, prop);
+    int32_t *ptr = FIELD_PTR(obj, prop, int32_t);
 
     if (*ptr == -1) {
         return snprintf(dest, len, "<unset>");
@@ -762,7 +762,7 @@ const PropertyInfo qdev_prop_pci_devfn = {
 static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
                                   Property *prop, Error **errp)
 {
-    PCIHostDeviceAddress *addr = object_field_prop_ptr(obj, prop);
+    PCIHostDeviceAddress *addr = FIELD_PTR(obj, prop, PCIHostDeviceAddress);
     char buffer[] = "ffff:ff:ff.f";
     char *p = buffer;
     int rc = 0;
@@ -787,7 +787,7 @@ 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,
                                   Property *prop, Error **errp)
 {
-    PCIHostDeviceAddress *addr = object_field_prop_ptr(obj, prop);
+    PCIHostDeviceAddress *addr = FIELD_PTR(obj, prop, PCIHostDeviceAddress);
     char *str, *p;
     const char *e;
     unsigned long val;
@@ -875,7 +875,7 @@ const PropertyInfo qdev_prop_off_auto_pcibar = {
 static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
                                     Property *prop, Error **errp)
 {
-    PCIExpLinkSpeed *p = object_field_prop_ptr(obj, prop);
+    PCIExpLinkSpeed *p = FIELD_PTR(obj, prop, PCIExpLinkSpeed);
     int speed;
 
     switch (*p) {
@@ -902,7 +902,7 @@ static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
 static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
                                     Property *prop, Error **errp)
 {
-    PCIExpLinkSpeed *p = object_field_prop_ptr(obj, prop);
+    PCIExpLinkSpeed *p = FIELD_PTR(obj, prop, PCIExpLinkSpeed);
     int speed;
 
     if (!visit_type_enum(v, name, &speed, prop->info->enum_table,
@@ -943,7 +943,7 @@ const PropertyInfo qdev_prop_pcie_link_speed = {
 static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
                                     Property *prop, Error **errp)
 {
-    PCIExpLinkWidth *p = object_field_prop_ptr(obj, prop);
+    PCIExpLinkWidth *p = FIELD_PTR(obj, prop, PCIExpLinkWidth);
     int width;
 
     switch (*p) {
@@ -979,7 +979,7 @@ static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
 static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
                                     Property *prop, Error **errp)
 {
-    PCIExpLinkWidth *p = object_field_prop_ptr(obj, prop);
+    PCIExpLinkWidth *p = FIELD_PTR(obj, prop, PCIExpLinkWidth);
     int width;
 
     if (!visit_type_enum(v, name, &width, prop->info->enum_table,
@@ -1029,7 +1029,7 @@ const PropertyInfo qdev_prop_pcie_link_width = {
 static void get_uuid(Object *obj, Visitor *v, const char *name,
                      Property *prop, Error **errp)
 {
-    QemuUUID *uuid = object_field_prop_ptr(obj, prop);
+    QemuUUID *uuid = FIELD_PTR(obj, prop, QemuUUID);
     char buffer[UUID_FMT_LEN + 1];
     char *p = buffer;
 
@@ -1043,7 +1043,7 @@ static void get_uuid(Object *obj, Visitor *v, const char *name,
 static void set_uuid(Object *obj, Visitor *v, const char *name,
                     Property *prop, Error **errp)
 {
-    QemuUUID *uuid = object_field_prop_ptr(obj, prop);
+    QemuUUID *uuid = FIELD_PTR(obj, prop, QemuUUID);
     char *str;
 
     if (!visit_type_str(v, name, &str, errp)) {
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 1400d80689..5a38919a05 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -2343,7 +2343,7 @@ void css_reset(void)
 static void get_css_devid(Object *obj, Visitor *v, const char *name,
                            Property *prop, Error **errp)
 {
-    CssDevId *dev_id = object_field_prop_ptr(obj, prop);
+    CssDevId *dev_id = FIELD_PTR(obj, prop, CssDevId);
     char buffer[] = "xx.x.xxxx";
     char *p = buffer;
     int r;
@@ -2371,7 +2371,7 @@ static void get_css_devid(Object *obj, Visitor *v, const char *name,
 static void set_css_devid(Object *obj, Visitor *v, const char *name,
                            Property *prop, Error **errp)
 {
-    CssDevId *dev_id = object_field_prop_ptr(obj, prop);
+    CssDevId *dev_id = FIELD_PTR(obj, prop, CssDevId);
     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 a29bba17b4..8e38787c99 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -1322,7 +1322,7 @@ static void s390_pci_device_reset(DeviceState *dev)
 static void s390_pci_get_fid(Object *obj, Visitor *v, const char *name,
                           Property *prop, Error **errp)
 {
-    uint32_t *ptr = object_field_prop_ptr(obj, prop);
+    uint32_t *ptr = FIELD_PTR(obj, prop, uint32_t);
 
     visit_type_uint32(v, name, ptr, errp);
 }
@@ -1331,7 +1331,7 @@ static void s390_pci_set_fid(Object *obj, Visitor *v, const char *name,
                           Property *prop, Error **errp)
 {
     S390PCIBusDevice *zpci = S390_PCI_DEVICE(obj);
-    uint32_t *ptr = object_field_prop_ptr(obj, prop);
+    uint32_t *ptr = FIELD_PTR(obj, prop, uint32_t);
 
     if (!visit_type_uint32(v, name, ptr, errp)) {
         return;
diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
index 34f5f5dce2..93fb507ec4 100644
--- a/hw/vfio/pci-quirks.c
+++ b/hw/vfio/pci-quirks.c
@@ -1488,7 +1488,7 @@ static void get_nv_gpudirect_clique_id(Object *obj, Visitor *v,
                                        const char *name,
                                        Property *prop, Error **errp)
 {
-    uint8_t *ptr = object_field_prop_ptr(obj, prop);
+    uint8_t *ptr = FIELD_PTR(obj, prop, uint8_t);
 
     visit_type_uint8(v, name, ptr, errp);
 }
@@ -1497,7 +1497,7 @@ static void set_nv_gpudirect_clique_id(Object *obj, Visitor *v,
                                        const char *name,
                                        Property *prop, Error **errp)
 {
-    uint8_t value, *ptr = object_field_prop_ptr(obj, prop);
+    uint8_t value, *ptr = FIELD_PTR(obj, prop, uint8_t);
 
     if (!visit_type_uint8(v, name, &value, errp)) {
         return;
diff --git a/qom/field-property.c b/qom/field-property.c
index 865d4929a3..0932a799de 100644
--- a/qom/field-property.c
+++ b/qom/field-property.c
@@ -5,10 +5,11 @@
 #include "qom/field-property.h"
 #include "qom/field-property-internal.h"
 
-void *object_field_prop_ptr(Object *obj, Property *prop)
+void *object_field_prop_ptr(Object *obj, Property *prop, size_t expected_size)
 {
     void *ptr = obj;
     ptr += prop->offset;
+    assert(prop->size == expected_size);
     return ptr;
 }
 
diff --git a/qom/property-types.c b/qom/property-types.c
index 0182a73e38..e01f5a9fef 100644
--- a/qom/property-types.c
+++ b/qom/property-types.c
@@ -10,7 +10,7 @@
 void field_prop_get_enum(Object *obj, Visitor *v, const char *name,
                           Property *prop, Error **errp)
 {
-    int *ptr = object_field_prop_ptr(obj, prop);
+    int *ptr = FIELD_PTR(obj, prop, int);
 
     visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
 }
@@ -18,7 +18,7 @@ void field_prop_get_enum(Object *obj, Visitor *v, const char *name,
 void field_prop_set_enum(Object *obj, Visitor *v, const char *name,
                           Property *prop, Error **errp)
 {
-    int *ptr = object_field_prop_ptr(obj, prop);
+    int *ptr = FIELD_PTR(obj, prop, int);
 
     visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
 }
@@ -47,7 +47,7 @@ static uint32_t qdev_get_prop_mask(Property *prop)
 
 static void bit_prop_set(Object *obj, Property *props, bool val)
 {
-    uint32_t *p = object_field_prop_ptr(obj, props);
+    uint32_t *p = FIELD_PTR(obj, props, uint32_t);
     uint32_t mask = qdev_get_prop_mask(props);
     if (val) {
         *p |= mask;
@@ -59,7 +59,7 @@ static void bit_prop_set(Object *obj, Property *props, bool val)
 static void prop_get_bit(Object *obj, Visitor *v, const char *name,
                           Property *prop, Error **errp)
 {
-    uint32_t *p = object_field_prop_ptr(obj, prop);
+    uint32_t *p = FIELD_PTR(obj, prop, uint32_t);
     bool value = (*p & qdev_get_prop_mask(prop)) != 0;
 
     visit_type_bool(v, name, &value, errp);
@@ -99,7 +99,7 @@ static uint64_t qdev_get_prop_mask64(Property *prop)
 
 static void bit64_prop_set(Object *obj, Property *props, bool val)
 {
-    uint64_t *p = object_field_prop_ptr(obj, props);
+    uint64_t *p = FIELD_PTR(obj, props, uint64_t);
     uint64_t mask = qdev_get_prop_mask64(props);
     if (val) {
         *p |= mask;
@@ -111,7 +111,7 @@ static void bit64_prop_set(Object *obj, Property *props, bool val)
 static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
                             Property *prop, Error **errp)
 {
-    uint64_t *p = object_field_prop_ptr(obj, prop);
+    uint64_t *p = FIELD_PTR(obj, prop, uint64_t);
     bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
 
     visit_type_bool(v, name, &value, errp);
@@ -141,7 +141,7 @@ const PropertyInfo prop_info_bit64 = {
 static void get_bool(Object *obj, Visitor *v, const char *name,
                      Property *prop, Error **errp)
 {
-    bool *ptr = object_field_prop_ptr(obj, prop);
+    bool *ptr = FIELD_PTR(obj, prop, bool);
 
     visit_type_bool(v, name, ptr, errp);
 }
@@ -149,7 +149,7 @@ static void get_bool(Object *obj, Visitor *v, const char *name,
 static void set_bool(Object *obj, Visitor *v, const char *name,
                      Property *prop, Error **errp)
 {
-    bool *ptr = object_field_prop_ptr(obj, prop);
+    bool *ptr = FIELD_PTR(obj, prop, bool);
 
     visit_type_bool(v, name, ptr, errp);
 }
@@ -166,7 +166,7 @@ const PropertyInfo prop_info_bool = {
 static void get_uint8(Object *obj, Visitor *v, const char *name,
                       Property *prop, Error **errp)
 {
-    uint8_t *ptr = object_field_prop_ptr(obj, prop);
+    uint8_t *ptr = FIELD_PTR(obj, prop, uint8_t);
 
     visit_type_uint8(v, name, ptr, errp);
 }
@@ -174,7 +174,7 @@ static void get_uint8(Object *obj, Visitor *v, const char *name,
 static void set_uint8(Object *obj, Visitor *v, const char *name,
                       Property *prop, Error **errp)
 {
-    uint8_t *ptr = object_field_prop_ptr(obj, prop);
+    uint8_t *ptr = FIELD_PTR(obj, prop, uint8_t);
 
     visit_type_uint8(v, name, ptr, errp);
 }
@@ -203,7 +203,7 @@ const PropertyInfo prop_info_uint8 = {
 static void get_uint16(Object *obj, Visitor *v, const char *name,
                         Property *prop, Error **errp)
 {
-    uint16_t *ptr = object_field_prop_ptr(obj, prop);
+    uint16_t *ptr = FIELD_PTR(obj, prop, uint16_t);
 
     visit_type_uint16(v, name, ptr, errp);
 }
@@ -211,7 +211,7 @@ static void get_uint16(Object *obj, Visitor *v, const char *name,
 static void set_uint16(Object *obj, Visitor *v, const char *name,
                         Property *prop, Error **errp)
 {
-    uint16_t *ptr = object_field_prop_ptr(obj, prop);
+    uint16_t *ptr = FIELD_PTR(obj, prop, uint16_t);
 
     visit_type_uint16(v, name, ptr, errp);
 }
@@ -228,7 +228,7 @@ const PropertyInfo prop_info_uint16 = {
 static void get_uint32(Object *obj, Visitor *v, const char *name,
                         Property *prop, Error **errp)
 {
-    uint32_t *ptr = object_field_prop_ptr(obj, prop);
+    uint32_t *ptr = FIELD_PTR(obj, prop, uint32_t);
 
     visit_type_uint32(v, name, ptr, errp);
 }
@@ -236,7 +236,7 @@ static void get_uint32(Object *obj, Visitor *v, const char *name,
 static void set_uint32(Object *obj, Visitor *v, const char *name,
                         Property *prop, Error **errp)
 {
-    uint32_t *ptr = object_field_prop_ptr(obj, prop);
+    uint32_t *ptr = FIELD_PTR(obj, prop, uint32_t);
 
     visit_type_uint32(v, name, ptr, errp);
 }
@@ -244,7 +244,7 @@ static void set_uint32(Object *obj, Visitor *v, const char *name,
 void field_prop_get_int32(Object *obj, Visitor *v, const char *name,
                            Property *prop, Error **errp)
 {
-    int32_t *ptr = object_field_prop_ptr(obj, prop);
+    int32_t *ptr = FIELD_PTR(obj, prop, int32_t);
 
     visit_type_int32(v, name, ptr, errp);
 }
@@ -252,7 +252,7 @@ void field_prop_get_int32(Object *obj, Visitor *v, const char *name,
 static void set_int32(Object *obj, Visitor *v, const char *name,
                       Property *prop, Error **errp)
 {
-    int32_t *ptr = object_field_prop_ptr(obj, prop);
+    int32_t *ptr = FIELD_PTR(obj, prop, int32_t);
 
     visit_type_int32(v, name, ptr, errp);
 }
@@ -276,7 +276,7 @@ const PropertyInfo prop_info_int32 = {
 static void get_uint64(Object *obj, Visitor *v, const char *name,
                         Property *prop, Error **errp)
 {
-    uint64_t *ptr = object_field_prop_ptr(obj, prop);
+    uint64_t *ptr = FIELD_PTR(obj, prop, uint64_t);
 
     visit_type_uint64(v, name, ptr, errp);
 }
@@ -284,7 +284,7 @@ static void get_uint64(Object *obj, Visitor *v, const char *name,
 static void set_uint64(Object *obj, Visitor *v, const char *name,
                         Property *prop, Error **errp)
 {
-    uint64_t *ptr = object_field_prop_ptr(obj, prop);
+    uint64_t *ptr = FIELD_PTR(obj, prop, uint64_t);
 
     visit_type_uint64(v, name, ptr, errp);
 }
@@ -292,7 +292,7 @@ static void set_uint64(Object *obj, Visitor *v, const char *name,
 static void get_int64(Object *obj, Visitor *v, const char *name,
                        Property *prop, Error **errp)
 {
-    int64_t *ptr = object_field_prop_ptr(obj, prop);
+    int64_t *ptr = FIELD_PTR(obj, prop, int64_t);
 
     visit_type_int64(v, name, ptr, errp);
 }
@@ -300,7 +300,7 @@ static void get_int64(Object *obj, Visitor *v, const char *name,
 static void set_int64(Object *obj, Visitor *v, const char *name,
                        Property *prop, Error **errp)
 {
-    int64_t *ptr = object_field_prop_ptr(obj, prop);
+    int64_t *ptr = FIELD_PTR(obj, prop, int64_t);
 
     visit_type_int64(v, name, ptr, errp);
 }
@@ -323,13 +323,14 @@ const PropertyInfo prop_info_int64 = {
 
 static void release_string(Object *obj, const char *name, Property *prop)
 {
-    g_free(*(char **)object_field_prop_ptr(obj, prop));
+    char **ptr = FIELD_PTR(obj, prop, char *);
+    g_free(*ptr);
 }
 
 static void get_string(Object *obj, Visitor *v, const char *name,
                         Property *prop, Error **errp)
 {
-    char **ptr = object_field_prop_ptr(obj, prop);
+    char **ptr = FIELD_PTR(obj, prop, char *);
 
     if (!*ptr) {
         char *str = (char *)"";
@@ -342,7 +343,7 @@ static void get_string(Object *obj, Visitor *v, const char *name,
 static void set_string(Object *obj, Visitor *v, const char *name,
                         Property *prop, Error **errp)
 {
-    char **ptr = object_field_prop_ptr(obj, prop);
+    char **ptr = FIELD_PTR(obj, prop, char *);
     char *str;
 
     if (!visit_type_str(v, name, &str, errp)) {
@@ -375,7 +376,7 @@ const PropertyInfo prop_info_on_off_auto = {
 void field_prop_get_size32(Object *obj, Visitor *v, const char *name,
                             Property *prop, Error **errp)
 {
-    uint32_t *ptr = object_field_prop_ptr(obj, prop);
+    uint32_t *ptr = FIELD_PTR(obj, prop, uint32_t);
     uint64_t value = *ptr;
 
     visit_type_size(v, name, &value, errp);
@@ -384,7 +385,7 @@ void field_prop_get_size32(Object *obj, Visitor *v, const char *name,
 static void set_size32(Object *obj, Visitor *v, const char *name,
                        Property *prop, Error **errp)
 {
-    uint32_t *ptr = object_field_prop_ptr(obj, prop);
+    uint32_t *ptr = FIELD_PTR(obj, prop, uint32_t);
     uint64_t value;
 
     if (!visit_type_size(v, name, &value, errp)) {
@@ -415,7 +416,7 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
                                Property *prop, Error **errp)
 {
     ObjectProperty *op = object_property_find_err(obj, name, &error_abort);
-    uint32_t *alenptr = object_field_prop_ptr(obj, prop);
+    uint32_t *alenptr = FIELD_PTR(obj, prop, uint32_t);
     void **arrayptr = (void *)obj + prop->arrayoffset;
     void *eltptr;
     const char *arrayname;
@@ -455,7 +456,8 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
          */
         arrayprop->offset = eltptr - (void *)obj;
         arrayprop->size = prop->arrayfieldsize;
-        assert(object_field_prop_ptr(obj, arrayprop) == eltptr);
+        assert(object_field_prop_ptr(obj, arrayprop,
+                                     prop->arrayfieldsize) == eltptr);
         object_property_add_field(obj, propname, arrayprop, op->allow_set);
     }
 }
@@ -472,7 +474,7 @@ const PropertyInfo prop_info_arraylen = {
 static void get_size(Object *obj, Visitor *v, const char *name,
                      Property *prop, Error **errp)
 {
-    uint64_t *ptr = object_field_prop_ptr(obj, prop);
+    uint64_t *ptr = FIELD_PTR(obj, prop, uint64_t);
 
     visit_type_size(v, name, ptr, errp);
 }
@@ -480,7 +482,7 @@ static void get_size(Object *obj, Visitor *v, const char *name,
 static void set_size(Object *obj, Visitor *v, const char *name,
                      Property *prop, Error **errp)
 {
-    uint64_t *ptr = object_field_prop_ptr(obj, prop);
+    uint64_t *ptr = FIELD_PTR(obj, prop, uint64_t);
 
     visit_type_size(v, name, ptr, errp);
 }
-- 
2.28.0



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

* [PATCH 6/7] qom: Add FIELD_PTR, a type-safe wrapper for object_field_prop_ptr()
@ 2020-11-04 17:25   ` Eduardo Habkost
  0 siblings, 0 replies; 16+ messages in thread
From: Eduardo Habkost @ 2020-11-04 17:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: Igor Mammedov, Daniel P. Berrange, Paolo Bonzini, Stefan Berger,
	Stefano Stabellini, Anthony Perard, Paul Durrant, Kevin Wolf,
	Max Reitz, Cornelia Huck, Thomas Huth, Halil Pasic,
	Christian Borntraeger, Richard Henderson, David Hildenbrand,
	Matthew Rosato, Alex Williamson, xen-devel, qemu-block,
	qemu-s390x

Introduce a FIELD_PTR macro that will ensure the size of the area
we are accessing has the correct size, and will return a pointer
of the correct type.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
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: 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: 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/qom/field-property.h     | 21 ++++++++++-
 backends/tpm/tpm_util.c          |  6 ++--
 hw/block/xen-block.c             |  4 +--
 hw/core/qdev-properties-system.c | 50 +++++++++++++-------------
 hw/s390x/css.c                   |  4 +--
 hw/s390x/s390-pci-bus.c          |  4 +--
 hw/vfio/pci-quirks.c             |  4 +--
 qom/field-property.c             |  3 +-
 qom/property-types.c             | 60 +++++++++++++++++---------------
 9 files changed, 89 insertions(+), 67 deletions(-)

diff --git a/include/qom/field-property.h b/include/qom/field-property.h
index 1d3bf9699b..58baaca160 100644
--- a/include/qom/field-property.h
+++ b/include/qom/field-property.h
@@ -125,6 +125,25 @@ object_class_property_add_field(ObjectClass *oc, const char *name,
                                 Property *prop,
                                 ObjectPropertyAllowSet allow_set);
 
-void *object_field_prop_ptr(Object *obj, Property *prop);
+/**
+ * object_field_prop_ptr: Get pointer to property field
+ * @obj: the object instance
+ * @prop: field property definition
+ * @expected_size: expected size of struct field
+ *
+ * Don't use this function directly, use the FIELD_PTR() macro instead.
+ */
+void *object_field_prop_ptr(Object *obj, Property *prop, size_t expected_size);
+
+/**
+ * FIELD_PTR: Get pointer to struct field for property
+ *
+ * This returns a pointer to type @type, pointing to the struct
+ * field containing the property value.
+ *
+ * @type must match the expected type for the property.
+ */
+#define FIELD_PTR(obj, prop, type) \
+    ((type *)object_field_prop_ptr((obj), (prop), sizeof(type)))
 
 #endif
diff --git a/backends/tpm/tpm_util.c b/backends/tpm/tpm_util.c
index 556e21388c..da80379404 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,
                     Property *prop, Error **errp)
 {
-    TPMBackend **be = object_field_prop_ptr(obj, prop);
+    TPMBackend **be = FIELD_PTR(obj, prop, TPMBackend *);
     char *p;
 
     p = g_strdup(*be ? (*be)->id : "");
@@ -46,7 +46,7 @@ static void get_tpm(Object *obj, Visitor *v, const char *name,
 static void set_tpm(Object *obj, Visitor *v, const char *name,
                     Property *prop, Error **errp)
 {
-    TPMBackend *s, **be = object_field_prop_ptr(obj, prop);
+    TPMBackend *s, **be = FIELD_PTR(obj, prop, TPMBackend *);
     char *str;
 
     if (!visit_type_str(v, name, &str, errp)) {
@@ -65,7 +65,7 @@ static void set_tpm(Object *obj, Visitor *v, const char *name,
 
 static void release_tpm(Object *obj, const char *name, Property *prop)
 {
-    TPMBackend **be = object_field_prop_ptr(obj, prop);
+    TPMBackend **be = FIELD_PTR(obj, prop, TPMBackend *);
 
     if (*be) {
         tpm_backend_reset(*be);
diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
index c1ee634639..390bf417ab 100644
--- a/hw/block/xen-block.c
+++ b/hw/block/xen-block.c
@@ -335,7 +335,7 @@ static char *disk_to_vbd_name(unsigned int disk)
 static void xen_block_get_vdev(Object *obj, Visitor *v, const char *name,
                                 Property *prop, Error **errp)
 {
-    XenBlockVdev *vdev = object_field_prop_ptr(obj, prop);
+    XenBlockVdev *vdev = FIELD_PTR(obj, prop, XenBlockVdev);
     char *str;
 
     switch (vdev->type) {
@@ -394,7 +394,7 @@ 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,
                                 Property *prop, Error **errp)
 {
-    XenBlockVdev *vdev = object_field_prop_ptr(obj, prop);
+    XenBlockVdev *vdev = FIELD_PTR(obj, prop, XenBlockVdev);
     char *str, *p;
     const char *end;
 
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 2fdd5863bb..1ec64514b9 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -61,7 +61,7 @@ static bool check_prop_still_unset(Object *obj, const char *name,
 static void get_drive(Object *obj, Visitor *v, const char *name,
                       Property *prop, Error **errp)
 {
-    void **ptr = object_field_prop_ptr(obj, prop);
+    void **ptr = FIELD_PTR(obj, prop, void *);
     const char *value;
     char *p;
 
@@ -87,7 +87,7 @@ static void set_drive_helper(Object *obj, Visitor *v, const char *name,
 {
     DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
-    void **ptr = object_field_prop_ptr(obj, prop);
+    void **ptr = FIELD_PTR(obj, prop, void *);
     char *str;
     BlockBackend *blk;
     bool blk_created = false;
@@ -179,7 +179,7 @@ static void set_drive_iothread(Object *obj, Visitor *v, const char *name,
 static void release_drive(Object *obj, const char *name, Property *prop)
 {
     DeviceState *dev = DEVICE(obj);
-    BlockBackend **ptr = object_field_prop_ptr(obj, prop);
+    BlockBackend **ptr = FIELD_PTR(obj, prop, BlockBackend *);
 
     if (*ptr) {
         AioContext *ctx = blk_get_aio_context(*ptr);
@@ -212,7 +212,7 @@ const PropertyInfo qdev_prop_drive_iothread = {
 static void get_chr(Object *obj, Visitor *v, const char *name,
                     Property *prop, Error **errp)
 {
-    CharBackend *be = object_field_prop_ptr(obj, prop);
+    CharBackend *be = FIELD_PTR(obj, prop, CharBackend);
     char *p;
 
     p = g_strdup(be->chr && be->chr->label ? be->chr->label : "");
@@ -223,7 +223,7 @@ static void get_chr(Object *obj, Visitor *v, const char *name,
 static void set_chr(Object *obj, Visitor *v, const char *name,
                     Property *prop, Error **errp)
 {
-    CharBackend *be = object_field_prop_ptr(obj, prop);
+    CharBackend *be = FIELD_PTR(obj, prop, CharBackend);
     Chardev *s;
     char *str;
 
@@ -258,7 +258,7 @@ static void set_chr(Object *obj, Visitor *v, const char *name,
 
 static void release_chr(Object *obj, const char *name, Property *prop)
 {
-    CharBackend *be = object_field_prop_ptr(obj, prop);
+    CharBackend *be = FIELD_PTR(obj, prop, CharBackend);
 
     qemu_chr_fe_deinit(be, false);
 }
@@ -281,7 +281,7 @@ const PropertyInfo qdev_prop_chr = {
 static void get_mac(Object *obj, Visitor *v, const char *name,
                     Property *prop, Error **errp)
 {
-    MACAddr *mac = object_field_prop_ptr(obj, prop);
+    MACAddr *mac = FIELD_PTR(obj, prop, MACAddr);
     char buffer[2 * 6 + 5 + 1];
     char *p = buffer;
 
@@ -295,7 +295,7 @@ static void get_mac(Object *obj, Visitor *v, const char *name,
 static void set_mac(Object *obj, Visitor *v, const char *name,
                     Property *prop, Error **errp)
 {
-    MACAddr *mac = object_field_prop_ptr(obj, prop);
+    MACAddr *mac = FIELD_PTR(obj, prop, MACAddr);
     int i, pos;
     char *str;
     const char *p;
@@ -356,7 +356,7 @@ void qdev_prop_set_macaddr(DeviceState *dev, const char *name,
 static void get_netdev(Object *obj, Visitor *v, const char *name,
                         Property *prop, Error **errp)
 {
-    NICPeers *peers_ptr = object_field_prop_ptr(obj, prop);
+    NICPeers *peers_ptr = FIELD_PTR(obj, prop, NICPeers);
     char *p = g_strdup(peers_ptr->ncs[0] ? peers_ptr->ncs[0]->name : "");
 
     visit_type_str(v, name, &p, errp);
@@ -366,7 +366,7 @@ static void get_netdev(Object *obj, Visitor *v, const char *name,
 static void set_netdev(Object *obj, Visitor *v, const char *name,
                         Property *prop, Error **errp)
 {
-    NICPeers *peers_ptr = object_field_prop_ptr(obj, prop);
+    NICPeers *peers_ptr = FIELD_PTR(obj, prop, NICPeers);
     NetClientState **ncs = peers_ptr->ncs;
     NetClientState *peers[MAX_QUEUE_NUM];
     int queues, err = 0, i = 0;
@@ -427,7 +427,7 @@ const PropertyInfo qdev_prop_netdev = {
 static void get_audiodev(Object *obj, Visitor *v, const char* name,
                           Property *prop, Error **errp)
 {
-    QEMUSoundCard *card = object_field_prop_ptr(obj, prop);
+    QEMUSoundCard *card = FIELD_PTR(obj, prop, QEMUSoundCard);
     char *p = g_strdup(audio_get_id(card));
 
     visit_type_str(v, name, &p, errp);
@@ -437,7 +437,7 @@ static void get_audiodev(Object *obj, Visitor *v, const char* name,
 static void set_audiodev(Object *obj, Visitor *v, const char* name,
                           Property *prop, Error **errp)
 {
-    QEMUSoundCard *card = object_field_prop_ptr(obj, prop);
+    QEMUSoundCard *card = FIELD_PTR(obj, prop, QEMUSoundCard);
     AudioState *state;
     int err = 0;
     char *str;
@@ -538,7 +538,7 @@ static void set_blocksize(Object *obj, Visitor *v, const char *name,
                            Property *prop, Error **errp)
 {
     DeviceState *dev = DEVICE(obj);
-    uint32_t *ptr = object_field_prop_ptr(obj, prop);
+    uint32_t *ptr = FIELD_PTR(obj, prop, uint32_t);
     uint64_t value;
     Error *local_err = NULL;
 
@@ -625,7 +625,7 @@ const PropertyInfo qdev_prop_multifd_compression = {
 static void get_reserved_region(Object *obj, Visitor *v, const char *name,
                                  Property *prop, Error **errp)
 {
-    ReservedRegion *rr = object_field_prop_ptr(obj, prop);
+    ReservedRegion *rr = FIELD_PTR(obj, prop, ReservedRegion);
     char buffer[64];
     char *p = buffer;
     int rc;
@@ -640,7 +640,7 @@ static void get_reserved_region(Object *obj, Visitor *v, const char *name,
 static void set_reserved_region(Object *obj, Visitor *v, const char *name,
                                  Property *prop, Error **errp)
 {
-    ReservedRegion *rr = object_field_prop_ptr(obj, prop);
+    ReservedRegion *rr = FIELD_PTR(obj, prop, ReservedRegion);
     Error *local_err = NULL;
     const char *endptr;
     char *str;
@@ -701,7 +701,7 @@ const PropertyInfo qdev_prop_reserved_region = {
 static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
                            Property *prop, Error **errp)
 {
-    int32_t value, *ptr = object_field_prop_ptr(obj, prop);
+    int32_t value, *ptr = FIELD_PTR(obj, prop, int32_t);
     unsigned int slot, fn, n;
     char *str;
 
@@ -739,7 +739,7 @@ invalid:
 static int print_pci_devfn(Object *obj, Property *prop, char *dest,
                            size_t len)
 {
-    int32_t *ptr = object_field_prop_ptr(obj, prop);
+    int32_t *ptr = FIELD_PTR(obj, prop, int32_t);
 
     if (*ptr == -1) {
         return snprintf(dest, len, "<unset>");
@@ -762,7 +762,7 @@ const PropertyInfo qdev_prop_pci_devfn = {
 static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
                                   Property *prop, Error **errp)
 {
-    PCIHostDeviceAddress *addr = object_field_prop_ptr(obj, prop);
+    PCIHostDeviceAddress *addr = FIELD_PTR(obj, prop, PCIHostDeviceAddress);
     char buffer[] = "ffff:ff:ff.f";
     char *p = buffer;
     int rc = 0;
@@ -787,7 +787,7 @@ 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,
                                   Property *prop, Error **errp)
 {
-    PCIHostDeviceAddress *addr = object_field_prop_ptr(obj, prop);
+    PCIHostDeviceAddress *addr = FIELD_PTR(obj, prop, PCIHostDeviceAddress);
     char *str, *p;
     const char *e;
     unsigned long val;
@@ -875,7 +875,7 @@ const PropertyInfo qdev_prop_off_auto_pcibar = {
 static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
                                     Property *prop, Error **errp)
 {
-    PCIExpLinkSpeed *p = object_field_prop_ptr(obj, prop);
+    PCIExpLinkSpeed *p = FIELD_PTR(obj, prop, PCIExpLinkSpeed);
     int speed;
 
     switch (*p) {
@@ -902,7 +902,7 @@ static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
 static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
                                     Property *prop, Error **errp)
 {
-    PCIExpLinkSpeed *p = object_field_prop_ptr(obj, prop);
+    PCIExpLinkSpeed *p = FIELD_PTR(obj, prop, PCIExpLinkSpeed);
     int speed;
 
     if (!visit_type_enum(v, name, &speed, prop->info->enum_table,
@@ -943,7 +943,7 @@ const PropertyInfo qdev_prop_pcie_link_speed = {
 static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
                                     Property *prop, Error **errp)
 {
-    PCIExpLinkWidth *p = object_field_prop_ptr(obj, prop);
+    PCIExpLinkWidth *p = FIELD_PTR(obj, prop, PCIExpLinkWidth);
     int width;
 
     switch (*p) {
@@ -979,7 +979,7 @@ static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
 static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
                                     Property *prop, Error **errp)
 {
-    PCIExpLinkWidth *p = object_field_prop_ptr(obj, prop);
+    PCIExpLinkWidth *p = FIELD_PTR(obj, prop, PCIExpLinkWidth);
     int width;
 
     if (!visit_type_enum(v, name, &width, prop->info->enum_table,
@@ -1029,7 +1029,7 @@ const PropertyInfo qdev_prop_pcie_link_width = {
 static void get_uuid(Object *obj, Visitor *v, const char *name,
                      Property *prop, Error **errp)
 {
-    QemuUUID *uuid = object_field_prop_ptr(obj, prop);
+    QemuUUID *uuid = FIELD_PTR(obj, prop, QemuUUID);
     char buffer[UUID_FMT_LEN + 1];
     char *p = buffer;
 
@@ -1043,7 +1043,7 @@ static void get_uuid(Object *obj, Visitor *v, const char *name,
 static void set_uuid(Object *obj, Visitor *v, const char *name,
                     Property *prop, Error **errp)
 {
-    QemuUUID *uuid = object_field_prop_ptr(obj, prop);
+    QemuUUID *uuid = FIELD_PTR(obj, prop, QemuUUID);
     char *str;
 
     if (!visit_type_str(v, name, &str, errp)) {
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 1400d80689..5a38919a05 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -2343,7 +2343,7 @@ void css_reset(void)
 static void get_css_devid(Object *obj, Visitor *v, const char *name,
                            Property *prop, Error **errp)
 {
-    CssDevId *dev_id = object_field_prop_ptr(obj, prop);
+    CssDevId *dev_id = FIELD_PTR(obj, prop, CssDevId);
     char buffer[] = "xx.x.xxxx";
     char *p = buffer;
     int r;
@@ -2371,7 +2371,7 @@ static void get_css_devid(Object *obj, Visitor *v, const char *name,
 static void set_css_devid(Object *obj, Visitor *v, const char *name,
                            Property *prop, Error **errp)
 {
-    CssDevId *dev_id = object_field_prop_ptr(obj, prop);
+    CssDevId *dev_id = FIELD_PTR(obj, prop, CssDevId);
     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 a29bba17b4..8e38787c99 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -1322,7 +1322,7 @@ static void s390_pci_device_reset(DeviceState *dev)
 static void s390_pci_get_fid(Object *obj, Visitor *v, const char *name,
                           Property *prop, Error **errp)
 {
-    uint32_t *ptr = object_field_prop_ptr(obj, prop);
+    uint32_t *ptr = FIELD_PTR(obj, prop, uint32_t);
 
     visit_type_uint32(v, name, ptr, errp);
 }
@@ -1331,7 +1331,7 @@ static void s390_pci_set_fid(Object *obj, Visitor *v, const char *name,
                           Property *prop, Error **errp)
 {
     S390PCIBusDevice *zpci = S390_PCI_DEVICE(obj);
-    uint32_t *ptr = object_field_prop_ptr(obj, prop);
+    uint32_t *ptr = FIELD_PTR(obj, prop, uint32_t);
 
     if (!visit_type_uint32(v, name, ptr, errp)) {
         return;
diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
index 34f5f5dce2..93fb507ec4 100644
--- a/hw/vfio/pci-quirks.c
+++ b/hw/vfio/pci-quirks.c
@@ -1488,7 +1488,7 @@ static void get_nv_gpudirect_clique_id(Object *obj, Visitor *v,
                                        const char *name,
                                        Property *prop, Error **errp)
 {
-    uint8_t *ptr = object_field_prop_ptr(obj, prop);
+    uint8_t *ptr = FIELD_PTR(obj, prop, uint8_t);
 
     visit_type_uint8(v, name, ptr, errp);
 }
@@ -1497,7 +1497,7 @@ static void set_nv_gpudirect_clique_id(Object *obj, Visitor *v,
                                        const char *name,
                                        Property *prop, Error **errp)
 {
-    uint8_t value, *ptr = object_field_prop_ptr(obj, prop);
+    uint8_t value, *ptr = FIELD_PTR(obj, prop, uint8_t);
 
     if (!visit_type_uint8(v, name, &value, errp)) {
         return;
diff --git a/qom/field-property.c b/qom/field-property.c
index 865d4929a3..0932a799de 100644
--- a/qom/field-property.c
+++ b/qom/field-property.c
@@ -5,10 +5,11 @@
 #include "qom/field-property.h"
 #include "qom/field-property-internal.h"
 
-void *object_field_prop_ptr(Object *obj, Property *prop)
+void *object_field_prop_ptr(Object *obj, Property *prop, size_t expected_size)
 {
     void *ptr = obj;
     ptr += prop->offset;
+    assert(prop->size == expected_size);
     return ptr;
 }
 
diff --git a/qom/property-types.c b/qom/property-types.c
index 0182a73e38..e01f5a9fef 100644
--- a/qom/property-types.c
+++ b/qom/property-types.c
@@ -10,7 +10,7 @@
 void field_prop_get_enum(Object *obj, Visitor *v, const char *name,
                           Property *prop, Error **errp)
 {
-    int *ptr = object_field_prop_ptr(obj, prop);
+    int *ptr = FIELD_PTR(obj, prop, int);
 
     visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
 }
@@ -18,7 +18,7 @@ void field_prop_get_enum(Object *obj, Visitor *v, const char *name,
 void field_prop_set_enum(Object *obj, Visitor *v, const char *name,
                           Property *prop, Error **errp)
 {
-    int *ptr = object_field_prop_ptr(obj, prop);
+    int *ptr = FIELD_PTR(obj, prop, int);
 
     visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
 }
@@ -47,7 +47,7 @@ static uint32_t qdev_get_prop_mask(Property *prop)
 
 static void bit_prop_set(Object *obj, Property *props, bool val)
 {
-    uint32_t *p = object_field_prop_ptr(obj, props);
+    uint32_t *p = FIELD_PTR(obj, props, uint32_t);
     uint32_t mask = qdev_get_prop_mask(props);
     if (val) {
         *p |= mask;
@@ -59,7 +59,7 @@ static void bit_prop_set(Object *obj, Property *props, bool val)
 static void prop_get_bit(Object *obj, Visitor *v, const char *name,
                           Property *prop, Error **errp)
 {
-    uint32_t *p = object_field_prop_ptr(obj, prop);
+    uint32_t *p = FIELD_PTR(obj, prop, uint32_t);
     bool value = (*p & qdev_get_prop_mask(prop)) != 0;
 
     visit_type_bool(v, name, &value, errp);
@@ -99,7 +99,7 @@ static uint64_t qdev_get_prop_mask64(Property *prop)
 
 static void bit64_prop_set(Object *obj, Property *props, bool val)
 {
-    uint64_t *p = object_field_prop_ptr(obj, props);
+    uint64_t *p = FIELD_PTR(obj, props, uint64_t);
     uint64_t mask = qdev_get_prop_mask64(props);
     if (val) {
         *p |= mask;
@@ -111,7 +111,7 @@ static void bit64_prop_set(Object *obj, Property *props, bool val)
 static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
                             Property *prop, Error **errp)
 {
-    uint64_t *p = object_field_prop_ptr(obj, prop);
+    uint64_t *p = FIELD_PTR(obj, prop, uint64_t);
     bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
 
     visit_type_bool(v, name, &value, errp);
@@ -141,7 +141,7 @@ const PropertyInfo prop_info_bit64 = {
 static void get_bool(Object *obj, Visitor *v, const char *name,
                      Property *prop, Error **errp)
 {
-    bool *ptr = object_field_prop_ptr(obj, prop);
+    bool *ptr = FIELD_PTR(obj, prop, bool);
 
     visit_type_bool(v, name, ptr, errp);
 }
@@ -149,7 +149,7 @@ static void get_bool(Object *obj, Visitor *v, const char *name,
 static void set_bool(Object *obj, Visitor *v, const char *name,
                      Property *prop, Error **errp)
 {
-    bool *ptr = object_field_prop_ptr(obj, prop);
+    bool *ptr = FIELD_PTR(obj, prop, bool);
 
     visit_type_bool(v, name, ptr, errp);
 }
@@ -166,7 +166,7 @@ const PropertyInfo prop_info_bool = {
 static void get_uint8(Object *obj, Visitor *v, const char *name,
                       Property *prop, Error **errp)
 {
-    uint8_t *ptr = object_field_prop_ptr(obj, prop);
+    uint8_t *ptr = FIELD_PTR(obj, prop, uint8_t);
 
     visit_type_uint8(v, name, ptr, errp);
 }
@@ -174,7 +174,7 @@ static void get_uint8(Object *obj, Visitor *v, const char *name,
 static void set_uint8(Object *obj, Visitor *v, const char *name,
                       Property *prop, Error **errp)
 {
-    uint8_t *ptr = object_field_prop_ptr(obj, prop);
+    uint8_t *ptr = FIELD_PTR(obj, prop, uint8_t);
 
     visit_type_uint8(v, name, ptr, errp);
 }
@@ -203,7 +203,7 @@ const PropertyInfo prop_info_uint8 = {
 static void get_uint16(Object *obj, Visitor *v, const char *name,
                         Property *prop, Error **errp)
 {
-    uint16_t *ptr = object_field_prop_ptr(obj, prop);
+    uint16_t *ptr = FIELD_PTR(obj, prop, uint16_t);
 
     visit_type_uint16(v, name, ptr, errp);
 }
@@ -211,7 +211,7 @@ static void get_uint16(Object *obj, Visitor *v, const char *name,
 static void set_uint16(Object *obj, Visitor *v, const char *name,
                         Property *prop, Error **errp)
 {
-    uint16_t *ptr = object_field_prop_ptr(obj, prop);
+    uint16_t *ptr = FIELD_PTR(obj, prop, uint16_t);
 
     visit_type_uint16(v, name, ptr, errp);
 }
@@ -228,7 +228,7 @@ const PropertyInfo prop_info_uint16 = {
 static void get_uint32(Object *obj, Visitor *v, const char *name,
                         Property *prop, Error **errp)
 {
-    uint32_t *ptr = object_field_prop_ptr(obj, prop);
+    uint32_t *ptr = FIELD_PTR(obj, prop, uint32_t);
 
     visit_type_uint32(v, name, ptr, errp);
 }
@@ -236,7 +236,7 @@ static void get_uint32(Object *obj, Visitor *v, const char *name,
 static void set_uint32(Object *obj, Visitor *v, const char *name,
                         Property *prop, Error **errp)
 {
-    uint32_t *ptr = object_field_prop_ptr(obj, prop);
+    uint32_t *ptr = FIELD_PTR(obj, prop, uint32_t);
 
     visit_type_uint32(v, name, ptr, errp);
 }
@@ -244,7 +244,7 @@ static void set_uint32(Object *obj, Visitor *v, const char *name,
 void field_prop_get_int32(Object *obj, Visitor *v, const char *name,
                            Property *prop, Error **errp)
 {
-    int32_t *ptr = object_field_prop_ptr(obj, prop);
+    int32_t *ptr = FIELD_PTR(obj, prop, int32_t);
 
     visit_type_int32(v, name, ptr, errp);
 }
@@ -252,7 +252,7 @@ void field_prop_get_int32(Object *obj, Visitor *v, const char *name,
 static void set_int32(Object *obj, Visitor *v, const char *name,
                       Property *prop, Error **errp)
 {
-    int32_t *ptr = object_field_prop_ptr(obj, prop);
+    int32_t *ptr = FIELD_PTR(obj, prop, int32_t);
 
     visit_type_int32(v, name, ptr, errp);
 }
@@ -276,7 +276,7 @@ const PropertyInfo prop_info_int32 = {
 static void get_uint64(Object *obj, Visitor *v, const char *name,
                         Property *prop, Error **errp)
 {
-    uint64_t *ptr = object_field_prop_ptr(obj, prop);
+    uint64_t *ptr = FIELD_PTR(obj, prop, uint64_t);
 
     visit_type_uint64(v, name, ptr, errp);
 }
@@ -284,7 +284,7 @@ static void get_uint64(Object *obj, Visitor *v, const char *name,
 static void set_uint64(Object *obj, Visitor *v, const char *name,
                         Property *prop, Error **errp)
 {
-    uint64_t *ptr = object_field_prop_ptr(obj, prop);
+    uint64_t *ptr = FIELD_PTR(obj, prop, uint64_t);
 
     visit_type_uint64(v, name, ptr, errp);
 }
@@ -292,7 +292,7 @@ static void set_uint64(Object *obj, Visitor *v, const char *name,
 static void get_int64(Object *obj, Visitor *v, const char *name,
                        Property *prop, Error **errp)
 {
-    int64_t *ptr = object_field_prop_ptr(obj, prop);
+    int64_t *ptr = FIELD_PTR(obj, prop, int64_t);
 
     visit_type_int64(v, name, ptr, errp);
 }
@@ -300,7 +300,7 @@ static void get_int64(Object *obj, Visitor *v, const char *name,
 static void set_int64(Object *obj, Visitor *v, const char *name,
                        Property *prop, Error **errp)
 {
-    int64_t *ptr = object_field_prop_ptr(obj, prop);
+    int64_t *ptr = FIELD_PTR(obj, prop, int64_t);
 
     visit_type_int64(v, name, ptr, errp);
 }
@@ -323,13 +323,14 @@ const PropertyInfo prop_info_int64 = {
 
 static void release_string(Object *obj, const char *name, Property *prop)
 {
-    g_free(*(char **)object_field_prop_ptr(obj, prop));
+    char **ptr = FIELD_PTR(obj, prop, char *);
+    g_free(*ptr);
 }
 
 static void get_string(Object *obj, Visitor *v, const char *name,
                         Property *prop, Error **errp)
 {
-    char **ptr = object_field_prop_ptr(obj, prop);
+    char **ptr = FIELD_PTR(obj, prop, char *);
 
     if (!*ptr) {
         char *str = (char *)"";
@@ -342,7 +343,7 @@ static void get_string(Object *obj, Visitor *v, const char *name,
 static void set_string(Object *obj, Visitor *v, const char *name,
                         Property *prop, Error **errp)
 {
-    char **ptr = object_field_prop_ptr(obj, prop);
+    char **ptr = FIELD_PTR(obj, prop, char *);
     char *str;
 
     if (!visit_type_str(v, name, &str, errp)) {
@@ -375,7 +376,7 @@ const PropertyInfo prop_info_on_off_auto = {
 void field_prop_get_size32(Object *obj, Visitor *v, const char *name,
                             Property *prop, Error **errp)
 {
-    uint32_t *ptr = object_field_prop_ptr(obj, prop);
+    uint32_t *ptr = FIELD_PTR(obj, prop, uint32_t);
     uint64_t value = *ptr;
 
     visit_type_size(v, name, &value, errp);
@@ -384,7 +385,7 @@ void field_prop_get_size32(Object *obj, Visitor *v, const char *name,
 static void set_size32(Object *obj, Visitor *v, const char *name,
                        Property *prop, Error **errp)
 {
-    uint32_t *ptr = object_field_prop_ptr(obj, prop);
+    uint32_t *ptr = FIELD_PTR(obj, prop, uint32_t);
     uint64_t value;
 
     if (!visit_type_size(v, name, &value, errp)) {
@@ -415,7 +416,7 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
                                Property *prop, Error **errp)
 {
     ObjectProperty *op = object_property_find_err(obj, name, &error_abort);
-    uint32_t *alenptr = object_field_prop_ptr(obj, prop);
+    uint32_t *alenptr = FIELD_PTR(obj, prop, uint32_t);
     void **arrayptr = (void *)obj + prop->arrayoffset;
     void *eltptr;
     const char *arrayname;
@@ -455,7 +456,8 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
          */
         arrayprop->offset = eltptr - (void *)obj;
         arrayprop->size = prop->arrayfieldsize;
-        assert(object_field_prop_ptr(obj, arrayprop) == eltptr);
+        assert(object_field_prop_ptr(obj, arrayprop,
+                                     prop->arrayfieldsize) == eltptr);
         object_property_add_field(obj, propname, arrayprop, op->allow_set);
     }
 }
@@ -472,7 +474,7 @@ const PropertyInfo prop_info_arraylen = {
 static void get_size(Object *obj, Visitor *v, const char *name,
                      Property *prop, Error **errp)
 {
-    uint64_t *ptr = object_field_prop_ptr(obj, prop);
+    uint64_t *ptr = FIELD_PTR(obj, prop, uint64_t);
 
     visit_type_size(v, name, ptr, errp);
 }
@@ -480,7 +482,7 @@ static void get_size(Object *obj, Visitor *v, const char *name,
 static void set_size(Object *obj, Visitor *v, const char *name,
                      Property *prop, Error **errp)
 {
-    uint64_t *ptr = object_field_prop_ptr(obj, prop);
+    uint64_t *ptr = FIELD_PTR(obj, prop, uint64_t);
 
     visit_type_size(v, name, ptr, errp);
 }
-- 
2.28.0



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

* [PATCH 7/7] sparc: Use FIELD_PTR at nwindows getter/setter
  2020-11-04 17:25 [PATCH 0/7] qom: Field properties type safety Eduardo Habkost
                   ` (5 preceding siblings ...)
  2020-11-04 17:25   ` Eduardo Habkost
@ 2020-11-04 17:25 ` Eduardo Habkost
  2020-11-10 13:04   ` Mark Cave-Ayland
  6 siblings, 1 reply; 16+ messages in thread
From: Eduardo Habkost @ 2020-11-04 17:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: Igor Mammedov, Mark Cave-Ayland, Daniel P. Berrange,
	Artyom Tarasenko, Paolo Bonzini

This makes the nwindows getter and setter more consistent with
the other field getters and setters (which work with any struct
field).

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 | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 3acc99c29c..8bf02a4fe0 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -789,8 +789,8 @@ static void sparc_cpu_initfn(Object *obj)
 static void sparc_get_nwindows(Object *obj, Visitor *v, const char *name,
                                Property *prop, Error **errp)
 {
-    SPARCCPU *cpu = SPARC_CPU(obj);
-    int64_t value = cpu->env.def.nwindows;
+    uint32_t *ptr = FIELD_PTR(obj, prop, uint32_t);
+    int64_t value = *ptr;
 
     visit_type_int(v, name, &value, errp);
 }
@@ -798,9 +798,9 @@ static void sparc_get_nwindows(Object *obj, Visitor *v, const char *name,
 static void sparc_set_nwindows(Object *obj, Visitor *v, const char *name,
                                Property *prop, Error **errp)
 {
+    uint32_t *ptr = FIELD_PTR(obj, prop, uint32_t);
     const int64_t min = MIN_NWINDOWS;
     const int64_t max = MAX_NWINDOWS;
-    SPARCCPU *cpu = SPARC_CPU(obj);
     int64_t value;
 
     if (!visit_type_int(v, name, &value, errp)) {
@@ -814,7 +814,7 @@ static void sparc_set_nwindows(Object *obj, Visitor *v, const char *name,
                    value, min, max);
         return;
     }
-    cpu->env.def.nwindows = value;
+    *ptr = value;
 }
 
 static PropertyInfo qdev_prop_nwindows = {
-- 
2.28.0



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

* Re: [PATCH 4/7] qom: Replace void* parameter with Property* on field getters/setters
  2020-11-04 17:25   ` Eduardo Habkost
@ 2020-11-09 10:44     ` Cornelia Huck
  -1 siblings, 0 replies; 16+ messages in thread
From: Cornelia Huck @ 2020-11-09 10:44 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: Matthew Rosato, Paul Durrant, Mark Cave-Ayland, qemu-devel,
	Stefano Stabellini, qemu-block, Stefan Berger, David Hildenbrand,
	Halil Pasic, Christian Borntraeger, Anthony Perard, xen-devel,
	Artyom Tarasenko, Thomas Huth, qemu-s390x, Igor Mammedov,
	Richard Henderson, Kevin Wolf, Daniel P. Berrange,
	Alex Williamson, Max Reitz, Paolo Bonzini

On Wed,  4 Nov 2020 12:25:09 -0500
Eduardo Habkost <ehabkost@redhat.com> wrote:

> All field property getters and setters must interpret the fourth
> argument as Property*.  Change the function signature of field
> property getters and setters to indicate that.
> 
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> ---
> 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: Richard Henderson <rth@twiddle.net>
> Cc: David Hildenbrand <david@redhat.com>
> Cc: Cornelia Huck <cohuck@redhat.com>
> Cc: Thomas Huth <thuth@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: 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
> ---
>  include/qom/field-property-internal.h |   8 +-
>  include/qom/field-property.h          |  26 ++++---
>  backends/tpm/tpm_util.c               |  11 ++-
>  hw/block/xen-block.c                  |   6 +-
>  hw/core/qdev-properties-system.c      |  86 +++++++++-------------
>  hw/s390x/css.c                        |   6 +-
>  hw/s390x/s390-pci-bus.c               |   6 +-
>  hw/vfio/pci-quirks.c                  |  10 +--
>  qom/property-types.c                  | 102 +++++++++-----------------
>  target/sparc/cpu.c                    |   4 +-
>  10 files changed, 105 insertions(+), 160 deletions(-)

Acked-by: Cornelia Huck <cohuck@redhat.com>



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

* Re: [PATCH 4/7] qom: Replace void* parameter with Property* on field getters/setters
@ 2020-11-09 10:44     ` Cornelia Huck
  0 siblings, 0 replies; 16+ messages in thread
From: Cornelia Huck @ 2020-11-09 10:44 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: qemu-devel, Igor Mammedov, Daniel P. Berrange, Paolo Bonzini,
	Stefan Berger, Stefano Stabellini, Anthony Perard, Paul Durrant,
	Kevin Wolf, Max Reitz, Richard Henderson, David Hildenbrand,
	Thomas Huth, Halil Pasic, Christian Borntraeger, Matthew Rosato,
	Alex Williamson, Mark Cave-Ayland, Artyom Tarasenko, xen-devel,
	qemu-block, qemu-s390x

On Wed,  4 Nov 2020 12:25:09 -0500
Eduardo Habkost <ehabkost@redhat.com> wrote:

> All field property getters and setters must interpret the fourth
> argument as Property*.  Change the function signature of field
> property getters and setters to indicate that.
> 
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> ---
> 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: Richard Henderson <rth@twiddle.net>
> Cc: David Hildenbrand <david@redhat.com>
> Cc: Cornelia Huck <cohuck@redhat.com>
> Cc: Thomas Huth <thuth@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: 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
> ---
>  include/qom/field-property-internal.h |   8 +-
>  include/qom/field-property.h          |  26 ++++---
>  backends/tpm/tpm_util.c               |  11 ++-
>  hw/block/xen-block.c                  |   6 +-
>  hw/core/qdev-properties-system.c      |  86 +++++++++-------------
>  hw/s390x/css.c                        |   6 +-
>  hw/s390x/s390-pci-bus.c               |   6 +-
>  hw/vfio/pci-quirks.c                  |  10 +--
>  qom/property-types.c                  | 102 +++++++++-----------------
>  target/sparc/cpu.c                    |   4 +-
>  10 files changed, 105 insertions(+), 160 deletions(-)

Acked-by: Cornelia Huck <cohuck@redhat.com>



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

* Re: [PATCH 6/7] qom: Add FIELD_PTR, a type-safe wrapper for object_field_prop_ptr()
  2020-11-04 17:25   ` Eduardo Habkost
@ 2020-11-09 10:47     ` Cornelia Huck
  -1 siblings, 0 replies; 16+ messages in thread
From: Cornelia Huck @ 2020-11-09 10:47 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: Kevin Wolf, Thomas Huth, Stefano Stabellini, Daniel P. Berrange,
	xen-devel, Matthew Rosato, Stefan Berger, qemu-s390x,
	Paul Durrant, David Hildenbrand, qemu-devel, Max Reitz,
	Halil Pasic, Christian Borntraeger, Alex Williamson,
	Paolo Bonzini, Anthony Perard, Igor Mammedov, qemu-block,
	Richard Henderson

On Wed,  4 Nov 2020 12:25:11 -0500
Eduardo Habkost <ehabkost@redhat.com> wrote:

> Introduce a FIELD_PTR macro that will ensure the size of the area
> we are accessing has the correct size, and will return a pointer
> of the correct type.
> 
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> ---
> 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: 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: 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/qom/field-property.h     | 21 ++++++++++-
>  backends/tpm/tpm_util.c          |  6 ++--
>  hw/block/xen-block.c             |  4 +--
>  hw/core/qdev-properties-system.c | 50 +++++++++++++-------------
>  hw/s390x/css.c                   |  4 +--
>  hw/s390x/s390-pci-bus.c          |  4 +--
>  hw/vfio/pci-quirks.c             |  4 +--
>  qom/field-property.c             |  3 +-
>  qom/property-types.c             | 60 +++++++++++++++++---------------
>  9 files changed, 89 insertions(+), 67 deletions(-)

Acked-by: Cornelia Huck <cohuck@redhat.com>



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

* Re: [PATCH 6/7] qom: Add FIELD_PTR, a type-safe wrapper for object_field_prop_ptr()
@ 2020-11-09 10:47     ` Cornelia Huck
  0 siblings, 0 replies; 16+ messages in thread
From: Cornelia Huck @ 2020-11-09 10:47 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: qemu-devel, Igor Mammedov, Daniel P. Berrange, Paolo Bonzini,
	Stefan Berger, Stefano Stabellini, Anthony Perard, Paul Durrant,
	Kevin Wolf, Max Reitz, Thomas Huth, Halil Pasic,
	Christian Borntraeger, Richard Henderson, David Hildenbrand,
	Matthew Rosato, Alex Williamson, xen-devel, qemu-block,
	qemu-s390x

On Wed,  4 Nov 2020 12:25:11 -0500
Eduardo Habkost <ehabkost@redhat.com> wrote:

> Introduce a FIELD_PTR macro that will ensure the size of the area
> we are accessing has the correct size, and will return a pointer
> of the correct type.
> 
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> ---
> 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: 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: 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/qom/field-property.h     | 21 ++++++++++-
>  backends/tpm/tpm_util.c          |  6 ++--
>  hw/block/xen-block.c             |  4 +--
>  hw/core/qdev-properties-system.c | 50 +++++++++++++-------------
>  hw/s390x/css.c                   |  4 +--
>  hw/s390x/s390-pci-bus.c          |  4 +--
>  hw/vfio/pci-quirks.c             |  4 +--
>  qom/field-property.c             |  3 +-
>  qom/property-types.c             | 60 +++++++++++++++++---------------
>  9 files changed, 89 insertions(+), 67 deletions(-)

Acked-by: Cornelia Huck <cohuck@redhat.com>



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

* Re: [PATCH 1/7] sparc: Fix property/field size mismatch for iu-version
  2020-11-04 17:25 ` [PATCH 1/7] sparc: Fix property/field size mismatch for iu-version Eduardo Habkost
@ 2020-11-10 13:00   ` Mark Cave-Ayland
  0 siblings, 0 replies; 16+ messages in thread
From: Mark Cave-Ayland @ 2020-11-10 13:00 UTC (permalink / raw)
  To: Eduardo Habkost, qemu-devel
  Cc: Igor Mammedov, Daniel P. Berrange, Artyom Tarasenko, Paolo Bonzini

On 04/11/2020 17:25, Eduardo Habkost wrote:

> The "iu-version" property is declared as uint64_t but points to a
> target_ulong struct field.  On the sparc 32-bit target, This
> makes every write of iu-version corrupt the 4 bytes after
> sparc_def_t.iu_version (where the fpu_version field is located).
> 
> Change the type of the iu_version struct field to uint64_t,
> and just use DEFINE_PROP_UINT64.
> 
> The only place where env.def.iu_version field is read is the
>      env->version = env->def.iu_version;
> assignment at sparc_cpu_realizefn().  This means behavior will be
> kept exactly the same (except for the memory corruption bug fix).
> 
> It would be nice to explicitly validate iu_version against
> target_ulong limits, but that would be a new feature (since the
> first version of this code, iu-version was parsed as 64-bit value
> value).  It can be done later, once we have an appropriate API to
> define limits for integer properties.
> 
> Fixes: de05005bf785 ("sparc: convert cpu features to qdev properties")
> 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.h | 2 +-
>   target/sparc/cpu.c | 5 ++---
>   2 files changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
> index b9369398f2..8ed0f4fef3 100644
> --- a/target/sparc/cpu.h
> +++ b/target/sparc/cpu.h
> @@ -252,7 +252,7 @@ typedef struct trap_state {
>   
>   struct sparc_def_t {
>       const char *name;
> -    target_ulong iu_version;
> +    uint64_t iu_version;
>       uint32_t fpu_version;
>       uint32_t mmu_version;
>       uint32_t mmu_bm;
> diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
> index ec59a13eb8..5a9397f19a 100644
> --- a/target/sparc/cpu.c
> +++ b/target/sparc/cpu.c
> @@ -576,7 +576,7 @@ void sparc_cpu_list(void)
>       unsigned int i;
>   
>       for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
> -        qemu_printf("Sparc %16s IU " TARGET_FMT_lx
> +        qemu_printf("Sparc %16s IU %" PRIx64
>                       " FPU %08x MMU %08x NWINS %d ",
>                       sparc_defs[i].name,
>                       sparc_defs[i].iu_version,
> @@ -838,8 +838,7 @@ static Property sparc_cpu_properties[] = {
>       DEFINE_PROP_BIT("hypv",     SPARCCPU, env.def.features, 11, false),
>       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,
> -                         prop_info_uint64, target_ulong),
> +    DEFINE_PROP_UINT64("iu-version", SPARCCPU, env.def.iu_version, 0),
>       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,

Acked-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>


ATB,

Mark.


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

* Re: [PATCH 7/7] sparc: Use FIELD_PTR at nwindows getter/setter
  2020-11-04 17:25 ` [PATCH 7/7] sparc: Use FIELD_PTR at nwindows getter/setter Eduardo Habkost
@ 2020-11-10 13:04   ` Mark Cave-Ayland
  0 siblings, 0 replies; 16+ messages in thread
From: Mark Cave-Ayland @ 2020-11-10 13:04 UTC (permalink / raw)
  To: Eduardo Habkost, qemu-devel
  Cc: Igor Mammedov, Daniel P. Berrange, Artyom Tarasenko, Paolo Bonzini

On 04/11/2020 17:25, Eduardo Habkost wrote:

> This makes the nwindows getter and setter more consistent with
> the other field getters and setters (which work with any struct
> field).
> 
> 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 | 8 ++++----
>   1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
> index 3acc99c29c..8bf02a4fe0 100644
> --- a/target/sparc/cpu.c
> +++ b/target/sparc/cpu.c
> @@ -789,8 +789,8 @@ static void sparc_cpu_initfn(Object *obj)
>   static void sparc_get_nwindows(Object *obj, Visitor *v, const char *name,
>                                  Property *prop, Error **errp)
>   {
> -    SPARCCPU *cpu = SPARC_CPU(obj);
> -    int64_t value = cpu->env.def.nwindows;
> +    uint32_t *ptr = FIELD_PTR(obj, prop, uint32_t);
> +    int64_t value = *ptr;
>   
>       visit_type_int(v, name, &value, errp);
>   }
> @@ -798,9 +798,9 @@ static void sparc_get_nwindows(Object *obj, Visitor *v, const char *name,
>   static void sparc_set_nwindows(Object *obj, Visitor *v, const char *name,
>                                  Property *prop, Error **errp)
>   {
> +    uint32_t *ptr = FIELD_PTR(obj, prop, uint32_t);
>       const int64_t min = MIN_NWINDOWS;
>       const int64_t max = MAX_NWINDOWS;
> -    SPARCCPU *cpu = SPARC_CPU(obj);
>       int64_t value;
>   
>       if (!visit_type_int(v, name, &value, errp)) {
> @@ -814,7 +814,7 @@ static void sparc_set_nwindows(Object *obj, Visitor *v, const char *name,
>                      value, min, max);
>           return;
>       }
> -    cpu->env.def.nwindows = value;
> +    *ptr = value;
>   }
>   
>   static PropertyInfo qdev_prop_nwindows = {

This looks correct to me:

Acked-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>


ATB,

Mark.


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

end of thread, other threads:[~2020-11-10 13:06 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-04 17:25 [PATCH 0/7] qom: Field properties type safety Eduardo Habkost
2020-11-04 17:25 ` [PATCH 1/7] sparc: Fix property/field size mismatch for iu-version Eduardo Habkost
2020-11-10 13:00   ` Mark Cave-Ayland
2020-11-04 17:25 ` [PATCH 2/7] qom: Save size of struct field in Property struct Eduardo Habkost
2020-11-04 17:25 ` [PATCH 3/7] qdev: Don't register unreadable legacy properties Eduardo Habkost
2020-11-04 17:25 ` [PATCH 4/7] qom: Replace void* parameter with Property* on field getters/setters Eduardo Habkost
2020-11-04 17:25   ` Eduardo Habkost
2020-11-09 10:44   ` Cornelia Huck
2020-11-09 10:44     ` Cornelia Huck
2020-11-04 17:25 ` [PATCH 5/7] qom: Replace void* parameter with Property* on PropertyInfo.release Eduardo Habkost
2020-11-04 17:25 ` [PATCH 6/7] qom: Add FIELD_PTR, a type-safe wrapper for object_field_prop_ptr() Eduardo Habkost
2020-11-04 17:25   ` Eduardo Habkost
2020-11-09 10:47   ` Cornelia Huck
2020-11-09 10:47     ` Cornelia Huck
2020-11-04 17:25 ` [PATCH 7/7] sparc: Use FIELD_PTR at nwindows getter/setter Eduardo Habkost
2020-11-10 13:04   ` Mark Cave-Ayland

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.