All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/54] qom/qdev: associate properties with QAPI schema types
@ 2026-05-10 13:42 Marc-André Lureau
  2026-05-10 13:42 ` [PATCH 01/54] qapi: add QAPITypeInfo struct definition Marc-André Lureau
                   ` (54 more replies)
  0 siblings, 55 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:42 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Hi,

This series connects QOM and qdev properties to the QAPI type system, so
that management tools can discover the QAPI schema type of each object
property.

Today, QOM properties carry a free-form "type" string ("bool", "uint32",
"OnOffAuto", ..) that has no formal link to the QAPI schema exposed by
query-qmp-schema. Management tools must maintain ad-hoc mappings or rely
on naming conventions to figure out how to interpret property values.

This series adds:
  - A new QAPITypeInfo struct that pairs a property with its QAPI schema
    type name, enum lookup table, and list-element type.

  - A QAPI code generator (qapi-type-infos) that emits a QAPITypeInfo
    instance for every schema-defined type, including the mapping
    between internal C names and the schema name visible to clients.

  - A "qapi-type" field in the ObjectPropertyInfo and
    ObjectPropertyValue QMP structs, populated from the QAPITypeInfo
    when present giving clients a cross-reference into query-qmp-schema
    output.

  - Conversion of all PropertyInfo definitions from the old
    .type/.enum_table strings to the new .qapi_type pointer.

  - Replacement of the generic qdev_prop_array with typed per-element
    array PropertyInfos, removing the arrayinfo/arrayfieldsize
    indirection from struct Property.

  - Removal of the deprecated PropertyInfo.type and .enum_table fields,
    and of the old object_property_add_enum/add_tm APIs.

Along the way, a few pre-existing type mismatches in property
definitions are fixed, the "struct tm" RTC property is replaced with a
proper QAPI StructTm type etc. Introducing more specific types or a
"typedef" to QAPI could help provide better associated type informations
than plain "str" in many cases, for example.

Comments welcome!

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
Marc-André Lureau (54):
      qapi: add QAPITypeInfo struct definition
      qapi/introspect: expose the type name map
      qapi: add type-infos generator
      qapi/backend: wire up type-infos generation
      qapi/gen: fix _module_basename for multi-dash 'what' parameters
      meson: add qapi-type-infos-*.c/h to build
      qom: add qapi_type field to ObjectProperty
      qapi/qom: add qapi-type field to ObjectPropertyInfo
      qom/qmp: populate qapi-type in QMP handlers
      qom: add QAPI-aware property registration
      tests: update check-qom-proplist for QAPI-aware property registration
      qom: convert enum properties to QAPI-aware registration
      qom: remove old enum property registration API
      qom: convert struct properties to QAPI-aware registration
      qom: convert struct properties to QAPI-aware registration
      x86: convert OnOffAuto properties to QAPI-aware registration
      microvm: convert OnOffAuto properties to QAPI-aware registration
      pc: convert OnOffAuto vmport property to QAPI-aware registration
      arm/virt: convert OnOffAuto acpi property to QAPI-aware registration
      riscv/virt: convert OnOffAuto properties to QAPI-aware registration
      loongarch/virt: convert OnOffAuto properties to QAPI-aware registration
      hostmem-file: convert OnOffAuto rom property to QAPI-aware registration
      sev: convert OnOffAuto legacy-vm-type property to QAPI-aware registration
      whpx: convert OnOffAuto hyperv property to QAPI-aware registration
      whpx: convert OnOffAuto arch properties to QAPI-aware registration
      accel/kvm: convert OnOffSplit property to QAPI-aware registration
      whpx: convert OnOffSplit property to QAPI-aware registration
      ppc/spapr-caps: convert to QAPI-aware property registration
      system/memory: fix "priority" property typename
      hw/mem/nvdimm: fix "size" property typename
      qom: convert scalar properties to QAPI-aware registration
      i386/cpu: convert strList property to QAPI-aware registration
      accel/hvf: convert OnOffSplit property to QAPI-aware registration
      i386/x86: convert SgxEPCList property to QAPI-aware registration
      virtio-balloon: convert guest-stats property to QAPI type
      qom: replace object_property_add_tm with StructTm QAPI type
      hw/nvdimm: convert UUID property to QAPI-aware registration
      hw/s390-virtio-ccw: convert loadparm property to QAPI-aware registration
      hw/ppc/spapr_drc: convert fdt property to QAPI-aware registration
      spdm-socket: convert SpdmTransportType to QAPI enum
      hw/pci: change the busnr type to uint8
      qdev: add qapi_type field to PropertyInfo with fallback registration
      qdev: convert core PropertyInfo definitions to use qapi_type
      qdev: convert system PropertyInfo definitions to use qapi_type
      hw: convert device-local PropertyInfo definitions to use qapi_type
      target/riscv: fix incorrect QAPI types and u8 casting
      target/riscv: convert PropertyInfo definitions to use qapi_type
      qdev: convert PropertyInfo definitions to use qapi_type
      qdev: introduce typed array PropertyInfos
      qdev: simplify DEFINE_PROP_ARRAY and remove generic array PropertyInfo
      qdev: remove deprecated PropertyInfo.type and .enum_table fields
      memory: use object_property_add_link for container property
      qom: drop free-form property typename registration
      qom: use QAPITypeInfo in object_property_get_enum

 docs/devel/qapi-code-gen.rst             |  90 ++++++++++++
 docs/interop/virtio-balloon-stats.rst    |  22 +--
 meson.build                              |   1 +
 qapi/common.json                         |  28 ++++
 qapi/machine.json                        |  92 ++++++++++++
 qapi/pragma.json                         |   1 +
 qapi/qom.json                            |  12 ++
 qapi/sockets.json                        |  20 +++
 hw/core/qdev-prop-internal.h             |  20 +++
 hw/display/apple-gfx.h                   |   1 +
 include/hw/block/block.h                 |   2 +-
 include/hw/core/qdev-properties-system.h |   2 +
 include/hw/core/qdev-properties.h        |  29 ++--
 include/qapi/qapi-type-info.h            |  19 +++
 include/qemu/uuid.h                      |   4 +
 include/qom/object.h                     | 162 ++++++++++++---------
 include/system/spdm-socket.h             |  28 ++--
 accel/hvf/hvf-all.c                      |  29 ++--
 accel/kvm/kvm-all.c                      |  31 ++--
 accel/nitro/nitro-accel.c                |   3 +-
 accel/tcg/tcg-all.c                      |   3 +-
 accel/whpx/whpx-common.c                 |  58 +++-----
 authz/list.c                             |  14 +-
 backends/cryptodev.c                     |   7 +-
 backends/hostmem-file.c                  |  33 ++---
 backends/hostmem-memfd.c                 |   3 +-
 backends/hostmem.c                       |  20 +--
 backends/spdm-socket.c                   |  25 ++--
 backends/tpm/tpm_util.c                  |   3 +-
 block/throttle-groups.c                  |  10 +-
 chardev/char-socket.c                    |   3 +-
 crypto/secret_common.c                   |  12 +-
 crypto/secret_keyring.c                  |   9 +-
 crypto/tlscreds.c                        |  12 +-
 event-loop-base.c                        |   7 +-
 hw/acpi/ich9.c                           |   3 +-
 hw/acpi/pci.c                            |   5 +-
 hw/arm/virt.c                            |  31 ++--
 hw/block/xen-block.c                     |   3 +-
 hw/core/clock.c                          |   3 +-
 hw/core/machine-qmp-cmds.c               |   3 +-
 hw/core/machine.c                        |  13 +-
 hw/core/qdev-properties-system.c         |  97 ++++++-------
 hw/core/qdev-properties.c                | 168 ++++++++++++++--------
 hw/cpu/core.c                            |  10 +-
 hw/cxl/cxl-host.c                        |   6 +-
 hw/gpio/aspeed_gpio.c                    |   5 +-
 hw/gpio/aspeed_sgpio.c                   |   3 +-
 hw/gpio/pca9552.c                        |   6 +-
 hw/gpio/pca9554.c                        |   6 +-
 hw/gpio/stm32l4x5_gpio.c                 |   5 +-
 hw/i386/microvm.c                        |  84 +++++------
 hw/i386/pc.c                             |  32 ++---
 hw/i386/pc_piix.c                        |  19 ++-
 hw/i386/sgx-epc.c                        |   3 +-
 hw/i386/x86.c                            | 119 +++++++---------
 hw/ide/ide-dev.c                         |   3 +-
 hw/input/stellaris_gamepad.c             |   2 +-
 hw/intc/apic_common.c                    |   3 +-
 hw/intc/arm_gicv3_common.c               |   2 +-
 hw/intc/rx_icu.c                         |   4 +-
 hw/loongarch/virt.c                      |  87 ++++++------
 hw/mem/nvdimm.c                          |  11 +-
 hw/mem/pc-dimm.c                         |   3 +-
 hw/microblaze/petalogix_s3adsp1800_mmu.c |  19 +--
 hw/misc/arm_sysctl.c                     |   4 +-
 hw/misc/aspeed_lpc.c                     |  73 ++++++----
 hw/misc/aspeed_sdmc.c                    |   3 +-
 hw/misc/mps2-scc.c                       |   2 +-
 hw/misc/npcm7xx_mft.c                    |   3 +-
 hw/misc/xlnx-versal-trng.c               |   3 +-
 hw/net/ne2000-isa.c                      |   3 +-
 hw/net/rocker/rocker.c                   |   2 +-
 hw/net/virtio-net.c                      |   2 +-
 hw/nvme/ctrl.c                           |  29 ++--
 hw/nvme/nguid.c                          |   3 +-
 hw/nvram/xlnx-bbram.c                    |   3 +-
 hw/nvram/xlnx-efuse.c                    |   5 +-
 hw/nvram/xlnx-versal-efuse-ctrl.c        |   2 +-
 hw/pci-bridge/pci_expander_bridge.c      |   3 +-
 hw/pci-host/i440fx.c                     |  35 +++--
 hw/pci-host/pnv_phb3.c                   |   5 +-
 hw/pci-host/pnv_phb4.c                   |   5 +-
 hw/pci-host/q35.c                        |   9 +-
 hw/pci/pci.c                             |   3 +-
 hw/ppc/spapr_caps.c                      |  39 ++---
 hw/ppc/spapr_drc.c                       |   5 +-
 hw/ppc/spapr_rtc.c                       |  18 ++-
 hw/remote/vfio-user-obj.c                |   5 +-
 hw/riscv/microchip_pfsoc.c               |   3 +-
 hw/riscv/riscv_hart.c                    |   6 +-
 hw/riscv/virt.c                          |  54 ++++---
 hw/rtc/mc146818rtc.c                     |  16 ++-
 hw/s390x/ccw-device.c                    |   3 +-
 hw/s390x/css.c                           |   5 +-
 hw/s390x/s390-pci-bus.c                  |   3 +-
 hw/s390x/s390-virtio-ccw.c               |   4 +-
 hw/s390x/sclpcpi.c                       |   8 +-
 hw/s390x/virtio-ccw-mem.c                |   3 +-
 hw/sensor/adm1266.c                      |   3 +-
 hw/sensor/adm1272.c                      |   9 +-
 hw/sensor/emc141x.c                      |   9 +-
 hw/sensor/isl_pmbus_vr.c                 |  19 +--
 hw/sensor/lsm303dlhc_mag.c               |   9 +-
 hw/sensor/max34451.c                     |   5 +-
 hw/sensor/tmp105.c                       |   3 +-
 hw/sensor/tmp421.c                       |   9 +-
 hw/usb/dev-storage-classic.c             |   3 +-
 hw/vfio-user/pci.c                       |   5 +-
 hw/vfio/pci-quirks.c                     |   3 +-
 hw/virtio/virtio-balloon.c               |  89 +++++-------
 hw/virtio/virtio-iommu-pci.c             |   2 +-
 hw/virtio/virtio-mem-pci.c               |   3 +-
 hw/virtio/virtio-mem.c                   |  18 +--
 hw/xen/xen-pvh-common.c                  |   9 +-
 iothread.c                               |   9 +-
 migration/options.c                      |   4 +-
 net/colo-compare.c                       |   7 +-
 net/dump.c                               |   6 +-
 net/filter-buffer.c                      |   3 +-
 net/filter.c                             |  10 +-
 qom/object.c                             | 237 ++++++++++++++-----------------
 qom/qom-qmp-cmds.c                       |  32 +++--
 system/bootdevice.c                      |   3 +-
 system/memory.c                          |  40 ++----
 target/arm/cpu64.c                       |  11 +-
 target/arm/kvm.c                         |   3 +-
 target/arm/tcg/cpu64.c                   |   5 +-
 target/i386/cpu.c                        |  26 ++--
 target/i386/kvm/kvm.c                    |  38 ++---
 target/i386/kvm/tdx.c                    |   4 +-
 target/i386/sev.c                        |  31 ++--
 target/i386/whpx/whpx-all.c              | 102 +++++--------
 target/ppc/compat.c                      |   3 +-
 target/riscv/cpu.c                       |  46 +++---
 target/riscv/kvm/kvm-cpu.c               |   7 +-
 target/riscv/tcg/tcg-cpu.c               |   7 +-
 target/s390x/cpu-system.c                |   4 +-
 target/s390x/cpu_models.c                |   5 +-
 target/sparc/cpu.c                       |   3 +-
 tests/unit/check-qom-proplist.c          | 100 ++++++++++---
 tests/unit/test-qdev-global-props.c      |  11 +-
 tests/unit/test-qdev.c                   |   2 +-
 ui/console.c                             |   3 +-
 ui/dbus.c                                |  10 +-
 ui/input-linux.c                         |  11 +-
 util/thread-context.c                    |   7 +-
 util/uuid.c                              |   4 +
 hw/display/apple-gfx-mmio.m              |   2 +-
 hw/display/apple-gfx-pci.m               |   2 +-
 hw/display/apple-gfx.m                   |   7 +-
 qapi/meson.build                         |   4 +
 scripts/qapi/backend.py                  |   4 +-
 scripts/qapi/gen.py                      |   2 +-
 scripts/qapi/introspect.py               |  13 +-
 scripts/qapi/type_infos.py               | 182 ++++++++++++++++++++++++
 tests/include/meson.build                |   2 +
 tests/meson.build                        |   6 +
 tests/qapi-schema/meson.build            |   1 +
 159 files changed, 1887 insertions(+), 1272 deletions(-)
---
base-commit: ee7eb612be8f8886d48c1d0c1f1c65e495138f83
change-id: 20260510-qom-qapi-fbe0f5060c3f

Best regards,
--  
Marc-André Lureau <marcandre.lureau@redhat.com>



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

* [PATCH 01/54] qapi: add QAPITypeInfo struct definition
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
@ 2026-05-10 13:42 ` Marc-André Lureau
  2026-05-10 13:42 ` [PATCH 02/54] qapi/introspect: expose the type name map Marc-André Lureau
                   ` (53 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:42 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Introduce a minimal struct that pairs a QAPI type's internal name with
its "masked" introspection name. Generated constants of this type will
let QOM property registration carry a reliable reference to the QAPI
schema and possibly other associated data.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/qapi/qapi-type-info.h | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/include/qapi/qapi-type-info.h b/include/qapi/qapi-type-info.h
new file mode 100644
index 00000000000..53b4732297d
--- /dev/null
+++ b/include/qapi/qapi-type-info.h
@@ -0,0 +1,19 @@
+/*
+ * QAPITypeInfo — associates a QOM property with its QAPI schema type.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef QAPI_TYPE_INFO_H
+#define QAPI_TYPE_INFO_H
+
+#include "qapi/util.h"
+
+typedef struct QAPITypeInfo {
+    const char *name;
+    const char *schema_name;
+    const QEnumLookup *lookup;
+    const struct QAPITypeInfo *list;
+} QAPITypeInfo;
+
+#endif /* QAPI_TYPE_INFO_H */

-- 
2.54.0



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

* [PATCH 02/54] qapi/introspect: expose the type name map
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
  2026-05-10 13:42 ` [PATCH 01/54] qapi: add QAPITypeInfo struct definition Marc-André Lureau
@ 2026-05-10 13:42 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 03/54] qapi: add type-infos generator Marc-André Lureau
                   ` (52 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:42 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Preserve the internal-to-masked name map computed during introspection
visitation and return it from gen_introspect(). The type-infos generator
will consume this map to produce per-type QAPITypeInfo constants with
correct masked names.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 scripts/qapi/introspect.py | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index 7e28de2279a..d3d3de481f4 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -178,6 +178,7 @@ def __init__(self, prefix: str, unmask: bool):
         self._trees: List[Annotated[SchemaInfo]] = []
         self._used_types: List[QAPISchemaType] = []
         self._name_map: Dict[str, str] = {}
+        self._final_name_map: Dict[str, str] = {}
         self._genc.add(mcgen('''
 #include "qemu/osdep.h"
 #include "%(prefix)sqapi-introspect.h"
@@ -208,8 +209,17 @@ def visit_end(self) -> None:
         self._schema = None
         self._trees = []
         self._used_types = []
+        self._final_name_map = dict(self._name_map)
         self._name_map = {}
 
+    def name_map(self) -> Dict[str, str]:
+        """Return the QAPI-name-to-schema-name map.
+
+        Must be called after visit() has completed; the map is
+        populated during visit_end().
+        """
+        return self._final_name_map
+
     def visit_needed(self, entity: QAPISchemaEntity) -> bool:
         # Ignore types on first pass; visit_end() will pick up used types
         return not isinstance(entity, QAPISchemaType)
@@ -387,7 +397,8 @@ def visit_event(self, name: str, info: Optional[QAPISourceInfo],
 
 
 def gen_introspect(schema: QAPISchema, output_dir: str, prefix: str,
-                   opt_unmask: bool) -> None:
+                   opt_unmask: bool) -> Dict[str, str]:
     vis = QAPISchemaGenIntrospectVisitor(prefix, opt_unmask)
     schema.visit(vis)
     vis.write(output_dir)
+    return vis.name_map()

-- 
2.54.0



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

* [PATCH 03/54] qapi: add type-infos generator
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
  2026-05-10 13:42 ` [PATCH 01/54] qapi: add QAPITypeInfo struct definition Marc-André Lureau
  2026-05-10 13:42 ` [PATCH 02/54] qapi/introspect: expose the type name map Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 04/54] qapi/backend: wire up type-infos generation Marc-André Lureau
                   ` (51 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

New QAPISchemaGenTypeInfoVisitor produces per-module
qapi-type-infos-*.h/c files. Each file declares QAPITypeInfo constants
pairing the QAPI type name with its masked introspection name.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 docs/devel/qapi-code-gen.rst |  90 +++++++++++++++++++++
 meson.build                  |   1 +
 scripts/qapi/type_infos.py   | 182 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 273 insertions(+)

diff --git a/docs/devel/qapi-code-gen.rst b/docs/devel/qapi-code-gen.rst
index 3a632b4a648..bb2e8d9c675 100644
--- a/docs/devel/qapi-code-gen.rst
+++ b/docs/devel/qapi-code-gen.rst
@@ -2103,3 +2103,93 @@ Example::
     }));
 
     [Uninteresting stuff omitted...]
+
+
+Code generated for type information
+-----------------------------------
+
+The following files are created:
+
+ ``$(prefix)qapi-type-infos.c``
+     A ``QAPITypeInfo`` instance for each schema-defined type, providing
+     a mapping between the C type name and the schema name used by
+     introspection, along with optional enum lookup table and list-element
+     pointers.
+
+ ``$(prefix)qapi-type-infos.h``
+     Declarations for the above type info instances
+
+Each ``QAPITypeInfo`` struct has the following fields:
+
+``name``
+    The C identifier of the type (e.g. ``"UserDefOne"``).
+
+``schema_name``
+    The masked name used in ``query-qmp-schema`` output, or ``NULL``
+    for built-in types whose schema name equals their C name.  This
+    allows management tools to cross-reference a QOM property's
+    ``qapi-type`` against the introspection schema.
+
+``lookup``
+    For enum types, a pointer to the corresponding ``QEnumLookup``
+    table.  ``NULL`` for non-enum types.
+
+``list``
+    For types that have an array variant, a pointer to the list type's
+    ``QAPITypeInfo``.  ``NULL`` when no list type exists.
+
+These type info instances are used by QOM property registration
+functions (``object_property_add_qapi()``,
+``object_class_property_add_qapi_enum()``, etc.) to associate each
+property with its QAPI schema type.  The ``qom-list`` and
+``device-list-properties`` QMP commands then expose the ``qapi-type``
+field, giving management tools a formal type reference into the
+introspection schema.
+
+Implicit types (names starting with ``q_``) are skipped.
+
+Example::
+
+    $ cat qapi-generated/example-qapi-type-infos.h
+    [Uninteresting stuff omitted...]
+
+    #ifndef EXAMPLE_QAPI_TYPE_INFOS_H
+    #define EXAMPLE_QAPI_TYPE_INFOS_H
+
+    #include "qapi/qapi-builtin-type-infos.h"
+
+    extern const QAPITypeInfo UserDefOne_type_info;
+
+    extern const QAPITypeInfo UserDefOneList_type_info;
+
+    #endif /* EXAMPLE_QAPI_TYPE_INFOS_H */
+    $ cat qapi-generated/example-qapi-type-infos.c
+    [Uninteresting stuff omitted...]
+
+    const QAPITypeInfo UserDefOne_type_info = {
+        .name = "UserDefOne",
+        .schema_name = "1",
+        .list = &UserDefOneList_type_info,
+    };
+
+    const QAPITypeInfo UserDefOneList_type_info = {
+        .name = "UserDefOneList",
+        .schema_name = "[1]",
+    };
+
+    [Uninteresting stuff omitted...]
+
+For a modular QAPI schema (see section `Include directives`_), code for
+each sub-module SUBDIR/SUBMODULE.json is actually generated into ::
+
+ SUBDIR/$(prefix)qapi-type-infos-SUBMODULE.h
+ SUBDIR/$(prefix)qapi-type-infos-SUBMODULE.c
+
+If qapi-gen.py is run with option --builtins, additional files are
+created:
+
+ ``qapi-builtin-type-infos.h``
+     Type info instances for built-in types
+
+ ``qapi-builtin-type-infos.c``
+     Definitions for the above type info instances
diff --git a/meson.build b/meson.build
index 5fbdc75a0fc..f239ed24fae 100644
--- a/meson.build
+++ b/meson.build
@@ -3518,6 +3518,7 @@ qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
                      meson.current_source_dir() / 'scripts/qapi/parser.py',
                      meson.current_source_dir() / 'scripts/qapi/schema.py',
                      meson.current_source_dir() / 'scripts/qapi/source.py',
+                     meson.current_source_dir() / 'scripts/qapi/type_infos.py',
                      meson.current_source_dir() / 'scripts/qapi/types.py',
                      meson.current_source_dir() / 'scripts/qapi/visit.py',
                      meson.current_source_dir() / 'scripts/qapi-gen.py'
diff --git a/scripts/qapi/type_infos.py b/scripts/qapi/type_infos.py
new file mode 100644
index 00000000000..dc7e2bace9e
--- /dev/null
+++ b/scripts/qapi/type_infos.py
@@ -0,0 +1,182 @@
+"""
+QAPI type info generator
+
+SPDX-License-Identifier: GPL-2.0-or-later
+"""
+
+from typing import (
+    Dict,
+    List,
+    Optional,
+    Set,
+)
+
+from .common import c_name, mcgen
+from .gen import QAPISchemaModularCVisitor, ifcontext
+from .schema import (
+    QAPISchema,
+    QAPISchemaAlternatives,
+    QAPISchemaBranches,
+    QAPISchemaEnumMember,
+    QAPISchemaFeature,
+    QAPISchemaIfCond,
+    QAPISchemaObjectType,
+    QAPISchemaObjectTypeMember,
+    QAPISchemaType,
+    QAPISchemaVisitor,
+)
+from .source import QAPISourceInfo
+
+
+class _ArrayTypeCollector(QAPISchemaVisitor):
+    def __init__(self) -> None:
+        self.list_types: Set[str] = set()
+
+    def visit_array_type(self,
+                         name: str,
+                         info: Optional[QAPISourceInfo],
+                         ifcond: QAPISchemaIfCond,
+                         element_type: QAPISchemaType) -> None:
+        self.list_types.add(name)
+
+
+class QAPISchemaGenTypeInfoVisitor(QAPISchemaModularCVisitor):
+
+    def __init__(self, prefix: str, name_map: Dict[str, str],
+                 list_types: Set[str]):
+        super().__init__(
+            prefix, 'qapi-type-infos',
+            ' * Schema-defined QAPI type info',
+            ' * Built-in QAPI type info', __doc__)
+        self._name_map = name_map
+        self._list_types = list_types
+
+    def _begin_builtin_module(self) -> None:
+        self._genc.preamble_add(mcgen('''
+#include "qemu/osdep.h"
+#include "qapi/qapi-builtin-types.h"
+#include "qapi/qapi-builtin-type-infos.h"
+'''))
+        self._genh.preamble_add(mcgen('''
+#include "qapi/qapi-type-info.h"
+'''))
+
+    def _begin_user_module(self, name: str) -> None:
+        type_infos = self._module_basename('qapi-type-infos', name)
+        types = self._module_basename('qapi-types', name)
+        self._genc.preamble_add(mcgen('''
+#include "qemu/osdep.h"
+#include "%(types)s.h"
+#include "%(type_infos)s.h"
+''',
+                                      types=types,
+                                      type_infos=type_infos))
+        self._genh.preamble_add(mcgen('''
+#include "qapi/qapi-builtin-type-infos.h"
+'''))
+
+    def _gen_type_info(self, name: str,
+                       ifcond: Optional[QAPISchemaIfCond] = None,
+                       with_lookup: bool = False,
+                       with_list: bool = False,
+                       schema_name: Optional[str] = None) -> None:
+        c_id = c_name(name + '_type_info')
+        lookup = ''
+        if with_lookup:
+            lookup = mcgen('''
+    .lookup = &%(c_name)s_lookup,
+''',
+                           c_name=c_name(name))
+        list_ref = ''
+        if with_list:
+            list_ref = mcgen('''
+    .list = &%(list_id)s,
+''',
+                             list_id=c_name(name + 'List_type_info'))
+        if schema_name is None:
+            masked = self._name_map.get(name)
+            schema_name = '"%s"' % masked if masked is not None else 'NULL'
+        else:
+            schema_name = '"%s"' % schema_name
+        with ifcontext(ifcond or QAPISchemaIfCond(),
+                       self._genh, self._genc):
+            self._genh.add(mcgen('''
+
+extern const QAPITypeInfo %(c_id)s;
+''',
+                                 c_id=c_id))
+            self._genc.add(mcgen('''
+
+const QAPITypeInfo %(c_id)s = {
+    .name = "%(name)s",
+    .schema_name = %(schema_name)s,
+%(lookup)s%(list_ref)s};
+''',
+                                 c_id=c_id, name=name,
+                                 schema_name=schema_name,
+                                 lookup=lookup,
+                                 list_ref=list_ref))
+
+    def _has_list(self, name: str) -> bool:
+        return name + 'List' in self._list_types
+
+    def visit_builtin_type(self,
+                           name: str,
+                           info: Optional[QAPISourceInfo],
+                           json_type: str) -> None:
+        self._gen_type_info(name, with_list=self._has_list(name))
+
+    def visit_enum_type(self,
+                        name: str,
+                        info: Optional[QAPISourceInfo],
+                        ifcond: QAPISchemaIfCond,
+                        features: List[QAPISchemaFeature],
+                        members: List[QAPISchemaEnumMember],
+                        prefix: Optional[str]) -> None:
+        self._gen_type_info(name, ifcond, with_lookup=True,
+                            with_list=self._has_list(name))
+
+    def visit_object_type(self,
+                          name: str,
+                          info: Optional[QAPISourceInfo],
+                          ifcond: QAPISchemaIfCond,
+                          features: List[QAPISchemaFeature],
+                          base: Optional[QAPISchemaObjectType],
+                          members: List[QAPISchemaObjectTypeMember],
+                          branches: Optional[QAPISchemaBranches]) -> None:
+        if name.startswith('q_'):
+            return
+        self._gen_type_info(name, ifcond,
+                            with_list=self._has_list(name))
+
+    def visit_array_type(self,
+                         name: str,
+                         info: Optional[QAPISourceInfo],
+                         ifcond: QAPISchemaIfCond,
+                         element_type: QAPISchemaType) -> None:
+        elem_schema = self._name_map.get(element_type.name,
+                                         element_type.name)
+        self._gen_type_info(name, ifcond,
+                            schema_name='[' + elem_schema + ']')
+
+    def visit_alternate_type(self,
+                             name: str,
+                             info: Optional[QAPISourceInfo],
+                             ifcond: QAPISchemaIfCond,
+                             features: List[QAPISchemaFeature],
+                             alternatives: QAPISchemaAlternatives) -> None:
+        self._gen_type_info(name, ifcond,
+                            with_list=self._has_list(name))
+
+
+def gen_type_infos(schema: QAPISchema,
+                   output_dir: str,
+                   prefix: str,
+                   opt_builtins: bool,
+                   name_map: Dict[str, str]) -> None:
+    collector = _ArrayTypeCollector()
+    schema.visit(collector)
+    vis = QAPISchemaGenTypeInfoVisitor(prefix, name_map,
+                                       collector.list_types)
+    schema.visit(vis)
+    vis.write(output_dir, opt_builtins)

-- 
2.54.0



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

* [PATCH 04/54] qapi/backend: wire up type-infos generation
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (2 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 03/54] qapi: add type-infos generator Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 05/54] qapi/gen: fix _module_basename for multi-dash 'what' parameters Marc-André Lureau
                   ` (50 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Call gen_type_infos() after gen_introspect(), passing the name map so
type-info constants get the correct masked names.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 scripts/qapi/backend.py | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/scripts/qapi/backend.py b/scripts/qapi/backend.py
index 49ae6ecdd33..353f7801149 100644
--- a/scripts/qapi/backend.py
+++ b/scripts/qapi/backend.py
@@ -8,6 +8,7 @@
 from .features import gen_features
 from .introspect import gen_introspect
 from .schema import QAPISchema
+from .type_infos import gen_type_infos
 from .types import gen_types
 from .visit import gen_visit
 
@@ -62,4 +63,5 @@ def generate(self,
         gen_visit(schema, output_dir, prefix, builtins)
         gen_commands(schema, output_dir, prefix, gen_tracing)
         gen_events(schema, output_dir, prefix)
-        gen_introspect(schema, output_dir, prefix, unmask)
+        name_map = gen_introspect(schema, output_dir, prefix, unmask)
+        gen_type_infos(schema, output_dir, prefix, builtins, name_map)

-- 
2.54.0



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

* [PATCH 05/54] qapi/gen: fix _module_basename for multi-dash 'what' parameters
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (3 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 04/54] qapi/backend: wire up type-infos generation Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 06/54] meson: add qapi-type-infos-*.c/h to build Marc-André Lureau
                   ` (49 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

The re.sub() call replaces every hyphen in 'what' with the system module
infix. This produces broken filenames for multi-hyphen names (e.g.
'qapi-type-infos' becomes 'qapi-builtin-type-builtin-infos').

Add count=1 so only the first hyphen is replaced.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 scripts/qapi/gen.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/qapi/gen.py b/scripts/qapi/gen.py
index 0c9b8db3b02..690187d4280 100644
--- a/scripts/qapi/gen.py
+++ b/scripts/qapi/gen.py
@@ -300,7 +300,7 @@ def _module_basename(self, what: str, name: str) -> str:
                 ret += '-' + os.path.splitext(basename)[0]
         else:
             assert QAPISchemaModule.is_system_module(name)
-            ret += re.sub(r'-', '-' + name[2:] + '-', what)
+            ret += re.sub(r'-', '-' + name[2:] + '-', what, count=1)
         return ret
 
     def _module_filename(self, what: str, name: str) -> str:

-- 
2.54.0



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

* [PATCH 06/54] meson: add qapi-type-infos-*.c/h to build
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (4 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 05/54] qapi/gen: fix _module_basename for multi-dash 'what' parameters Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 07/54] qom: add qapi_type field to ObjectProperty Marc-André Lureau
                   ` (48 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Register the new per-module type-infos output files so they are
generated during the QAPI code generation step and compiled into
the build.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 qapi/meson.build              | 4 ++++
 tests/include/meson.build     | 2 ++
 tests/meson.build             | 6 ++++++
 tests/qapi-schema/meson.build | 1 +
 4 files changed, 13 insertions(+)

diff --git a/qapi/meson.build b/qapi/meson.build
index a46269b5a0c..7ae3843de6e 100644
--- a/qapi/meson.build
+++ b/qapi/meson.build
@@ -80,6 +80,7 @@ endif
 qapi_nonmodule_outputs = [
   'qapi-introspect.c', 'qapi-introspect.h',
   'qapi-types.c', 'qapi-types.h',
+  'qapi-type-infos.c', 'qapi-type-infos.h',
   'qapi-visit.h', 'qapi-visit.c',
   'qapi-commands.h', 'qapi-commands.c',
   'qapi-init-commands.h', 'qapi-init-commands.c',
@@ -90,6 +91,7 @@ qapi_nonmodule_outputs = [
 qapi_outputs = qapi_nonmodule_outputs + [
   'qapi-builtin-types.c', 'qapi-builtin-visit.c',
   'qapi-builtin-types.h', 'qapi-builtin-visit.h',
+  'qapi-builtin-type-infos.c', 'qapi-builtin-type-infos.h',
 ]
 
 qapi_inputs = []
@@ -100,6 +102,8 @@ foreach module : qapi_all_modules
     'qapi-types-@0@.h'.format(module),
     'qapi-visit-@0@.c'.format(module),
     'qapi-visit-@0@.h'.format(module),
+    'qapi-type-infos-@0@.c'.format(module),
+    'qapi-type-infos-@0@.h'.format(module),
   ]
   if have_system or have_tools
     qapi_module_outputs += [
diff --git a/tests/include/meson.build b/tests/include/meson.build
index 8e8d1ec4e69..026480d9685 100644
--- a/tests/include/meson.build
+++ b/tests/include/meson.build
@@ -4,6 +4,8 @@ test_qapi_outputs_extra = [
   'test-qapi-commands-sub-module.h',
   'test-qapi-events-sub-module.c',
   'test-qapi-events-sub-module.h',
+  'test-qapi-type-infos-sub-module.c',
+  'test-qapi-type-infos-sub-module.h',
   'test-qapi-types-sub-module.c',
   'test-qapi-types-sub-module.h',
   'test-qapi-visit-sub-module.c',
diff --git a/tests/meson.build b/tests/meson.build
index 9ba04bbedd3..71dc4ac8bf9 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -2,6 +2,8 @@ subdir('bench')
 subdir('qemu-iotests')
 
 test_qapi_outputs = [
+  'qapi-builtin-type-infos.c',
+  'qapi-builtin-type-infos.h',
   'qapi-builtin-types.c',
   'qapi-builtin-types.h',
   'qapi-builtin-visit.c',
@@ -22,6 +24,10 @@ test_qapi_outputs = [
   'test-qapi-init-commands.h',
   'test-qapi-introspect.c',
   'test-qapi-introspect.h',
+  'test-qapi-type-infos-sub-sub-module.c',
+  'test-qapi-type-infos-sub-sub-module.h',
+  'test-qapi-type-infos.c',
+  'test-qapi-type-infos.h',
   'test-qapi-types-sub-sub-module.c',
   'test-qapi-types-sub-sub-module.h',
   'test-qapi-types.c',
diff --git a/tests/qapi-schema/meson.build b/tests/qapi-schema/meson.build
index debff633ac1..b10f081554d 100644
--- a/tests/qapi-schema/meson.build
+++ b/tests/qapi-schema/meson.build
@@ -232,6 +232,7 @@ custom_target('QAPI doc',
                        'doc-good-qapi-init-commands.c', 'doc-good-qapi-init-commands.h',
                        'doc-good-qapi-introspect.c', 'doc-good-qapi-introspect.h',
                        'doc-good-qapi-types.c', 'doc-good-qapi-types.h',
+                       'doc-good-qapi-type-infos.c', 'doc-good-qapi-type-infos.h',
                        'doc-good-qapi-visit.c', 'doc-good-qapi-visit.h' ],
               input: files('doc-good.json'),
               command: [ qapi_gen, '-o', meson.current_build_dir(),

-- 
2.54.0



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

* [PATCH 07/54] qom: add qapi_type field to ObjectProperty
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (5 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 06/54] meson: add qapi-type-infos-*.c/h to build Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 08/54] qapi/qom: add qapi-type field to ObjectPropertyInfo Marc-André Lureau
                   ` (47 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Add a const pointer to QAPITypeInfo in ObjectProperty. NULL for legacy
properties, set by new QAPI-aware registration wrappers.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/qom/object.h | 2 ++
 qom/object.c         | 1 +
 2 files changed, 3 insertions(+)

diff --git a/include/qom/object.h b/include/qom/object.h
index 510885218ba..d47ae209170 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -15,6 +15,7 @@
 #define QEMU_OBJECT_H
 
 #include "qapi/qapi-builtin-types.h"
+#include "qapi/qapi-type-info.h"
 #include "qemu/module.h"
 
 struct TypeImpl;
@@ -91,6 +92,7 @@ struct ObjectProperty
     char *name;
     char *type;
     char *description;
+    const QAPITypeInfo *qapi_type;
     ObjectPropertyAccessor *get;
     ObjectPropertyAccessor *set;
     ObjectPropertyResolve *resolve;
diff --git a/qom/object.c b/qom/object.c
index f981e270440..dd657903f7c 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -2803,6 +2803,7 @@ object_property_add_alias(Object *obj, const char *name,
                              property_release_alias,
                              prop);
     op->resolve = property_resolve_alias;
+    op->qapi_type = target_prop->qapi_type;
     if (target_prop->defval) {
         op->defval = qobject_ref(target_prop->defval);
     }

-- 
2.54.0



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

* [PATCH 08/54] qapi/qom: add qapi-type field to ObjectPropertyInfo
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (6 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 07/54] qom: add qapi_type field to ObjectProperty Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 09/54] qom/qmp: populate qapi-type in QMP handlers Marc-André Lureau
                   ` (46 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Add an optional 'qapi-type' field to ObjectPropertyInfo and
ObjectPropertyValue. When present, it contains the masked type name that
can be looked up in query-qmp-schema output. Absent for properties
without a QAPI type association.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 qapi/qom.json | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/qapi/qom.json b/qapi/qom.json
index dd45ac1087c..a655be0beaa 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -35,6 +35,11 @@
 #        qdev device type name.  Link properties form the device model
 #        graph.
 #
+# @qapi-type: if the property was registered with a QAPI type
+#     association, the type name as it appears in the output of
+#     ``query-qmp-schema``.  Absent for properties without a QAPI
+#     type association.  (since 11.1)
+#
 # @description: if specified, the description of the property.
 #
 # @default-value: the default value, if any (since 5.0)
@@ -44,6 +49,7 @@
 { 'struct': 'ObjectPropertyInfo',
   'data': { 'name': 'str',
             'type': 'str',
+            '*qapi-type': 'str',
             '*description': 'str',
             '*default-value': 'any' } }
 
@@ -55,6 +61,11 @@
 # @type: the type of the property, as described in
 #     `ObjectPropertyInfo`.
 #
+# @qapi-type: if the property was registered with a QAPI type
+#     association, the type name as it appears in the output of
+#     ``query-qmp-schema``.  Absent for properties without a QAPI
+#     type association.  (since 11.1)
+#
 # @value: the value of the property.  Absent when the property cannot
 #     be read.
 #
@@ -63,6 +74,7 @@
 { 'struct': 'ObjectPropertyValue',
   'data': { 'name': 'str',
             'type': 'str',
+            '*qapi-type': 'str',
             '*value': 'any' } }
 
 ##

-- 
2.54.0



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

* [PATCH 09/54] qom/qmp: populate qapi-type in QMP handlers
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (7 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 08/54] qapi/qom: add qapi-type field to ObjectPropertyInfo Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 10/54] qom: add QAPI-aware property registration Marc-André Lureau
                   ` (45 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Wire up the new qapi-type field in all four QMP handlers that return
ObjectPropertyInfo or ObjectPropertyValue: qom-list, qom-list-get,
device-list-properties, and qom-list-properties.

When an ObjectProperty has a qapi_type set, the masked QAPI type name
is copied into the response, allowing clients to cross-reference with
query-qmp-schema.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 qom/qom-qmp-cmds.c | 32 +++++++++++++++++++-------------
 1 file changed, 19 insertions(+), 13 deletions(-)

diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c
index 48b38d2b7f7..30af2cef53e 100644
--- a/qom/qom-qmp-cmds.c
+++ b/qom/qom-qmp-cmds.c
@@ -25,9 +25,22 @@
 #include "qapi/qobject-input-visitor.h"
 #include "qapi/qobject-output-visitor.h"
 #include "qemu/cutils.h"
+#include "qapi/qapi-type-info.h"
 #include "qom/object_interfaces.h"
 #include "qom/qom-qobject.h"
 
+static ObjectPropertyInfo *qom_property_info(ObjectProperty *prop)
+{
+    ObjectPropertyInfo *info = g_new0(ObjectPropertyInfo, 1);
+
+    info->name = g_strdup(prop->name);
+    info->type = g_strdup(prop->type);
+    if (prop->qapi_type) {
+        info->qapi_type = g_strdup(prop->qapi_type->schema_name);
+    }
+    return info;
+}
+
 static Object *qom_resolve_path(const char *path, Error **errp)
 {
     bool ambiguous = false;
@@ -58,12 +71,7 @@ ObjectPropertyInfoList *qmp_qom_list(const char *path, Error **errp)
 
     object_property_iter_init(&iter, obj);
     while ((prop = object_property_iter_next(&iter))) {
-        ObjectPropertyInfo *value = g_new0(ObjectPropertyInfo, 1);
-
-        QAPI_LIST_PREPEND(props, value);
-
-        value->name = g_strdup(prop->name);
-        value->type = g_strdup(prop->type);
+        QAPI_LIST_PREPEND(props, qom_property_info(prop));
     }
 
     return props;
@@ -78,6 +86,9 @@ static void qom_list_add_property_value(Object *obj, ObjectProperty *prop,
 
     item->name = g_strdup(prop->name);
     item->type = g_strdup(prop->type);
+    if (prop->qapi_type) {
+        item->qapi_type = g_strdup(prop->qapi_type->schema_name);
+    }
     item->value = object_property_get_qobject(obj, prop->name, NULL);
 }
 
@@ -225,9 +236,7 @@ ObjectPropertyInfoList *qmp_device_list_properties(const char *typename,
             continue;
         }
 
-        info = g_new0(ObjectPropertyInfo, 1);
-        info->name = g_strdup(prop->name);
-        info->type = g_strdup(prop->type);
+        info = qom_property_info(prop);
         info->description = g_strdup(prop->description);
         info->default_value = qobject_ref(prop->defval);
 
@@ -268,11 +277,8 @@ ObjectPropertyInfoList *qmp_qom_list_properties(const char *typename,
         object_property_iter_init(&iter, obj);
     }
     while ((prop = object_property_iter_next(&iter))) {
-        ObjectPropertyInfo *info;
+        ObjectPropertyInfo *info = qom_property_info(prop);
 
-        info = g_malloc0(sizeof(*info));
-        info->name = g_strdup(prop->name);
-        info->type = g_strdup(prop->type);
         info->description = g_strdup(prop->description);
         info->default_value = qobject_ref(prop->defval);
 

-- 
2.54.0



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

* [PATCH 10/54] qom: add QAPI-aware property registration
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (8 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 09/54] qom/qmp: populate qapi-type in QMP handlers Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 11/54] tests: update check-qom-proplist for " Marc-André Lureau
                   ` (44 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Add object{_class}_property_add_qapi_enum(), and
object_{_class}_property_add_qapi() functions. Set the qapi_type pointer
on the resulting ObjectProperty.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/qom/object.h | 105 +++++++++++++++++++++++++++++++++++++++++
 qom/object.c         | 131 +++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 232 insertions(+), 4 deletions(-)

diff --git a/include/qom/object.h b/include/qom/object.h
index d47ae209170..0eaa02688b0 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1140,6 +1140,15 @@ void object_property_set_default_bool(ObjectProperty *prop, bool value);
  */
 void object_property_set_default_str(ObjectProperty *prop, const char *value);
 
+/**
+ * object_property_set_default_enum:
+ * @prop: the property to set
+ * @value: the value to be written to the property
+ *
+ * Set the property default value.
+ */
+void object_property_set_default_enum(ObjectProperty *prop, int value);
+
 /**
  * object_property_set_default_list:
  * @prop: the property to set
@@ -1815,6 +1824,102 @@ ObjectProperty *object_class_property_add_enum(ObjectClass *klass,
                                     int (*get)(Object *, Error **),
                                     void (*set)(Object *, int, Error **));
 
+/**
+ * struct QapiEnumProp - Descriptor for a QOM property backed by a QAPI enum type
+ *
+ * Binds a QOM object property to a QAPI enum, providing automatic
+ * string<->int conversion through QAPI visitors and optional
+ * default-value initialization during object instance init.
+ *
+ * Use the QAPI_ENUM_PROP() macro to construct instances inline.
+ *
+ * @name: property name exposed on the QOM object
+ * @description: human-readable description (shown in ``-device help``, etc.)
+ * @default_value: initial enum value applied via @set during instance init,
+ *                 or -1 (the QAPI_ENUM_PROP default) to skip initialization
+ * @qapi_type: pointer to the generated QAPITypeInfo for the enum
+ *             (provides the string<->int lookup table)
+ * @get: getter — returns the current enum value as int, or -1 on error
+ * @set: setter — receives the enum value as int; %NULL for read-only props
+ */
+typedef struct QapiEnumProp {
+    const char *name;
+    const char *description;
+    const int default_value;
+    const QAPITypeInfo *qapi_type;
+    int (*get)(Object *, Error **);
+    void (*set)(Object *, int, Error **);
+} QapiEnumProp;
+
+#define QAPI_ENUM_PROP(...) ({                                           \
+    static const QapiEnumProp _prop = {                                  \
+        .default_value = -1, __VA_ARGS__                                 \
+    };                                                                   \
+    &_prop; })
+
+/**
+ * object_property_add_qapi_enum:
+ * @obj: the object to add a property to
+ * @prop: property descriptor
+ *
+ * Add an enum property with QAPI type association.
+ *
+ * Use the QAPI_ENUM_PROP() macro to construct the property descriptor
+ * inline. If .default_value is not set, the property is not initialized
+ * (default_value is -1). Otherwise, the setter is called with
+ * default_value during object instance init.
+ *
+ * Example::
+ *
+ *   object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+ *       .name = "policy",
+ *       .description = "Set the NUMA policy",
+ *       .default_value = HOST_MEM_POLICY_DEFAULT,
+ *       .qapi_type = &HostMemPolicy_type_info,
+ *       .get = my_get_policy,
+ *       .set = my_set_policy,
+ *   ));
+ *
+ * Returns: The newly added property on success, or %NULL on failure.
+ */
+ObjectProperty *
+object_property_add_qapi_enum(Object *obj, const QapiEnumProp *prop);
+
+ObjectProperty *
+object_class_property_add_qapi_enum(ObjectClass *klass, const QapiEnumProp *prop);
+
+/**
+ * object_property_add_qapi:
+ * @obj: the object to add a property to
+ * @name: the name of the property
+ * @qapi_type: QAPI type info descriptor
+ * @get: the getter or %NULL if the property is write-only.
+ * @set: the setter or %NULL if the property is read-only
+ * @release: called when the property is removed from the object
+ * @opaque: opaque pointer for get/set/release
+ *
+ * Add a property with a QAPI type association. The property type name
+ * is derived from @qapi_type->name.
+ *
+ * Returns: The newly added property on success, or %NULL on failure.
+ */
+ObjectProperty *
+object_property_add_qapi(Object *obj, const char *name,
+                         const QAPITypeInfo *qapi_type,
+                         ObjectPropertyAccessor *get,
+                         ObjectPropertyAccessor *set,
+                         ObjectPropertyRelease *release,
+                         void *opaque);
+
+ObjectProperty *
+object_class_property_add_qapi(ObjectClass *klass,
+                               const char *name,
+                               const QAPITypeInfo *qapi_type,
+                               ObjectPropertyAccessor *get,
+                               ObjectPropertyAccessor *set,
+                               ObjectPropertyRelease *release,
+                               void *opaque);
+
 /**
  * object_property_add_tm:
  * @obj: the object to add a property to
diff --git a/qom/object.c b/qom/object.c
index dd657903f7c..164907289a6 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -23,6 +23,7 @@
 #include "qapi/qobject-input-visitor.h"
 #include "qapi/forward-visitor.h"
 #include "qapi/qapi-builtin-visit.h"
+#include "qapi/qapi-type-info.h"
 #include "qobject/qjson.h"
 #include "trace.h"
 
@@ -1547,6 +1548,15 @@ void object_property_set_default_str(ObjectProperty *prop, const char *value)
     object_property_set_default(prop, QOBJECT(qstring_from_str(value)));
 }
 
+void object_property_set_default_enum(ObjectProperty *prop, int value)
+{
+    assert(prop && prop->qapi_type && prop->qapi_type->lookup);
+
+    object_property_set_default(prop, QOBJECT(qstring_from_str(
+        qapi_enum_lookup(prop->qapi_type->lookup, value)
+    )));
+}
+
 void object_property_set_default_list(ObjectProperty *prop)
 {
     object_property_set_default(prop, QOBJECT(qlist_new()));
@@ -1605,7 +1615,6 @@ int object_property_get_enum(Object *obj, const char *name,
     char *str;
     int ret;
     ObjectProperty *prop = object_property_find_err(obj, name, errp);
-    EnumProperty *enumprop;
 
     if (prop == NULL) {
         return -1;
@@ -1618,14 +1627,17 @@ int object_property_get_enum(Object *obj, const char *name,
         return -1;
     }
 
-    enumprop = prop->opaque;
-
     str = object_property_get_str(obj, name, errp);
     if (!str) {
         return -1;
     }
 
-    ret = qapi_enum_parse(enumprop->lookup, str, -1, errp);
+    if (prop->qapi_type) {
+        ret = qapi_enum_parse(prop->qapi_type->lookup, str, -1, errp);
+    } else {
+        EnumProperty *enumprop = prop->opaque;
+        ret = qapi_enum_parse(enumprop->lookup, str, -1, errp);
+    }
     g_free(str);
 
     return ret;
@@ -2418,6 +2430,117 @@ object_class_property_add_enum(ObjectClass *klass, const char *name,
                                      prop);
 }
 
+static void get_qapi_enum(Object *obj, Visitor *v, const char *name,
+                          void *opaque, Error **errp)
+{
+    const QapiEnumProp *prop = opaque;
+    int value;
+    Error *err = NULL;
+
+    value = prop->get(obj, &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+
+    visit_type_enum(v, name, &value, prop->qapi_type->lookup, errp);
+}
+
+static void set_qapi_enum(Object *obj, Visitor *v, const char *name,
+                          void *opaque, Error **errp)
+{
+    const QapiEnumProp *prop = opaque;
+    int value;
+
+    if (!visit_type_enum(v, name, &value, prop->qapi_type->lookup, errp)) {
+        return;
+    }
+    prop->set(obj, value, errp);
+}
+
+static void init_qapi_enum(Object *obj, ObjectProperty *prop)
+{
+    const QapiEnumProp *e = prop->opaque;
+
+    if (e->set && e->default_value >= 0) {
+        e->set(obj, e->default_value, &error_abort);
+    }
+}
+
+ObjectProperty *
+object_property_add_qapi_enum(Object *obj, const QapiEnumProp *e)
+{
+    ObjectProperty *prop;
+
+    assert(e && e->qapi_type && e->qapi_type->lookup);
+
+    prop = object_property_add(obj, e->name, e->qapi_type->name,
+                               e->get ? get_qapi_enum : NULL,
+                               e->set ? set_qapi_enum : NULL,
+                               NULL,
+                               (void *)e);
+    prop->qapi_type = e->qapi_type;
+    prop->description = g_strdup(e->description);
+    if (e->default_value >= 0) {
+        prop->init = init_qapi_enum;
+    }
+
+    return prop;
+}
+
+ObjectProperty *
+object_class_property_add_qapi_enum(ObjectClass *klass, const QapiEnumProp *e)
+{
+    ObjectProperty *prop;
+
+    assert(e && e->qapi_type && e->qapi_type->lookup);
+
+    prop = object_class_property_add(klass, e->name, e->qapi_type->name,
+                                     e->get ? get_qapi_enum : NULL,
+                                     e->set ? set_qapi_enum : NULL,
+                                     NULL,
+                                     (void *)e);
+    prop->qapi_type = e->qapi_type;
+    prop->description = g_strdup(e->description);
+    if (e->default_value >= 0) {
+        prop->init = init_qapi_enum;
+    }
+
+    return prop;
+}
+
+ObjectProperty *
+object_property_add_qapi(Object *obj, const char *name,
+                         const QAPITypeInfo *qapi_type,
+                         ObjectPropertyAccessor *get,
+                         ObjectPropertyAccessor *set,
+                         ObjectPropertyRelease *release,
+                         void *opaque)
+{
+    ObjectProperty *prop;
+
+    prop = object_property_add(obj, name, qapi_type->name,
+                               get, set, release, opaque);
+    prop->qapi_type = qapi_type;
+    return prop;
+}
+
+ObjectProperty *
+object_class_property_add_qapi(ObjectClass *klass, const char *name,
+                               const QAPITypeInfo *qapi_type,
+                               ObjectPropertyAccessor *get,
+                               ObjectPropertyAccessor *set,
+                               ObjectPropertyRelease *release,
+                               void *opaque)
+{
+    ObjectProperty *prop;
+
+    prop = object_class_property_add(klass, name, qapi_type->name,
+                                     get, set, release, opaque);
+    prop->qapi_type = qapi_type;
+    return prop;
+}
+
 typedef struct TMProperty {
     void (*get)(Object *, struct tm *, Error **);
 } TMProperty;

-- 
2.54.0



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

* [PATCH 11/54] tests: update check-qom-proplist for QAPI-aware property registration
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (9 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 10/54] qom: add QAPI-aware property registration Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 12/54] qom: convert enum properties to QAPI-aware registration Marc-André Lureau
                   ` (43 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Migrate the dummy object's string and enum properties from the legacy
object_class_property_add_str/enum() helpers to the new QAPI-aware
object_class_property_add_qapi/qapi_enum() registration.

Add test cases verifying that the qapi_type metadata is correctly
populated on properties registered through the new API, and that it
remains NULL for properties using the old-style registration.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 tests/unit/check-qom-proplist.c | 94 ++++++++++++++++++++++++++++++++++-------
 1 file changed, 78 insertions(+), 16 deletions(-)

diff --git a/tests/unit/check-qom-proplist.c b/tests/unit/check-qom-proplist.c
index ee3c6fb32b1..7f10befe687 100644
--- a/tests/unit/check-qom-proplist.c
+++ b/tests/unit/check-qom-proplist.c
@@ -21,6 +21,7 @@
 #include "qemu/osdep.h"
 
 #include "qapi/error.h"
+#include "qapi/qapi-type-info.h"
 #include "qapi/qobject-input-visitor.h"
 #include "qobject/qdict.h"
 #include "qobject/qobject.h"
@@ -108,22 +109,21 @@ static int dummy_get_av(Object *obj,
 }
 
 
-static void dummy_set_sv(Object *obj,
-                         const char *value,
-                         Error **errp)
+static void dummy_set_sv(Object *obj, Visitor *v, const char *name,
+                         void *opaque, Error **errp)
 {
     DummyObject *dobj = DUMMY_OBJECT(obj);
 
-    g_free(dobj->sv);
-    dobj->sv = g_strdup(value);
+    g_clear_pointer(&dobj->sv, g_free);
+    visit_type_str(v, name, &dobj->sv, errp);
 }
 
-static char *dummy_get_sv(Object *obj,
-                          Error **errp)
+static void dummy_get_sv(Object *obj, Visitor *v, const char *name,
+                         void *opaque, Error **errp)
 {
     DummyObject *dobj = DUMMY_OBJECT(obj);
 
-    return g_strdup(dobj->sv);
+    visit_type_str(v, name, &dobj->sv, errp);
 }
 
 
@@ -135,16 +135,28 @@ static void dummy_init(Object *obj)
 }
 
 
+static const QAPITypeInfo dummy_animal_qapi_type_info = {
+    .name = "DummyAnimal",
+    .schema_name = "DummyAnimalSchema",
+    .lookup = &dummy_animal_map,
+};
+
+static const QAPITypeInfo dummy_str_qapi_type_info = {
+    .name = "str",
+    .schema_name = "StrSchema",
+};
+
 static void dummy_class_init(ObjectClass *cls, const void *data)
 {
-    object_class_property_add_str(cls, "sv",
-                                  dummy_get_sv,
-                                  dummy_set_sv);
-    object_class_property_add_enum(cls, "av",
-                                   "DummyAnimal",
-                                   &dummy_animal_map,
-                                   dummy_get_av,
-                                   dummy_set_av);
+    object_class_property_add_qapi(cls, "sv", &dummy_str_qapi_type_info,
+                                   dummy_get_sv, dummy_set_sv,
+                                   NULL, NULL);
+    object_class_property_add_qapi_enum(cls, QAPI_ENUM_PROP(
+        .name = "av",
+        .qapi_type = &dummy_animal_qapi_type_info,
+        .get = dummy_get_av,
+        .set = dummy_set_av,
+    ));
 }
 
 
@@ -648,6 +660,54 @@ static void test_qom_partial_path(void)
     object_unparent(cont1);
 }
 
+static void test_dummy_qapi_enum(void)
+{
+    ObjectProperty *prop;
+    Object *parent = object_get_objects_root();
+    DummyObject *dobj = DUMMY_OBJECT(
+        object_new_with_props(TYPE_DUMMY,
+                              parent,
+                              "dummy0",
+                              &error_abort,
+                              "av", "platypus",
+                              NULL));
+
+    g_assert(dobj->av == DUMMY_PLATYPUS);
+
+    prop = object_property_find(OBJECT(dobj), "av");
+    g_assert(prop);
+    g_assert(prop->qapi_type == &dummy_animal_qapi_type_info);
+    g_assert_cmpstr(prop->qapi_type->name, ==, "DummyAnimal");
+    g_assert_cmpstr(prop->qapi_type->schema_name, ==, "DummyAnimalSchema");
+    g_assert(prop->qapi_type->lookup == &dummy_animal_map);
+
+    object_unparent(OBJECT(dobj));
+}
+
+static void test_dummy_qapi_prop(void)
+{
+    ObjectProperty *prop;
+    Object *parent = object_get_objects_root();
+    DummyObject *dobj = DUMMY_OBJECT(
+        object_new_with_props(TYPE_DUMMY,
+                              parent,
+                              "dummy0",
+                              &error_abort,
+                              "sv", "hello",
+                              NULL));
+
+    g_assert_cmpstr(dobj->sv, ==, "hello");
+
+    prop = object_property_find(OBJECT(dobj), "sv");
+    g_assert(prop);
+    g_assert(prop->qapi_type == &dummy_str_qapi_type_info);
+    g_assert_cmpstr(prop->qapi_type->name, ==, "str");
+    g_assert_cmpstr(prop->qapi_type->schema_name, ==, "StrSchema");
+    g_assert(prop->qapi_type->lookup == NULL);
+
+    object_unparent(OBJECT(dobj));
+}
+
 int main(int argc, char **argv)
 {
     g_test_init(&argc, &argv, NULL);
@@ -666,6 +726,8 @@ int main(int argc, char **argv)
     g_test_add_func("/qom/proplist/iterator", test_dummy_iterator);
     g_test_add_func("/qom/proplist/class_iterator", test_dummy_class_iterator);
     g_test_add_func("/qom/proplist/delchild", test_dummy_delchild);
+    g_test_add_func("/qom/proplist/qapi_enum", test_dummy_qapi_enum);
+    g_test_add_func("/qom/proplist/qapi_prop", test_dummy_qapi_prop);
     g_test_add_func("/qom/resolve/partial", test_qom_partial_path);
 
     return g_test_run();

-- 
2.54.0



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

* [PATCH 12/54] qom: convert enum properties to QAPI-aware registration
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (10 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 11/54] tests: update check-qom-proplist for " Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 13/54] qom: remove old enum property registration API Marc-André Lureau
                   ` (42 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Convert all callers of object_class_property_add_enum() to use the new
object_class_property_add_qapi_enum() with the QAPI_ENUM_PROP()
macro, which provides type information via QAPITypeInfo instead of
raw lookup tables and string type names.

This enables QMP introspection to report accurate QAPI type names
for enum properties. Where a separate set_description call was used,
the description is now embedded in the QAPI_ENUM_PROP initializer.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 authz/list.c                             | 12 +++++++-----
 backends/hostmem.c                       | 14 ++++++++------
 crypto/secret_common.c                   | 12 +++++++-----
 crypto/tlscreds.c                        | 12 +++++++-----
 hw/i386/pc_piix.c                        | 19 +++++++++++++------
 hw/microblaze/petalogix_s3adsp1800_mmu.c | 19 +++++++++++--------
 net/filter.c                             | 10 +++++++---
 target/i386/kvm/kvm.c                    | 30 +++++++++++++++++-------------
 ui/dbus.c                                | 10 +++++++---
 ui/input-linux.c                         | 11 +++++++----
 10 files changed, 91 insertions(+), 58 deletions(-)

diff --git a/authz/list.c b/authz/list.c
index 17aa0efd80e..363b2ee12c9 100644
--- a/authz/list.c
+++ b/authz/list.c
@@ -22,6 +22,7 @@
 #include "authz/list.h"
 #include "trace.h"
 #include "qom/object_interfaces.h"
+#include "qapi/qapi-type-infos-authz.h"
 #include "qapi/qapi-visit-authz.h"
 #include "qemu/module.h"
 
@@ -120,11 +121,12 @@ qauthz_list_class_init(ObjectClass *oc, const void *data)
 {
     QAuthZClass *authz = QAUTHZ_CLASS(oc);
 
-    object_class_property_add_enum(oc, "policy",
-                                   "QAuthZListPolicy",
-                                   &QAuthZListPolicy_lookup,
-                                   qauthz_list_prop_get_policy,
-                                   qauthz_list_prop_set_policy);
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = "policy",
+        .qapi_type = &QAuthZListPolicy_type_info,
+        .get = qauthz_list_prop_get_policy,
+        .set = qauthz_list_prop_set_policy,
+    ));
 
     object_class_property_add(oc, "rules", "QAuthZListRule",
                               qauthz_list_prop_get_rules,
diff --git a/backends/hostmem.c b/backends/hostmem.c
index cd2085fb3cd..d0977552b40 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -16,6 +16,7 @@
 #include "hw/core/boards.h"
 #include "qapi/error.h"
 #include "qapi/qapi-builtin-visit.h"
+#include "qapi/qapi-type-infos-common.h"
 #include "qapi/visitor.h"
 #include "qemu/config-file.h"
 #include "qom/compat-properties.h"
@@ -548,12 +549,13 @@ host_memory_backend_class_init(ObjectClass *oc, const void *data)
         NULL, NULL);
     object_class_property_set_description(oc, "host-nodes",
         "Binds memory to the list of NUMA host nodes");
-    object_class_property_add_enum(oc, "policy", "HostMemPolicy",
-        &HostMemPolicy_lookup,
-        host_memory_backend_get_policy,
-        host_memory_backend_set_policy);
-    object_class_property_set_description(oc, "policy",
-        "Set the NUMA policy");
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = "policy",
+        .description = "Set the NUMA policy",
+        .qapi_type = &HostMemPolicy_type_info,
+        .get = host_memory_backend_get_policy,
+        .set = host_memory_backend_set_policy,
+    ));
     object_class_property_add_bool(oc, "share",
         host_memory_backend_get_share, host_memory_backend_set_share);
     object_class_property_set_description(oc, "share",
diff --git a/crypto/secret_common.c b/crypto/secret_common.c
index a5ecb876aeb..381d23ecc8e 100644
--- a/crypto/secret_common.c
+++ b/crypto/secret_common.c
@@ -22,6 +22,7 @@
 #include "crypto/secret_common.h"
 #include "crypto/cipher.h"
 #include "qapi/error.h"
+#include "qapi/qapi-type-infos-crypto.h"
 #include "qom/object_interfaces.h"
 #include "qemu/base64.h"
 #include "qemu/module.h"
@@ -269,11 +270,12 @@ qcrypto_secret_class_init(ObjectClass *oc, const void *data)
 
     ucc->complete = qcrypto_secret_complete;
 
-    object_class_property_add_enum(oc, "format",
-                                   "QCryptoSecretFormat",
-                                   &QCryptoSecretFormat_lookup,
-                                   qcrypto_secret_prop_get_format,
-                                   qcrypto_secret_prop_set_format);
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = "format",
+        .qapi_type = &QCryptoSecretFormat_type_info,
+        .get = qcrypto_secret_prop_get_format,
+        .set = qcrypto_secret_prop_set_format,
+    ));
     object_class_property_add_str(oc, "keyid",
                                   qcrypto_secret_prop_get_keyid,
                                   qcrypto_secret_prop_set_keyid);
diff --git a/crypto/tlscreds.c b/crypto/tlscreds.c
index fb09e295a65..54859720bf7 100644
--- a/crypto/tlscreds.c
+++ b/crypto/tlscreds.c
@@ -20,6 +20,7 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
+#include "qapi/qapi-type-infos-crypto.h"
 #include "qapi-types-crypto.h"
 #include "qemu/module.h"
 #include "qemu/error-report.h"
@@ -221,11 +222,12 @@ qcrypto_tls_creds_class_init(ObjectClass *oc, const void *data)
     object_class_property_add_str(oc, "dir",
                                   qcrypto_tls_creds_prop_get_dir,
                                   qcrypto_tls_creds_prop_set_dir);
-    object_class_property_add_enum(oc, "endpoint",
-                                   "QCryptoTLSCredsEndpoint",
-                                   &QCryptoTLSCredsEndpoint_lookup,
-                                   qcrypto_tls_creds_prop_get_endpoint,
-                                   qcrypto_tls_creds_prop_set_endpoint);
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = "endpoint",
+        .qapi_type = &QCryptoTLSCredsEndpoint_type_info,
+        .get = qcrypto_tls_creds_prop_get_endpoint,
+        .set = qcrypto_tls_creds_prop_set_endpoint,
+    ));
     object_class_property_add_str(oc, "priority",
                                   qcrypto_tls_creds_prop_get_priority,
                                   qcrypto_tls_creds_prop_set_priority);
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 82457bdb167..91a371b12d7 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -47,6 +47,7 @@
 #include "hw/acpi/acpi.h"
 #include "hw/vfio/types.h"
 #include "qapi/error.h"
+#include "qapi/qapi-type-info.h"
 #include "qemu/error-report.h"
 #include "system/xen.h"
 #ifdef CONFIG_XEN
@@ -336,6 +337,11 @@ static const QEnumLookup PCSouthBridgeOption_lookup = {
     .size = PC_SOUTH_BRIDGE_OPTION_MAX
 };
 
+static const QAPITypeInfo PCSouthBridgeOption_type_info = {
+    .name = "PCSouthBridgeOption",
+    .lookup = &PCSouthBridgeOption_lookup,
+};
+
 static int pc_get_south_bridge(Object *obj, Error **errp)
 {
     PCMachineState *pcms = PC_MACHINE(obj);
@@ -418,12 +424,13 @@ static void pc_i440fx_machine_options(MachineClass *m)
     machine_class_allow_dynamic_sysbus_dev(m, TYPE_VMBUS_BRIDGE);
     machine_class_allow_dynamic_sysbus_dev(m, TYPE_UEFI_VARS_X64);
 
-    object_class_property_add_enum(oc, "x-south-bridge", "PCSouthBridgeOption",
-                                   &PCSouthBridgeOption_lookup,
-                                   pc_get_south_bridge,
-                                   pc_set_south_bridge);
-    object_class_property_set_description(oc, "x-south-bridge",
-                                     "Use a different south bridge than PIIX3");
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = "x-south-bridge",
+        .description = "Use a different south bridge than PIIX3",
+        .qapi_type = &PCSouthBridgeOption_type_info,
+        .get = pc_get_south_bridge,
+        .set = pc_set_south_bridge,
+    ));
     compat_props_add(m->compat_props,
                      pc_piix_compat_defaults, pc_piix_compat_defaults_len);
 }
diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c
index c5f64319009..9a8fcc66781 100644
--- a/hw/microblaze/petalogix_s3adsp1800_mmu.c
+++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c
@@ -27,6 +27,7 @@
 #include "qemu/target-info.h"
 #include "qemu/units.h"
 #include "qapi/error.h"
+#include "qapi/qapi-type-infos-common.h"
 #include "target/microblaze/cpu.h"
 #include "hw/core/sysbus.h"
 #include "net/net.h"
@@ -174,14 +175,16 @@ static void petalogix_s3adsp1800_machine_class_init(ObjectClass *oc,
     mc->init = petalogix_s3adsp1800_init;
     mc->is_default = true;
 
-    prop = object_class_property_add_enum(oc, "endianness", "EndianMode",
-                                          &EndianMode_lookup,
-                                          machine_get_endianness,
-                                          machine_set_endianness);
-    object_property_set_default_str(prop, target_big_endian() ? "big"
-                                                              : "little");
-    object_class_property_set_description(oc, "endianness",
-            "Defines whether the machine runs in big or little endian mode");
+    prop = object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = "endianness",
+        .description =
+            "Defines whether the machine runs in big or little endian mode",
+        .qapi_type = &EndianMode_type_info,
+        .get = machine_get_endianness,
+        .set = machine_set_endianness,
+    ));
+    object_property_set_default_enum(prop,
+        target_big_endian() ? ENDIAN_MODE_BIG : ENDIAN_MODE_LITTLE);
 }
 
 static const TypeInfo petalogix_s3adsp1800_machine_types[] = {
diff --git a/net/filter.c b/net/filter.c
index c7cc6615dc9..42e5d7c9072 100644
--- a/net/filter.c
+++ b/net/filter.c
@@ -8,6 +8,7 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
+#include "qapi/qapi-type-infos-common.h"
 #include "qapi/qmp/qerror.h"
 #include "qemu/error-report.h"
 
@@ -340,9 +341,12 @@ static void netfilter_class_init(ObjectClass *oc, const void *data)
 
     object_class_property_add_str(oc, "netdev",
                                   netfilter_get_netdev_id, netfilter_set_netdev_id);
-    object_class_property_add_enum(oc, "queue", "NetFilterDirection",
-                                   &NetFilterDirection_lookup,
-                                   netfilter_get_direction, netfilter_set_direction);
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = "queue",
+        .qapi_type = &NetFilterDirection_type_info,
+        .get = netfilter_get_direction,
+        .set = netfilter_set_direction,
+    ));
     object_class_property_add_str(oc, "status",
                                   netfilter_get_status, netfilter_set_status);
     object_class_property_add_str(oc, "position",
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 9e352882c8c..ecf0c76fcdf 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -14,6 +14,8 @@
 
 #include "qemu/osdep.h"
 #include "qapi/qapi-events-run-state.h"
+#include "qapi/qapi-type-infos-common.h"
+#include "qapi/qapi-type-infos-run-state.h"
 #include "qapi/error.h"
 #include "qapi/visitor.h"
 #include <math.h>
@@ -7086,12 +7088,13 @@ static void kvm_arch_set_honor_guest_pat(Object *obj, int value, Error **errp)
 
 void kvm_arch_accel_class_init(ObjectClass *oc)
 {
-    object_class_property_add_enum(oc, "notify-vmexit", "NotifyVMexitOption",
-                                   &NotifyVmexitOption_lookup,
-                                   kvm_arch_get_notify_vmexit,
-                                   kvm_arch_set_notify_vmexit);
-    object_class_property_set_description(oc, "notify-vmexit",
-                                          "Enable notify VM exit");
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = "notify-vmexit",
+        .description = "Enable notify VM exit",
+        .qapi_type = &NotifyVmexitOption_type_info,
+        .get = kvm_arch_get_notify_vmexit,
+        .set = kvm_arch_set_notify_vmexit,
+    ));
 
     object_class_property_add(oc, "notify-window", "uint32",
                               kvm_arch_get_notify_window,
@@ -7124,13 +7127,14 @@ void kvm_arch_accel_class_init(ObjectClass *oc)
     object_class_property_set_description(oc, "xen-evtchn-max-pirq",
                                           "Maximum number of Xen PIRQs");
 
-    object_class_property_add_enum(oc, "honor-guest-pat", "OnOffAuto",
-                                   &OnOffAuto_lookup,
-                                   kvm_arch_get_honor_guest_pat,
-                                   kvm_arch_set_honor_guest_pat);
-    object_class_property_set_description(oc, "honor-guest-pat",
-                                          "Disable KVM quirk that ignores guest PAT "
-                                          "memory type settings (default: auto)");
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = "honor-guest-pat",
+        .description = "Disable KVM quirk that ignores guest PAT "
+                       "memory type settings (default: auto)",
+        .qapi_type = &OnOffAuto_type_info,
+        .get = kvm_arch_get_honor_guest_pat,
+        .set = kvm_arch_set_honor_guest_pat,
+    ));
 }
 
 void kvm_set_max_apic_id(uint32_t max_apic_id)
diff --git a/ui/dbus.c b/ui/dbus.c
index 794b65c4ada..a9cc0c48ac7 100644
--- a/ui/dbus.c
+++ b/ui/dbus.c
@@ -37,6 +37,7 @@
 #include "qemu/audio.h"
 #include "audio/audio_int.h" /* FIXME: use QOM dynamic cast instead of drv->name */
 #include "qapi/error.h"
+#include "qapi/qapi-type-infos-ui.h"
 #include "trace.h"
 
 #include "dbus.h"
@@ -448,9 +449,12 @@ dbus_display_class_init(ObjectClass *oc, const void *data)
     object_class_property_add_bool(oc, "p2p", get_dbus_p2p, set_dbus_p2p);
     object_class_property_add_str(oc, "addr", get_dbus_addr, set_dbus_addr);
     object_class_property_add_str(oc, "audiodev", get_audiodev, set_audiodev);
-    object_class_property_add_enum(oc, "gl-mode",
-                                   "DisplayGLMode", &DisplayGLMode_lookup,
-                                   get_gl_mode, set_gl_mode);
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = "gl-mode",
+        .qapi_type = &DisplayGLMode_type_info,
+        .get = get_gl_mode,
+        .set = set_gl_mode,
+    ));
 }
 
 #define TYPE_CHARDEV_VC "chardev-vc"
diff --git a/ui/input-linux.c b/ui/input-linux.c
index 74bc8511428..5014a306e7d 100644
--- a/ui/input-linux.c
+++ b/ui/input-linux.c
@@ -6,6 +6,7 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
+#include "qapi/qapi-type-infos-common.h"
 #include "qemu/config-file.h"
 #include "qemu/main-loop.h"
 #include "qemu/module.h"
@@ -507,10 +508,12 @@ static void input_linux_class_init(ObjectClass *oc, const void *data)
     object_class_property_add_bool(oc, "repeat",
                                    input_linux_get_repeat,
                                    input_linux_set_repeat);
-    object_class_property_add_enum(oc, "grab-toggle", "GrabToggleKeys",
-                                   &GrabToggleKeys_lookup,
-                                   input_linux_get_grab_toggle,
-                                   input_linux_set_grab_toggle);
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = "grab-toggle",
+        .qapi_type = &GrabToggleKeys_type_info,
+        .get = input_linux_get_grab_toggle,
+        .set = input_linux_set_grab_toggle,
+    ));
 }
 
 static const TypeInfo input_linux_info = {

-- 
2.54.0



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

* [PATCH 13/54] qom: remove old enum property registration API
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (11 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 12/54] qom: convert enum properties to QAPI-aware registration Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 14/54] qom: convert struct properties to QAPI-aware registration Marc-André Lureau
                   ` (41 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Now that all callers use object_class_property_add_qapi_enum(), remove
the legacy object_property_add_enum() and object_class_property_add_enum()
functions along with their EnumProperty struct and property_get_enum /
property_set_enum helpers.

Simplify object_property_get_enum() to assert on qapi_type rather than
falling back to the old EnumProperty opaque data.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/qom/object.h | 31 ++-----------------
 qom/object.c         | 84 ++--------------------------------------------------
 2 files changed, 5 insertions(+), 110 deletions(-)

diff --git a/include/qom/object.h b/include/qom/object.h
index 0eaa02688b0..14238e4b844 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1577,12 +1577,12 @@ char *object_get_canonical_path(const Object *obj);
  *   because it was ambiguous, or %NULL. Set to %false on success.
  *
  * There are two types of supported paths--absolute paths and partial paths.
- * 
+ *
  * Absolute paths are derived from the root object and can follow child<> or
  * link<> properties.  Since they can follow link<> properties, they can be
  * arbitrarily long.  Absolute paths look like absolute filenames and are
  * prefixed with a leading slash.
- * 
+ *
  * Partial paths look like relative filenames.  They do not begin with a
  * prefix.  The matching rules for partial paths are subtle but designed to make
  * specifying objects easy.  At each level of the composition tree, the partial
@@ -1797,33 +1797,6 @@ ObjectProperty *object_class_property_add_bool(ObjectClass *klass,
                                     bool (*get)(Object *, Error **),
                                     void (*set)(Object *, bool, Error **));
 
-/**
- * object_property_add_enum:
- * @obj: the object to add a property to
- * @name: the name of the property
- * @typename: the name of the enum data type
- * @lookup: enum value namelookup table
- * @get: the getter or %NULL if the property is write-only.
- * @set: the setter or %NULL if the property is read-only
- *
- * Add an enum property using getters/setters.  This function will add a
- * property of type '@typename'.
- *
- * Returns: The newly added property on success, or %NULL on failure.
- */
-ObjectProperty *object_property_add_enum(Object *obj, const char *name,
-                              const char *typename,
-                              const QEnumLookup *lookup,
-                              int (*get)(Object *, Error **),
-                              void (*set)(Object *, int, Error **));
-
-ObjectProperty *object_class_property_add_enum(ObjectClass *klass,
-                                    const char *name,
-                                    const char *typename,
-                                    const QEnumLookup *lookup,
-                                    int (*get)(Object *, Error **),
-                                    void (*set)(Object *, int, Error **));
-
 /**
  * struct QapiEnumProp - Descriptor for a QOM property backed by a QAPI enum type
  *
diff --git a/qom/object.c b/qom/object.c
index 164907289a6..48d7a88ee43 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1055,7 +1055,7 @@ static void object_class_foreach_tramp(gpointer key, gpointer value,
         return;
     }
 
-    if (data->implements_type && 
+    if (data->implements_type &&
         !object_class_dynamic_cast(k, data->implements_type)) {
         return;
     }
@@ -1603,12 +1603,6 @@ uint64_t object_property_get_uint(Object *obj, const char *name,
     return retval;
 }
 
-typedef struct EnumProperty {
-    const QEnumLookup *lookup;
-    int (*get)(Object *, Error **);
-    void (*set)(Object *, int, Error **);
-} EnumProperty;
-
 int object_property_get_enum(Object *obj, const char *name,
                              const char *typename, Error **errp)
 {
@@ -1632,12 +1626,8 @@ int object_property_get_enum(Object *obj, const char *name,
         return -1;
     }
 
-    if (prop->qapi_type) {
-        ret = qapi_enum_parse(prop->qapi_type->lookup, str, -1, errp);
-    } else {
-        EnumProperty *enumprop = prop->opaque;
-        ret = qapi_enum_parse(enumprop->lookup, str, -1, errp);
-    }
+    assert(prop->qapi_type);
+    ret = qapi_enum_parse(prop->qapi_type->lookup, str, -1, errp);
     g_free(str);
 
     return ret;
@@ -2362,74 +2352,6 @@ object_class_property_add_bool(ObjectClass *klass, const char *name,
                                      prop);
 }
 
-static void property_get_enum(Object *obj, Visitor *v, const char *name,
-                              void *opaque, Error **errp)
-{
-    EnumProperty *prop = opaque;
-    int value;
-    Error *err = NULL;
-
-    value = prop->get(obj, &err);
-    if (err) {
-        error_propagate(errp, err);
-        return;
-    }
-
-    visit_type_enum(v, name, &value, prop->lookup, errp);
-}
-
-static void property_set_enum(Object *obj, Visitor *v, const char *name,
-                              void *opaque, Error **errp)
-{
-    EnumProperty *prop = opaque;
-    int value;
-
-    if (!visit_type_enum(v, name, &value, prop->lookup, errp)) {
-        return;
-    }
-    prop->set(obj, value, errp);
-}
-
-ObjectProperty *
-object_property_add_enum(Object *obj, const char *name,
-                         const char *typename,
-                         const QEnumLookup *lookup,
-                         int (*get)(Object *, Error **),
-                         void (*set)(Object *, int, Error **))
-{
-    EnumProperty *prop = g_malloc(sizeof(*prop));
-
-    prop->lookup = lookup;
-    prop->get = get;
-    prop->set = set;
-
-    return object_property_add(obj, name, typename,
-                               get ? property_get_enum : NULL,
-                               set ? property_set_enum : NULL,
-                               property_release_data,
-                               prop);
-}
-
-ObjectProperty *
-object_class_property_add_enum(ObjectClass *klass, const char *name,
-                                    const char *typename,
-                                    const QEnumLookup *lookup,
-                                    int (*get)(Object *, Error **),
-                                    void (*set)(Object *, int, Error **))
-{
-    EnumProperty *prop = g_malloc(sizeof(*prop));
-
-    prop->lookup = lookup;
-    prop->get = get;
-    prop->set = set;
-
-    return object_class_property_add(klass, name, typename,
-                                     get ? property_get_enum : NULL,
-                                     set ? property_set_enum : NULL,
-                                     NULL,
-                                     prop);
-}
-
 static void get_qapi_enum(Object *obj, Visitor *v, const char *name,
                           void *opaque, Error **errp)
 {

-- 
2.54.0



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

* [PATCH 14/54] qom: convert struct properties to QAPI-aware registration
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (12 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 13/54] qom: remove old enum property registration API Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 15/54] " Marc-André Lureau
                   ` (40 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Convert all callers of object_property_add() and
object_class_property_add() that register struct-typed properties with
QAPI visitor-based getters/setters to use object_property_add_qapi() and
object_class_property_add_qapi() instead.

This replaces the manual string type name with a reference to the
generated QAPITypeInfo constant, enabling QMP introspection to report
accurate QAPI type information for struct properties. Existing
getters/setters are preserved unchanged.

The cxl-fmw property type is corrected from "CXLFixedMemoryWindow"
(not a real QAPI type) to "CXLFixedMemoryWindowOptions".

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 authz/list.c              |  2 +-
 chardev/char-socket.c     |  3 ++-
 hw/core/machine.c         | 11 +++++++----
 hw/cxl/cxl-host.c         |  4 +++-
 hw/remote/vfio-user-obj.c |  5 +++--
 hw/vfio-user/pci.c        |  5 +++--
 target/i386/cpu.c         | 11 ++++++++---
 target/i386/kvm/tdx.c     |  4 +++-
 target/s390x/cpu-system.c |  4 +++-
 9 files changed, 33 insertions(+), 16 deletions(-)

diff --git a/authz/list.c b/authz/list.c
index 363b2ee12c9..ed3d346004c 100644
--- a/authz/list.c
+++ b/authz/list.c
@@ -128,7 +128,7 @@ qauthz_list_class_init(ObjectClass *oc, const void *data)
         .set = qauthz_list_prop_set_policy,
     ));
 
-    object_class_property_add(oc, "rules", "QAuthZListRule",
+    object_class_property_add_qapi(oc, "rules", &QAuthZListRule_type_info,
                               qauthz_list_prop_get_rules,
                               qauthz_list_prop_set_rules,
                               NULL, NULL);
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index e064b105c50..5268e037872 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -31,6 +31,7 @@
 #include "qemu/option.h"
 #include "qapi/error.h"
 #include "qapi/clone-visitor.h"
+#include "qapi/qapi-type-infos-sockets.h"
 #include "qapi/qapi-visit-sockets.h"
 #include "qemu/yank.h"
 #include "trace.h"
@@ -1569,7 +1570,7 @@ static void char_socket_class_init(ObjectClass *oc, const void *data)
     cc->chr_listener_cleanup = tcp_chr_listener_cleanup;
     cc->chr_get_filename = tcp_chr_get_filename;
 
-    object_class_property_add(oc, "addr", "SocketAddress",
+    object_class_property_add_qapi(oc, "addr", &SocketAddress_type_info,
                               char_socket_get_addr, NULL,
                               NULL, NULL);
 
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 1b661fd36ae..1dd5375caea 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -18,6 +18,7 @@
 #include "hw/core/loader.h"
 #include "qemu/error-report.h"
 #include "qapi/error.h"
+#include "qapi/qapi-type-infos-machine.h"
 #include "qapi/qapi-visit-machine.h"
 #include "qapi/qapi-commands-machine.h"
 #include "qemu/madvise.h"
@@ -1094,19 +1095,20 @@ static void machine_class_init(ObjectClass *oc, const void *data)
     object_class_property_set_description(oc, "dumpdtb",
         "Dump current dtb to a file and quit");
 
-    object_class_property_add(oc, "boot", "BootConfiguration",
+    object_class_property_add_qapi(oc, "boot", &BootConfiguration_type_info,
         machine_get_boot, machine_set_boot,
         NULL, NULL);
     object_class_property_set_description(oc, "boot",
         "Boot configuration");
 
-    object_class_property_add(oc, "smp", "SMPConfiguration",
+    object_class_property_add_qapi(oc, "smp", &SMPConfiguration_type_info,
         machine_get_smp, machine_set_smp,
         NULL, NULL);
     object_class_property_set_description(oc, "smp",
         "CPU topology");
 
-    object_class_property_add(oc, "smp-cache", "SmpCachePropertiesWrapper",
+    object_class_property_add_qapi(oc, "smp-cache",
+        &SmpCachePropertiesWrapper_type_info,
         machine_get_smp_cache, machine_set_smp_cache, NULL, NULL);
     object_class_property_set_description(oc, "smp-cache",
         "Cache properties list for SMP machine");
@@ -1188,7 +1190,8 @@ static void machine_class_init(ObjectClass *oc, const void *data)
                                           "Set RAM backend"
                                           "Valid value is ID of hostmem based backend");
 
-    object_class_property_add(oc, "memory", "MemorySizeConfiguration",
+    object_class_property_add_qapi(oc, "memory",
+        &MemorySizeConfiguration_type_info,
         machine_get_mem, machine_set_mem,
         NULL, NULL);
     object_class_property_set_description(oc, "memory",
diff --git a/hw/cxl/cxl-host.c b/hw/cxl/cxl-host.c
index a94b893e999..87067b94b34 100644
--- a/hw/cxl/cxl-host.c
+++ b/hw/cxl/cxl-host.c
@@ -13,6 +13,7 @@
 #include "system/qtest.h"
 #include "hw/core/boards.h"
 
+#include "qapi/qapi-type-infos-machine.h"
 #include "qapi/qapi-visit-machine.h"
 #include "hw/cxl/cxl.h"
 #include "hw/cxl/cxl_host.h"
@@ -350,7 +351,8 @@ void cxl_machine_init(Object *obj, CXLState *state)
                                     "Set on/off to enable/disable "
                                     "CXL instantiation");
 
-    object_property_add(obj, "cxl-fmw", "CXLFixedMemoryWindow",
+    object_property_add_qapi(obj, "cxl-fmw",
+                        &CXLFixedMemoryWindowOptions_type_info,
                         machine_get_cfmw, machine_set_cfmw,
                         NULL, state);
     object_property_set_description(obj, "cxl-fmw",
diff --git a/hw/remote/vfio-user-obj.c b/hw/remote/vfio-user-obj.c
index 12ecdab6dea..d0d0a7be7d2 100644
--- a/hw/remote/vfio-user-obj.c
+++ b/hw/remote/vfio-user-obj.c
@@ -47,6 +47,7 @@
 #include "hw/core/boards.h"
 #include "hw/remote/machine.h"
 #include "qapi/error.h"
+#include "qapi/qapi-type-infos-sockets.h"
 #include "qapi/qapi-visit-sockets.h"
 #include "qapi/qapi-events-misc.h"
 #include "qemu/notify.h"
@@ -928,8 +929,8 @@ static void vfu_object_class_init(ObjectClass *klass, const void *data)
 
     k->nr_devs = 0;
 
-    object_class_property_add(klass, "socket", "SocketAddress", NULL,
-                              vfu_object_set_socket, NULL, NULL);
+    object_class_property_add_qapi(klass, "socket", &SocketAddress_type_info,
+                              NULL, vfu_object_set_socket, NULL, NULL);
     object_class_property_set_description(klass, "socket",
                                           "SocketAddress "
                                           "(ex: type=unix,path=/tmp/sock). "
diff --git a/hw/vfio-user/pci.c b/hw/vfio-user/pci.c
index facc79727ac..a4427ed0353 100644
--- a/hw/vfio-user/pci.c
+++ b/hw/vfio-user/pci.c
@@ -8,6 +8,7 @@
 
 #include "qemu/osdep.h"
 #include <sys/ioctl.h>
+#include "qapi/qapi-type-infos-sockets.h"
 #include "qapi-visit-sockets.h"
 #include "qemu/error-report.h"
 
@@ -468,8 +469,8 @@ static void vfio_user_pci_class_init(ObjectClass *klass, const void *data)
     device_class_set_legacy_reset(dc, vfio_user_pci_reset);
     device_class_set_props(dc, vfio_user_pci_properties);
 
-    object_class_property_add(klass, "socket", "SocketAddress", NULL,
-                              vfio_user_pci_set_socket, NULL, NULL);
+    object_class_property_add_qapi(klass, "socket", &SocketAddress_type_info,
+                              NULL, vfio_user_pci_set_socket, NULL, NULL);
     object_class_property_set_description(klass, "socket",
                                           "SocketAddress (UNIX sockets only)");
 
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 97c66c22262..a98bcc218ba 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -34,6 +34,8 @@
 #include "sev.h"
 #include "qapi/error.h"
 #include "qemu/error-report.h"
+#include "qapi/qapi-type-infos-machine.h"
+#include "qapi/qapi-type-infos-run-state.h"
 #include "qapi/qapi-visit-machine.h"
 #include "standard-headers/asm-x86/kvm_para.h"
 #include "hw/core/qdev-properties.h"
@@ -10506,10 +10508,12 @@ static void x86_cpu_initfn(Object *obj)
 
     x86_cpu_init_default_topo(cpu);
 
-    object_property_add(obj, "feature-words", "X86CPUFeatureWordInfo",
+    object_property_add_qapi(obj, "feature-words",
+                        &X86CPUFeatureWordInfo_type_info,
                         x86_cpu_get_feature_words,
                         NULL, NULL, (void *)env->features);
-    object_property_add(obj, "filtered-features", "X86CPUFeatureWordInfo",
+    object_property_add_qapi(obj, "filtered-features",
+                        &X86CPUFeatureWordInfo_type_info,
                         x86_cpu_get_feature_words,
                         NULL, NULL, (void *)cpu->filtered_features);
 
@@ -10969,7 +10973,8 @@ static void x86_cpu_common_class_init(ObjectClass *oc, const void *data)
                               NULL, NULL);
 
 #if !defined(CONFIG_USER_ONLY)
-    object_class_property_add(oc, "crash-information", "GuestPanicInformation",
+    object_class_property_add_qapi(oc, "crash-information",
+                              &GuestPanicInformation_type_info,
                               x86_cpu_get_crash_info_qom, NULL, NULL, NULL);
 #endif
 
diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c
index 4714c9d514e..3bdecbe9c5d 100644
--- a/target/i386/kvm/tdx.c
+++ b/target/i386/kvm/tdx.c
@@ -14,6 +14,7 @@
 #include "qemu/base64.h"
 #include "qemu/mmap-alloc.h"
 #include "qapi/error.h"
+#include "qapi/qapi-type-infos-sockets.h"
 #include "qapi/qapi-visit-sockets.h"
 #include "qom/object_interfaces.h"
 #include "crypto/hash.h"
@@ -1572,7 +1573,8 @@ static void tdx_guest_init(Object *obj)
                             tdx_guest_get_mrownerconfig,
                             tdx_guest_set_mrownerconfig);
 
-    object_property_add(obj, "quote-generation-socket", "SocketAddress",
+    object_property_add_qapi(obj, "quote-generation-socket",
+                            &SocketAddress_type_info,
                             tdx_guest_get_qgs,
                             tdx_guest_set_qgs,
                             NULL, NULL);
diff --git a/target/s390x/cpu-system.c b/target/s390x/cpu-system.c
index 285f5999661..349f2198c93 100644
--- a/target/s390x/cpu-system.c
+++ b/target/s390x/cpu-system.c
@@ -30,6 +30,7 @@
 #include "system/reset.h"
 #include "qemu/timer.h"
 #include "trace.h"
+#include "qapi/qapi-type-infos-run-state.h"
 #include "qapi/qapi-visit-run-state.h"
 #include "system/hw_accel.h"
 
@@ -130,7 +131,8 @@ void s390_cpu_system_init(Object *obj)
     S390CPU *cpu = S390_CPU(obj);
 
     cs->start_powered_off = true;
-    object_property_add(obj, "crash-information", "GuestPanicInformation",
+    object_property_add_qapi(obj, "crash-information",
+                        &GuestPanicInformation_type_info,
                         s390_cpu_get_crash_info_qom, NULL, NULL, NULL);
     cpu->env.tod_timer =
         timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_tod_timer, cpu);

-- 
2.54.0



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

* [PATCH 15/54] qom: convert struct properties to QAPI-aware registration
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (13 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 14/54] qom: convert struct properties to QAPI-aware registration Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 16/54] x86: convert OnOffAuto " Marc-André Lureau
                   ` (39 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Convert all callers of object_property_add() and
object_class_property_add() that register struct-typed properties with
QAPI visitor-based getters/setters to use object_property_add_qapi() and
object_class_property_add_qapi() instead.

This replaces the manual string type name with a reference to the
generated QAPITypeInfo constant, enabling QMP introspection to report
accurate QAPI type information for struct properties. Existing
getters/setters are preserved unchanged.

The cxl-fmw property type is corrected from "CXLFixedMemoryWindow"
(not a real QAPI type) to "CXLFixedMemoryWindowOptions".

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 block/throttle-groups.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/block/throttle-groups.c b/block/throttle-groups.c
index 4b1b1944c20..b161576432a 100644
--- a/block/throttle-groups.c
+++ b/block/throttle-groups.c
@@ -31,6 +31,7 @@
 #include "qemu/thread.h"
 #include "system/qtest.h"
 #include "qapi/error.h"
+#include "qapi/qapi-type-infos-block-core.h"
 #include "qapi/qapi-visit-block-core.h"
 #include "qom/object.h"
 #include "qom/object_interfaces.h"
@@ -985,8 +986,8 @@ static void throttle_group_obj_class_init(ObjectClass *klass,
     }
 
     /* ThrottleLimits */
-    object_class_property_add(klass,
-                              "limits", "ThrottleLimits",
+    object_class_property_add_qapi(klass,
+                              "limits", &ThrottleLimits_type_info,
                               throttle_group_get_limits,
                               throttle_group_set_limits,
                               NULL, NULL);

-- 
2.54.0



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

* [PATCH 16/54] x86: convert OnOffAuto properties to QAPI-aware registration
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (14 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 15/54] " Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 17/54] microvm: " Marc-André Lureau
                   ` (38 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Convert the smm, acpi, pit, and pic OnOffAuto properties from
manual visitor-based callbacks to property_add_qapi_enum().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/i386/x86.c | 110 +++++++++++++++++++++++++---------------------------------
 1 file changed, 48 insertions(+), 62 deletions(-)

diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 01872cba073..b76926a00bd 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -24,7 +24,7 @@
 #include "qemu/error-report.h"
 #include "qemu/units.h"
 #include "qapi/error.h"
-#include "qapi/qapi-visit-common.h"
+#include "qapi/qapi-type-infos-common.h"
 #include "qapi/qapi-visit-machine.h"
 #include "qapi/visitor.h"
 #include "system/qtest.h"
@@ -188,21 +188,16 @@ bool x86_machine_is_smm_enabled(const X86MachineState *x86ms)
     return false;
 }
 
-static void x86_machine_get_smm(Object *obj, Visitor *v, const char *name,
-                               void *opaque, Error **errp)
+static int x86_machine_get_smm(Object *obj, Error **errp)
 {
     X86MachineState *x86ms = X86_MACHINE(obj);
-    OnOffAuto smm = x86ms->smm;
-
-    visit_type_OnOffAuto(v, name, &smm, errp);
+    return x86ms->smm;
 }
 
-static void x86_machine_set_smm(Object *obj, Visitor *v, const char *name,
-                               void *opaque, Error **errp)
+static void x86_machine_set_smm(Object *obj, int value, Error **errp)
 {
     X86MachineState *x86ms = X86_MACHINE(obj);
-
-    visit_type_OnOffAuto(v, name, &x86ms->smm, errp);
+    x86ms->smm = value;
 }
 
 bool x86_machine_is_acpi_enabled(const X86MachineState *x86ms)
@@ -213,55 +208,40 @@ bool x86_machine_is_acpi_enabled(const X86MachineState *x86ms)
     return true;
 }
 
-static void x86_machine_get_acpi(Object *obj, Visitor *v, const char *name,
-                                 void *opaque, Error **errp)
+static int x86_machine_get_acpi(Object *obj, Error **errp)
 {
     X86MachineState *x86ms = X86_MACHINE(obj);
-    OnOffAuto acpi = x86ms->acpi;
-
-    visit_type_OnOffAuto(v, name, &acpi, errp);
+    return x86ms->acpi;
 }
 
-static void x86_machine_set_acpi(Object *obj, Visitor *v, const char *name,
-                                 void *opaque, Error **errp)
+static void x86_machine_set_acpi(Object *obj, int value, Error **errp)
 {
     X86MachineState *x86ms = X86_MACHINE(obj);
-
-    visit_type_OnOffAuto(v, name, &x86ms->acpi, errp);
+    x86ms->acpi = value;
 }
 
-static void x86_machine_get_pit(Object *obj, Visitor *v, const char *name,
-                                    void *opaque, Error **errp)
+static int x86_machine_get_pit(Object *obj, Error **errp)
 {
     X86MachineState *x86ms = X86_MACHINE(obj);
-    OnOffAuto pit = x86ms->pit;
-
-    visit_type_OnOffAuto(v, name, &pit, errp);
+    return x86ms->pit;
 }
 
-static void x86_machine_set_pit(Object *obj, Visitor *v, const char *name,
-                                    void *opaque, Error **errp)
+static void x86_machine_set_pit(Object *obj, int value, Error **errp)
 {
     X86MachineState *x86ms = X86_MACHINE(obj);
-
-    visit_type_OnOffAuto(v, name, &x86ms->pit, errp);
+    x86ms->pit = value;
 }
 
-static void x86_machine_get_pic(Object *obj, Visitor *v, const char *name,
-                                void *opaque, Error **errp)
+static int x86_machine_get_pic(Object *obj, Error **errp)
 {
     X86MachineState *x86ms = X86_MACHINE(obj);
-    OnOffAuto pic = x86ms->pic;
-
-    visit_type_OnOffAuto(v, name, &pic, errp);
+    return x86ms->pic;
 }
 
-static void x86_machine_set_pic(Object *obj, Visitor *v, const char *name,
-                                void *opaque, Error **errp)
+static void x86_machine_set_pic(Object *obj, int value, Error **errp)
 {
     X86MachineState *x86ms = X86_MACHINE(obj);
-
-    visit_type_OnOffAuto(v, name, &x86ms->pic, errp);
+    x86ms->pic = value;
 }
 
 static char *x86_machine_get_oem_id(Object *obj, Error **errp)
@@ -383,31 +363,37 @@ static void x86_machine_class_init(ObjectClass *oc, const void *data)
     mc->kvm_type = x86_kvm_type;
     nc->nmi_monitor_handler = x86_nmi;
 
-    object_class_property_add(oc, X86_MACHINE_SMM, "OnOffAuto",
-        x86_machine_get_smm, x86_machine_set_smm,
-        NULL, NULL);
-    object_class_property_set_description(oc, X86_MACHINE_SMM,
-        "Enable SMM");
-
-    object_class_property_add(oc, X86_MACHINE_ACPI, "OnOffAuto",
-        x86_machine_get_acpi, x86_machine_set_acpi,
-        NULL, NULL);
-    object_class_property_set_description(oc, X86_MACHINE_ACPI,
-        "Enable ACPI");
-
-    object_class_property_add(oc, X86_MACHINE_PIT, "OnOffAuto",
-                              x86_machine_get_pit,
-                              x86_machine_set_pit,
-                              NULL, NULL);
-    object_class_property_set_description(oc, X86_MACHINE_PIT,
-        "Enable i8254 PIT");
-
-    object_class_property_add(oc, X86_MACHINE_PIC, "OnOffAuto",
-                              x86_machine_get_pic,
-                              x86_machine_set_pic,
-                              NULL, NULL);
-    object_class_property_set_description(oc, X86_MACHINE_PIC,
-        "Enable i8259 PIC");
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = X86_MACHINE_SMM,
+        .description = "Enable SMM",
+        .qapi_type = &OnOffAuto_type_info,
+        .get = x86_machine_get_smm,
+        .set = x86_machine_set_smm,
+    ));
+
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = X86_MACHINE_ACPI,
+        .description = "Enable ACPI",
+        .qapi_type = &OnOffAuto_type_info,
+        .get = x86_machine_get_acpi,
+        .set = x86_machine_set_acpi,
+    ));
+
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = X86_MACHINE_PIT,
+        .description = "Enable i8254 PIT",
+        .qapi_type = &OnOffAuto_type_info,
+        .get = x86_machine_get_pit,
+        .set = x86_machine_set_pit,
+    ));
+
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = X86_MACHINE_PIC,
+        .description = "Enable i8259 PIC",
+        .qapi_type = &OnOffAuto_type_info,
+        .get = x86_machine_get_pic,
+        .set = x86_machine_set_pic,
+    ));
 
     object_class_property_add_str(oc, X86_MACHINE_OEM_ID,
                                   x86_machine_get_oem_id,

-- 
2.54.0



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

* [PATCH 17/54] microvm: convert OnOffAuto properties to QAPI-aware registration
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (15 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 16/54] x86: convert OnOffAuto " Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 18/54] pc: convert OnOffAuto vmport property " Marc-André Lureau
                   ` (37 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Convert the rtc, pcie, and ioapic2 OnOffAuto properties from
manual visitor-based callbacks to property_add_qapi_enum().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/i386/microvm.c | 84 ++++++++++++++++++++++++-------------------------------
 1 file changed, 36 insertions(+), 48 deletions(-)

diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
index 5a7889f21b8..54bdde515b1 100644
--- a/hw/i386/microvm.c
+++ b/hw/i386/microvm.c
@@ -21,7 +21,7 @@
 #include "qemu/units.h"
 #include "qapi/error.h"
 #include "qapi/visitor.h"
-#include "qapi/qapi-visit-common.h"
+#include "qapi/qapi-type-infos-common.h"
 #include "system/system.h"
 #include "system/cpus.h"
 #include "system/numa.h"
@@ -519,55 +519,40 @@ static void microvm_machine_reset(MachineState *machine, ResetType type)
     }
 }
 
-static void microvm_machine_get_rtc(Object *obj, Visitor *v, const char *name,
-                                    void *opaque, Error **errp)
+static int microvm_machine_get_rtc(Object *obj, Error **errp)
 {
     MicrovmMachineState *mms = MICROVM_MACHINE(obj);
-    OnOffAuto rtc = mms->rtc;
-
-    visit_type_OnOffAuto(v, name, &rtc, errp);
+    return mms->rtc;
 }
 
-static void microvm_machine_set_rtc(Object *obj, Visitor *v, const char *name,
-                                    void *opaque, Error **errp)
+static void microvm_machine_set_rtc(Object *obj, int value, Error **errp)
 {
     MicrovmMachineState *mms = MICROVM_MACHINE(obj);
-
-    visit_type_OnOffAuto(v, name, &mms->rtc, errp);
+    mms->rtc = value;
 }
 
-static void microvm_machine_get_pcie(Object *obj, Visitor *v, const char *name,
-                                     void *opaque, Error **errp)
+static int microvm_machine_get_pcie(Object *obj, Error **errp)
 {
     MicrovmMachineState *mms = MICROVM_MACHINE(obj);
-    OnOffAuto pcie = mms->pcie;
-
-    visit_type_OnOffAuto(v, name, &pcie, errp);
+    return mms->pcie;
 }
 
-static void microvm_machine_set_pcie(Object *obj, Visitor *v, const char *name,
-                                     void *opaque, Error **errp)
+static void microvm_machine_set_pcie(Object *obj, int value, Error **errp)
 {
     MicrovmMachineState *mms = MICROVM_MACHINE(obj);
-
-    visit_type_OnOffAuto(v, name, &mms->pcie, errp);
+    mms->pcie = value;
 }
 
-static void microvm_machine_get_ioapic2(Object *obj, Visitor *v, const char *name,
-                                        void *opaque, Error **errp)
+static int microvm_machine_get_ioapic2(Object *obj, Error **errp)
 {
     MicrovmMachineState *mms = MICROVM_MACHINE(obj);
-    OnOffAuto ioapic2 = mms->ioapic2;
-
-    visit_type_OnOffAuto(v, name, &ioapic2, errp);
+    return mms->ioapic2;
 }
 
-static void microvm_machine_set_ioapic2(Object *obj, Visitor *v, const char *name,
-                                        void *opaque, Error **errp)
+static void microvm_machine_set_ioapic2(Object *obj, int value, Error **errp)
 {
     MicrovmMachineState *mms = MICROVM_MACHINE(obj);
-
-    visit_type_OnOffAuto(v, name, &mms->ioapic2, errp);
+    mms->ioapic2 = value;
 }
 
 static bool microvm_machine_get_isa_serial(Object *obj, Error **errp)
@@ -673,26 +658,29 @@ static void microvm_class_init(ObjectClass *oc, const void *data)
     hc->unplug_request = microvm_device_unplug_request_cb;
     hc->unplug = microvm_device_unplug_cb;
 
-    object_class_property_add(oc, MICROVM_MACHINE_RTC, "OnOffAuto",
-                              microvm_machine_get_rtc,
-                              microvm_machine_set_rtc,
-                              NULL, NULL);
-    object_class_property_set_description(oc, MICROVM_MACHINE_RTC,
-        "Enable MC146818 RTC");
-
-    object_class_property_add(oc, MICROVM_MACHINE_PCIE, "OnOffAuto",
-                              microvm_machine_get_pcie,
-                              microvm_machine_set_pcie,
-                              NULL, NULL);
-    object_class_property_set_description(oc, MICROVM_MACHINE_PCIE,
-        "Enable PCIe");
-
-    object_class_property_add(oc, MICROVM_MACHINE_IOAPIC2, "OnOffAuto",
-                              microvm_machine_get_ioapic2,
-                              microvm_machine_set_ioapic2,
-                              NULL, NULL);
-    object_class_property_set_description(oc, MICROVM_MACHINE_IOAPIC2,
-        "Enable second IO-APIC");
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = MICROVM_MACHINE_RTC,
+        .description = "Enable MC146818 RTC",
+        .qapi_type = &OnOffAuto_type_info,
+        .get = microvm_machine_get_rtc,
+        .set = microvm_machine_set_rtc,
+    ));
+
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = MICROVM_MACHINE_PCIE,
+        .description = "Enable PCIe",
+        .qapi_type = &OnOffAuto_type_info,
+        .get = microvm_machine_get_pcie,
+        .set = microvm_machine_set_pcie,
+    ));
+
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = MICROVM_MACHINE_IOAPIC2,
+        .description = "Enable second IO-APIC",
+        .qapi_type = &OnOffAuto_type_info,
+        .get = microvm_machine_get_ioapic2,
+        .set = microvm_machine_set_ioapic2,
+    ));
 
     object_class_property_add_bool(oc, MICROVM_MACHINE_ISA_SERIAL,
                                    microvm_machine_get_isa_serial,

-- 
2.54.0



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

* [PATCH 18/54] pc: convert OnOffAuto vmport property to QAPI-aware registration
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (16 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 17/54] microvm: " Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 19/54] arm/virt: convert OnOffAuto acpi " Marc-André Lureau
                   ` (36 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Convert the vmport OnOffAuto property from manual visitor-based
callbacks to property_add_qapi_enum().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/i386/pc.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 2ecad3c503f..6a4fe126bc0 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -46,6 +46,7 @@
 #include "kvm/kvm_i386.h"
 #include "kvm/tdx.h"
 #include "hw/xen/xen.h"
+#include "qapi/qapi-type-infos-common.h"
 #include "qobject/qlist.h"
 #include "qemu/error-report.h"
 #include "hw/acpi/acpi.h"
@@ -1379,21 +1380,16 @@ static HotplugHandler *pc_get_hotplug_handler(MachineState *machine,
     return NULL;
 }
 
-static void pc_machine_get_vmport(Object *obj, Visitor *v, const char *name,
-                                  void *opaque, Error **errp)
+static int pc_machine_get_vmport(Object *obj, Error **errp)
 {
     PCMachineState *pcms = PC_MACHINE(obj);
-    OnOffAuto vmport = pcms->vmport;
-
-    visit_type_OnOffAuto(v, name, &vmport, errp);
+    return pcms->vmport;
 }
 
-static void pc_machine_set_vmport(Object *obj, Visitor *v, const char *name,
-                                  void *opaque, Error **errp)
+static void pc_machine_set_vmport(Object *obj, int value, Error **errp)
 {
     PCMachineState *pcms = PC_MACHINE(obj);
-
-    visit_type_OnOffAuto(v, name, &pcms->vmport, errp);
+    pcms->vmport = value;
 }
 
 static bool pc_machine_get_fd_bootchk(Object *obj, Error **errp)
@@ -1681,11 +1677,13 @@ static void pc_machine_class_init(ObjectClass *oc, const void *data)
     object_class_property_set_description(oc, PC_MACHINE_MAX_RAM_BELOW_4G,
         "Maximum ram below the 4G boundary (32bit boundary)");
 
-    object_class_property_add(oc, PC_MACHINE_VMPORT, "OnOffAuto",
-        pc_machine_get_vmport, pc_machine_set_vmport,
-        NULL, NULL);
-    object_class_property_set_description(oc, PC_MACHINE_VMPORT,
-        "Enable vmport (pc & q35)");
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = PC_MACHINE_VMPORT,
+        .description = "Enable vmport (pc & q35)",
+        .qapi_type = &OnOffAuto_type_info,
+        .get = pc_machine_get_vmport,
+        .set = pc_machine_set_vmport,
+    ));
 
     object_class_property_add_bool(oc, PC_MACHINE_SMBUS,
         pc_machine_get_smbus, pc_machine_set_smbus);

-- 
2.54.0



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

* [PATCH 19/54] arm/virt: convert OnOffAuto acpi property to QAPI-aware registration
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (17 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 18/54] pc: convert OnOffAuto vmport property " Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 20/54] riscv/virt: convert OnOffAuto properties " Marc-André Lureau
                   ` (35 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Convert the acpi OnOffAuto property from manual visitor-based
callbacks to property_add_qapi_enum().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/arm/virt.c | 27 ++++++++++++---------------
 1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index fe19030886b..e4c75cb1bae 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -73,7 +73,7 @@
 #include "whpx_arm.h"
 #include "hw/firmware/smbios.h"
 #include "qapi/visitor.h"
-#include "qapi/qapi-visit-common.h"
+#include "qapi/qapi-type-infos-common.h"
 #include "qobject/qlist.h"
 #include "standard-headers/linux/input.h"
 #include "hw/arm/smmuv3.h"
@@ -3267,21 +3267,16 @@ bool virt_is_acpi_enabled(const VirtMachineState *vms)
     return true;
 }
 
-static void virt_get_acpi(Object *obj, Visitor *v, const char *name,
-                          void *opaque, Error **errp)
+static int virt_get_acpi(Object *obj, Error **errp)
 {
     VirtMachineState *vms = VIRT_MACHINE(obj);
-    OnOffAuto acpi = vms->acpi;
-
-    visit_type_OnOffAuto(v, name, &acpi, errp);
+    return vms->acpi;
 }
 
-static void virt_set_acpi(Object *obj, Visitor *v, const char *name,
-                          void *opaque, Error **errp)
+static void virt_set_acpi(Object *obj, int value, Error **errp)
 {
     VirtMachineState *vms = VIRT_MACHINE(obj);
-
-    visit_type_OnOffAuto(v, name, &vms->acpi, errp);
+    vms->acpi = value;
 }
 
 static bool virt_get_ras(Object *obj, Error **errp)
@@ -3868,11 +3863,13 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data)
     mc->default_ram_id = "mach-virt.ram";
     mc->default_nic = "virtio-net-pci";
 
-    object_class_property_add(oc, "acpi", "OnOffAuto",
-        virt_get_acpi, virt_set_acpi,
-        NULL, NULL);
-    object_class_property_set_description(oc, "acpi",
-        "Enable ACPI");
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = "acpi",
+        .description = "Enable ACPI",
+        .qapi_type = &OnOffAuto_type_info,
+        .get = virt_get_acpi,
+        .set = virt_set_acpi,
+    ));
     object_class_property_add_bool(oc, "secure", virt_get_secure,
                                    virt_set_secure);
     object_class_property_set_description(oc, "secure",

-- 
2.54.0



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

* [PATCH 20/54] riscv/virt: convert OnOffAuto properties to QAPI-aware registration
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (18 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 19/54] arm/virt: convert OnOffAuto acpi " Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-13  2:04   ` Alistair Francis
  2026-05-10 13:43 ` [PATCH 21/54] loongarch/virt: " Marc-André Lureau
                   ` (34 subsequent siblings)
  54 siblings, 1 reply; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Convert the acpi and iommu-sys OnOffAuto properties from manual
visitor-based callbacks to property_add_qapi_enum().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/riscv/virt.c | 54 ++++++++++++++++++++++++------------------------------
 1 file changed, 24 insertions(+), 30 deletions(-)

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index a1c323e66df..5148044df95 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -55,7 +55,7 @@
 #include "hw/pci-host/gpex.h"
 #include "hw/display/ramfb.h"
 #include "hw/acpi/aml-build.h"
-#include "qapi/qapi-visit-common.h"
+#include "qapi/qapi-type-infos-common.h"
 #include "hw/virtio/virtio-iommu.h"
 #include "hw/uefi/var-service-api.h"
 
@@ -1832,21 +1832,16 @@ bool virt_is_iommu_sys_enabled(RISCVVirtState *s)
     return s->iommu_sys == ON_OFF_AUTO_ON;
 }
 
-static void virt_get_iommu_sys(Object *obj, Visitor *v, const char *name,
-                               void *opaque, Error **errp)
+static int virt_get_iommu_sys(Object *obj, Error **errp)
 {
     RISCVVirtState *s = RISCV_VIRT_MACHINE(obj);
-    OnOffAuto iommu_sys = s->iommu_sys;
-
-    visit_type_OnOffAuto(v, name, &iommu_sys, errp);
+    return s->iommu_sys;
 }
 
-static void virt_set_iommu_sys(Object *obj, Visitor *v, const char *name,
-                               void *opaque, Error **errp)
+static void virt_set_iommu_sys(Object *obj, int value, Error **errp)
 {
     RISCVVirtState *s = RISCV_VIRT_MACHINE(obj);
-
-    visit_type_OnOffAuto(v, name, &s->iommu_sys, errp);
+    s->iommu_sys = value;
 }
 
 bool virt_is_acpi_enabled(RISCVVirtState *s)
@@ -1854,21 +1849,16 @@ bool virt_is_acpi_enabled(RISCVVirtState *s)
     return s->acpi != ON_OFF_AUTO_OFF;
 }
 
-static void virt_get_acpi(Object *obj, Visitor *v, const char *name,
-                          void *opaque, Error **errp)
+static int virt_get_acpi(Object *obj, Error **errp)
 {
     RISCVVirtState *s = RISCV_VIRT_MACHINE(obj);
-    OnOffAuto acpi = s->acpi;
-
-    visit_type_OnOffAuto(v, name, &acpi, errp);
+    return s->acpi;
 }
 
-static void virt_set_acpi(Object *obj, Visitor *v, const char *name,
-                          void *opaque, Error **errp)
+static void virt_set_acpi(Object *obj, int value, Error **errp)
 {
     RISCVVirtState *s = RISCV_VIRT_MACHINE(obj);
-
-    visit_type_OnOffAuto(v, name, &s->acpi, errp);
+    s->acpi = value;
 }
 
 static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
@@ -1966,17 +1956,21 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data)
         object_class_property_set_description(oc, "aia-guests", str);
     }
 
-    object_class_property_add(oc, "acpi", "OnOffAuto",
-                              virt_get_acpi, virt_set_acpi,
-                              NULL, NULL);
-    object_class_property_set_description(oc, "acpi",
-                                          "Enable ACPI");
-
-    object_class_property_add(oc, "iommu-sys", "OnOffAuto",
-                              virt_get_iommu_sys, virt_set_iommu_sys,
-                              NULL, NULL);
-    object_class_property_set_description(oc, "iommu-sys",
-                                          "Enable IOMMU platform device");
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = "acpi",
+        .description = "Enable ACPI",
+        .qapi_type = &OnOffAuto_type_info,
+        .get = virt_get_acpi,
+        .set = virt_set_acpi,
+    ));
+
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = "iommu-sys",
+        .description = "Enable IOMMU platform device",
+        .qapi_type = &OnOffAuto_type_info,
+        .get = virt_get_iommu_sys,
+        .set = virt_set_iommu_sys,
+    ));
 }
 
 static const TypeInfo virt_machine_typeinfo = {

-- 
2.54.0



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

* [PATCH 21/54] loongarch/virt: convert OnOffAuto properties to QAPI-aware registration
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (19 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 20/54] riscv/virt: convert OnOffAuto properties " Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 22/54] hostmem-file: convert OnOffAuto rom property " Marc-André Lureau
                   ` (33 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Convert the acpi, v-eiointc, and dmsi OnOffAuto properties from
manual visitor-based callbacks to property_add_qapi_enum().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/loongarch/virt.c | 85 +++++++++++++++++++++++++----------------------------
 1 file changed, 40 insertions(+), 45 deletions(-)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 2fc15261309..b301398d1bd 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -36,7 +36,8 @@
 #include "target/loongarch/cpu.h"
 #include "target/loongarch/cpu-mmu.h"
 #include "hw/firmware/smbios.h"
-#include "qapi/qapi-visit-common.h"
+#include "qapi/qapi-type-infos-common.h"
+#include "qapi/visitor.h"
 #include "hw/acpi/generic_event_device.h"
 #include "hw/mem/nvdimm.h"
 #include "hw/core/platform-bus.h"
@@ -51,26 +52,21 @@
 #include "qemu/log.h"
 #include "kvm/kvm_loongarch.h"
 
-static void virt_get_dmsi(Object *obj, Visitor *v, const char *name,
-                             void *opaque, Error **errp)
+static int virt_get_dmsi(Object *obj, Error **errp)
 {
     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
-    OnOffAuto dmsi = lvms->dmsi;
-
-    visit_type_OnOffAuto(v, name, &dmsi, errp);
-
+    return lvms->dmsi;
 }
-static void virt_set_dmsi(Object *obj, Visitor *v, const char *name,
-                              void *opaque, Error **errp)
+
+static void virt_set_dmsi(Object *obj, int value, Error **errp)
 {
     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
+    lvms->dmsi = value;
 
-    visit_type_OnOffAuto(v, name, &lvms->dmsi, errp);
-
-    if (lvms->dmsi == ON_OFF_AUTO_OFF) {
+    if (value == ON_OFF_AUTO_OFF) {
         lvms->misc_feature &= ~BIT(IOCSRF_DMSI);
         lvms->misc_status &= ~BIT_ULL(IOCSRM_DMSI_EN);
-    } else if (lvms->dmsi == ON_OFF_AUTO_ON) {
+    } else if (value == ON_OFF_AUTO_ON) {
         lvms->misc_feature = BIT(IOCSRF_DMSI);
     }
 }
@@ -78,21 +74,16 @@ static void virt_set_dmsi(Object *obj, Visitor *v, const char *name,
 #define DEFAULT_HIGH_PCIE_MMIO_SIZE_GB 64
 #define DEFAULT_HIGH_PCIE_MMIO_SIZE (DEFAULT_HIGH_PCIE_MMIO_SIZE_GB * GiB)
 
-static void virt_get_veiointc(Object *obj, Visitor *v, const char *name,
-                              void *opaque, Error **errp)
+static int virt_get_veiointc(Object *obj, Error **errp)
 {
     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
-    OnOffAuto veiointc = lvms->veiointc;
-
-    visit_type_OnOffAuto(v, name, &veiointc, errp);
+    return lvms->veiointc;
 }
 
-static void virt_set_veiointc(Object *obj, Visitor *v, const char *name,
-                              void *opaque, Error **errp)
+static void virt_set_veiointc(Object *obj, int value, Error **errp)
 {
     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
-
-    visit_type_OnOffAuto(v, name, &lvms->veiointc, errp);
+    lvms->veiointc = value;
 }
 
 static bool virt_get_highmem_mmio(Object *obj, Error **errp)
@@ -1025,21 +1016,16 @@ static void virt_init(MachineState *machine)
     loongarch_load_kernel(machine, &lvms->bootinfo, phys_addr_mask);
 }
 
-static void virt_get_acpi(Object *obj, Visitor *v, const char *name,
-                          void *opaque, Error **errp)
+static int virt_get_acpi(Object *obj, Error **errp)
 {
     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
-    OnOffAuto acpi = lvms->acpi;
-
-    visit_type_OnOffAuto(v, name, &acpi, errp);
+    return lvms->acpi;
 }
 
-static void virt_set_acpi(Object *obj, Visitor *v, const char *name,
-                               void *opaque, Error **errp)
+static void virt_set_acpi(Object *obj, int value, Error **errp)
 {
     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
-
-    visit_type_OnOffAuto(v, name, &lvms->acpi, errp);
+    lvms->acpi = value;
 }
 
 static char *virt_get_oem_id(Object *obj, Error **errp)
@@ -1484,20 +1470,29 @@ static void virt_class_init(ObjectClass *oc, const void *data)
     hc->unplug_request = virt_device_unplug_request;
     hc->unplug = virt_device_unplug;
 
-    object_class_property_add(oc, "acpi", "OnOffAuto",
-        virt_get_acpi, virt_set_acpi,
-        NULL, NULL);
-    object_class_property_set_description(oc, "acpi",
-        "Enable ACPI");
-    object_class_property_add(oc, "v-eiointc", "OnOffAuto",
-        virt_get_veiointc, virt_set_veiointc,
-        NULL, NULL);
-    object_class_property_set_description(oc, "v-eiointc",
-                            "Enable Virt Extend I/O Interrupt Controller.");
-    object_class_property_add(oc, "dmsi", "OnOffAuto",
-        virt_get_dmsi, virt_set_dmsi, NULL, NULL);
-    object_class_property_set_description(oc, "dmsi",
-                            "Enable direct Message-interrupts Controller.");
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = "acpi",
+        .description = "Enable ACPI",
+        .qapi_type = &OnOffAuto_type_info,
+        .get = virt_get_acpi,
+        .set = virt_set_acpi,
+    ));
+
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = "v-eiointc",
+        .description = "Enable Virt Extend I/O Interrupt Controller.",
+        .qapi_type = &OnOffAuto_type_info,
+        .get = virt_get_veiointc,
+        .set = virt_set_veiointc,
+    ));
+
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = "dmsi",
+        .description = "Enable direct Message-interrupts Controller.",
+        .qapi_type = &OnOffAuto_type_info,
+        .get = virt_get_dmsi,
+        .set = virt_set_dmsi,
+    ));
     machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
     machine_class_allow_dynamic_sysbus_dev(mc, TYPE_UEFI_VARS_SYSBUS);
 #ifdef CONFIG_TPM

-- 
2.54.0



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

* [PATCH 22/54] hostmem-file: convert OnOffAuto rom property to QAPI-aware registration
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (20 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 21/54] loongarch/virt: " Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 23/54] sev: convert OnOffAuto legacy-vm-type " Marc-André Lureau
                   ` (32 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Convert the rom OnOffAuto property from manual visitor-based
callbacks to property_add_qapi_enum().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 backends/hostmem-file.c | 29 +++++++++++++----------------
 1 file changed, 13 insertions(+), 16 deletions(-)

diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index 8e3219c0617..52b62f71533 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -19,7 +19,7 @@
 #include "qom/object_interfaces.h"
 #include "qom/object.h"
 #include "qapi/visitor.h"
-#include "qapi/qapi-visit-common.h"
+#include "qapi/qapi-type-infos-common.h"
 
 OBJECT_DECLARE_SIMPLE_TYPE(HostMemoryBackendFile, MEMORY_BACKEND_FILE)
 
@@ -230,30 +230,24 @@ static void file_memory_backend_set_readonly(Object *obj, bool value,
     fb->readonly = value;
 }
 
-static void file_memory_backend_get_rom(Object *obj, Visitor *v,
-                                        const char *name, void *opaque,
-                                        Error **errp)
+static int file_memory_backend_get_rom(Object *obj, Error **errp)
 {
     HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(obj);
-    OnOffAuto rom = fb->rom;
-
-    visit_type_OnOffAuto(v, name, &rom, errp);
+    return fb->rom;
 }
 
-static void file_memory_backend_set_rom(Object *obj, Visitor *v,
-                                        const char *name, void *opaque,
-                                        Error **errp)
+static void file_memory_backend_set_rom(Object *obj, int value, Error **errp)
 {
     HostMemoryBackend *backend = MEMORY_BACKEND(obj);
     HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(obj);
 
     if (host_memory_backend_mr_inited(backend)) {
-        error_setg(errp, "cannot change property '%s' of %s.", name,
+        error_setg(errp, "cannot change property 'rom' of %s.",
                    object_get_typename(obj));
         return;
     }
 
-    visit_type_OnOffAuto(v, name, &fb->rom, errp);
+    fb->rom = value;
 }
 
 static void file_backend_unparent(Object *obj)
@@ -298,10 +292,13 @@ file_backend_class_init(ObjectClass *oc, const void *data)
     object_class_property_add_bool(oc, "readonly",
         file_memory_backend_get_readonly,
         file_memory_backend_set_readonly);
-    object_class_property_add(oc, "rom", "OnOffAuto",
-        file_memory_backend_get_rom, file_memory_backend_set_rom, NULL, NULL);
-    object_class_property_set_description(oc, "rom",
-        "Whether to create Read Only Memory (ROM)");
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = "rom",
+        .description = "Whether to create Read Only Memory (ROM)",
+        .qapi_type = &OnOffAuto_type_info,
+        .get = file_memory_backend_get_rom,
+        .set = file_memory_backend_set_rom,
+    ));
 }
 
 static void file_backend_instance_finalize(Object *o)

-- 
2.54.0



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

* [PATCH 23/54] sev: convert OnOffAuto legacy-vm-type property to QAPI-aware registration
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (21 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 22/54] hostmem-file: convert OnOffAuto rom property " Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 24/54] whpx: convert OnOffAuto hyperv " Marc-André Lureau
                   ` (31 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Convert the legacy-vm-type OnOffAuto property from manual
visitor-based callbacks to property_add_qapi_enum().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 target/i386/sev.c | 29 +++++++++++++----------------
 1 file changed, 13 insertions(+), 16 deletions(-)

diff --git a/target/i386/sev.c b/target/i386/sev.c
index b44b5a1c2b9..50a9bfc35d7 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -20,6 +20,7 @@
 #include <sys/ioctl.h>
 
 #include "qapi/error.h"
+#include "qapi/qapi-type-infos-common.h"
 #include "qom/object_interfaces.h"
 #include "qemu/base64.h"
 #include "qemu/module.h"
@@ -2872,23 +2873,16 @@ sev_guest_set_session_file(Object *obj, const char *value, Error **errp)
     SEV_GUEST(obj)->session_file = g_strdup(value);
 }
 
-static void sev_guest_get_legacy_vm_type(Object *obj, Visitor *v,
-                                         const char *name, void *opaque,
-                                         Error **errp)
+static int sev_guest_get_legacy_vm_type(Object *obj, Error **errp)
 {
     SevGuestState *sev_guest = SEV_GUEST(obj);
-    OnOffAuto legacy_vm_type = sev_guest->legacy_vm_type;
-
-    visit_type_OnOffAuto(v, name, &legacy_vm_type, errp);
+    return sev_guest->legacy_vm_type;
 }
 
-static void sev_guest_set_legacy_vm_type(Object *obj, Visitor *v,
-                                         const char *name, void *opaque,
-                                         Error **errp)
+static void sev_guest_set_legacy_vm_type(Object *obj, int value, Error **errp)
 {
     SevGuestState *sev_guest = SEV_GUEST(obj);
-
-    visit_type_OnOffAuto(v, name, &sev_guest->legacy_vm_type, errp);
+    sev_guest->legacy_vm_type = value;
 }
 
 static void
@@ -2914,11 +2908,14 @@ sev_guest_class_init(ObjectClass *oc, const void *data)
                                   sev_guest_set_session_file);
     object_class_property_set_description(oc, "session-file",
             "guest owners session parameters (encoded with base64)");
-    object_class_property_add(oc, "legacy-vm-type", "OnOffAuto",
-                              sev_guest_get_legacy_vm_type,
-                              sev_guest_set_legacy_vm_type, NULL, NULL);
-    object_class_property_set_description(oc, "legacy-vm-type",
-            "use legacy VM type to maintain measurement compatibility with older QEMU or kernel versions.");
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = "legacy-vm-type",
+        .description = "use legacy VM type to maintain measurement "
+                       "compatibility with older QEMU or kernel versions.",
+        .qapi_type = &OnOffAuto_type_info,
+        .get = sev_guest_get_legacy_vm_type,
+        .set = sev_guest_set_legacy_vm_type,
+    ));
 }
 
 static void

-- 
2.54.0



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

* [PATCH 24/54] whpx: convert OnOffAuto hyperv property to QAPI-aware registration
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (22 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 23/54] sev: convert OnOffAuto legacy-vm-type " Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 25/54] whpx: convert OnOffAuto arch properties " Marc-André Lureau
                   ` (30 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Convert the hyperv OnOffAuto property from manual visitor-based
callbacks to property_add_qapi_enum().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 accel/whpx/whpx-common.c | 29 ++++++++++-------------------
 1 file changed, 10 insertions(+), 19 deletions(-)

diff --git a/accel/whpx/whpx-common.c b/accel/whpx/whpx-common.c
index 247e12db812..187938c02b5 100644
--- a/accel/whpx/whpx-common.c
+++ b/accel/whpx/whpx-common.c
@@ -22,6 +22,7 @@
 #include "qemu/error-report.h"
 #include "qapi/error.h"
 #include "qapi/qapi-types-common.h"
+#include "qapi/qapi-type-infos-common.h"
 #include "qapi/qapi-visit-common.h"
 #include "migration/blocker.h"
 #include "accel/accel-cpu-target.h"
@@ -470,18 +471,11 @@ static void whpx_set_kernel_irqchip(Object *obj, Visitor *v,
     }
 }
 
-static void whpx_set_hyperv(Object *obj, Visitor *v,
-                                   const char *name, void *opaque,
-                                   Error **errp)
+static void whpx_set_hyperv(Object *obj, int value, Error **errp)
 {
     struct whpx_state *whpx = &whpx_global;
-    OnOffAuto mode;
-
-    if (!visit_type_OnOffAuto(v, name, &mode, errp)) {
-        return;
-    }
 
-    switch (mode) {
+    switch (value) {
     case ON_OFF_AUTO_ON:
         whpx->hyperv_enlightenments_allowed = true;
         whpx->hyperv_enlightenments_required = true;
@@ -497,11 +491,7 @@ static void whpx_set_hyperv(Object *obj, Visitor *v,
         whpx->hyperv_enlightenments_required = false;
         break;
     default:
-        /*
-         * The value was checked in visit_type_OnOffAuto() above. If
-         * we get here, then something is wrong in QEMU.
-         */
-        abort();
+        g_assert_not_reached();
     }
 }
 
@@ -533,11 +523,12 @@ static void whpx_accel_class_init(ObjectClass *oc, const void *data)
         NULL, NULL);
     object_class_property_set_description(oc, "kernel-irqchip",
         "Configure WHPX in-kernel irqchip");
-    object_class_property_add(oc, "hyperv", "OnOffAuto",
-        NULL, whpx_set_hyperv,
-        NULL, NULL);
-    object_class_property_set_description(oc, "hyperv",
-        "Configure Hyper-V enlightenments");
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = "hyperv",
+        .description = "Configure Hyper-V enlightenments",
+        .qapi_type = &OnOffAuto_type_info,
+        .set = whpx_set_hyperv,
+    ));
 
     whpx_arch_accel_class_init(oc);
 }

-- 
2.54.0



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

* [PATCH 25/54] whpx: convert OnOffAuto arch properties to QAPI-aware registration
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (23 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 24/54] whpx: convert OnOffAuto hyperv " Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 26/54] accel/kvm: convert OnOffSplit property " Marc-André Lureau
                   ` (29 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Convert the ignore-unknown-msr, intercept-msr-gp, and ssd OnOffAuto
properties from manual visitor-based callbacks to
property_add_qapi_enum().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 target/i386/whpx/whpx-all.c | 102 +++++++++++++++-----------------------------
 1 file changed, 34 insertions(+), 68 deletions(-)

diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c
index 9d0c391e36f..6826ac5bb18 100644
--- a/target/i386/whpx/whpx-all.c
+++ b/target/i386/whpx/whpx-all.c
@@ -30,7 +30,7 @@
 #include "qemu/error-report.h"
 #include "qapi/error.h"
 #include "qapi/qapi-types-common.h"
-#include "qapi/qapi-visit-common.h"
+#include "qapi/qapi-type-infos-common.h"
 #include "migration/blocker.h"
 #include "host-cpu.h"
 #include "accel/accel-cpu-target.h"
@@ -1853,7 +1853,7 @@ void whpx_apply_breakpoints(
     }
 }
 
-bool whpx_arch_supports_guest_debug(void) 
+bool whpx_arch_supports_guest_debug(void)
 {
     return true;
 }
@@ -1938,7 +1938,7 @@ static int whpx_handle_hyperv_guestidle(CPUState *cpu)
     return whpx_handle_halt(cpu);
 }
 
-static void whpx_vcpu_kick_out_of_hlt(CPUState *cpu) 
+static void whpx_vcpu_kick_out_of_hlt(CPUState *cpu)
 {
     WHV_REGISTER_VALUE reg;
     whpx_get_reg(cpu, WHvRegisterInternalActivityState, &reg);
@@ -2042,7 +2042,7 @@ static void whpx_vcpu_pre_run(CPUState *cpu)
                 .Vector = irq,
             };
             reg_count += 1;
-            /* 
+            /*
              * When the Hyper-V APIC is enabled, to get out of HLT we
              * either have to request an interrupt or manually get it away
              * from HLT.
@@ -2342,7 +2342,7 @@ int whpx_vcpu_run(CPUState *cpu)
             WHV_REGISTER_VALUE reg_values[3] = {0};
             WHV_REGISTER_NAME reg_names[3];
             UINT32 reg_count;
-            bool is_known_msr = 0; 
+            bool is_known_msr = 0;
             bool raises_gpf = false;
             uint64_t val;
 
@@ -2898,120 +2898,86 @@ void whpx_cpu_instance_init(CPUState *cs)
  * Partition support
  */
 
-static void whpx_set_unknown_msr(Object *obj, Visitor *v,
-                                   const char *name, void *opaque,
-                                   Error **errp)
+static void whpx_set_unknown_msr(Object *obj, int value, Error **errp)
 {
     struct whpx_state *whpx = &whpx_global;
-    OnOffAuto mode;
-
-    if (!visit_type_OnOffAuto(v, name, &mode, errp)) {
-        return;
-    }
 
-    switch (mode) {
+    switch (value) {
     case ON_OFF_AUTO_ON:
         whpx->ignore_unknown_msr = true;
         break;
-
     case ON_OFF_AUTO_OFF:
         whpx->ignore_unknown_msr = false;
         break;
-
     case ON_OFF_AUTO_AUTO:
         whpx->ignore_unknown_msr = true;
         break;
     default:
-        /*
-         * The value was checked in visit_type_OnOffAuto() above. If
-         * we get here, then something is wrong in QEMU.
-         */
-        abort();
+        g_assert_not_reached();
     }
 }
 
-static void whpx_set_intercept_msr_gp(Object *obj, Visitor *v,
-                                   const char *name, void *opaque,
-                                   Error **errp)
+static void whpx_set_intercept_msr_gp(Object *obj, int value, Error **errp)
 {
     struct whpx_state *whpx = &whpx_global;
-    OnOffAuto mode;
-
-    if (!visit_type_OnOffAuto(v, name, &mode, errp)) {
-        return;
-    }
 
-    switch (mode) {
+    switch (value) {
     case ON_OFF_AUTO_ON:
         whpx->intercept_msr_gp = true;
         break;
-
     case ON_OFF_AUTO_OFF:
         whpx->intercept_msr_gp = false;
         break;
-
     case ON_OFF_AUTO_AUTO:
         whpx->intercept_msr_gp = false;
         break;
     default:
-        /*
-         * The value was checked in visit_type_OnOffAuto() above. If
-         * we get here, then something is wrong in QEMU.
-         */
-        abort();
+        g_assert_not_reached();
     }
 }
 
-static void whpx_set_ssd(Object *obj, Visitor *v,
-                                   const char *name, void *opaque,
-                                   Error **errp)
+static void whpx_set_ssd(Object *obj, int value, Error **errp)
 {
     struct whpx_state *whpx = &whpx_global;
-    OnOffAuto mode;
-
-    if (!visit_type_OnOffAuto(v, name, &mode, errp)) {
-        return;
-    }
 
-    switch (mode) {
+    switch (value) {
     case ON_OFF_AUTO_ON:
         whpx->separate_security_domain = true;
         break;
-
     case ON_OFF_AUTO_OFF:
         whpx->separate_security_domain = false;
         break;
-
     case ON_OFF_AUTO_AUTO:
         whpx->separate_security_domain = true;
         break;
     default:
-        /*
-         * The value was checked in visit_type_OnOffAuto() above. If
-         * we get here, then something is wrong in QEMU.
-         */
-        abort();
+        g_assert_not_reached();
     }
 }
 
 
 void whpx_arch_accel_class_init(ObjectClass *oc)
 {
-    object_class_property_add(oc, "ignore-unknown-msr", "OnOffAuto",
-        NULL, whpx_set_unknown_msr,
-        NULL, NULL);
-    object_class_property_set_description(oc, "ignore-unknown-msr",
-        "Configure unknown MSR behavior");
-    object_class_property_add(oc, "intercept-msr-gp", "OnOffAuto",
-        NULL, whpx_set_intercept_msr_gp,
-        NULL, NULL);
-    object_class_property_set_description(oc, "intercept-msr-gp",
-        "Intercept #GP to log erroring MSR accesses.");
-    object_class_property_add(oc, "ssd", "OnOffAuto",
-        NULL, whpx_set_ssd,
-        NULL, NULL);
-    object_class_property_set_description(oc, "ssd",
-        "Separate security domain");
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = "ignore-unknown-msr",
+        .description = "Configure unknown MSR behavior",
+        .qapi_type = &OnOffAuto_type_info,
+        .set = whpx_set_unknown_msr,
+    ));
+
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = "intercept-msr-gp",
+        .description = "Intercept #GP to log erroring MSR accesses.",
+        .qapi_type = &OnOffAuto_type_info,
+        .set = whpx_set_intercept_msr_gp,
+    ));
+
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = "ssd",
+        .description = "Separate security domain",
+        .qapi_type = &OnOffAuto_type_info,
+        .set = whpx_set_ssd,
+    ));
 }
 
 int whpx_accel_init(AccelState *as, MachineState *ms)

-- 
2.54.0



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

* [PATCH 26/54] accel/kvm: convert OnOffSplit property to QAPI-aware registration
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (24 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 25/54] whpx: convert OnOffAuto arch properties " Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 27/54] whpx: " Marc-André Lureau
                   ` (28 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Convert the OnOffSplit property from manual visitor-based
callbacks to property_add_qapi_enum().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 accel/kvm/kvm-all.c | 26 ++++++++++----------------
 1 file changed, 10 insertions(+), 16 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 92af42503b1..94b64cde621 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -46,6 +46,7 @@
 #include "qapi/visitor.h"
 #include "qapi/qapi-types-common.h"
 #include "qapi/qapi-visit-common.h"
+#include "qapi/qapi-type-infos-common.h"
 #include "system/reset.h"
 #include "qemu/guest-random.h"
 #include "system/hw_accel.h"
@@ -4142,22 +4143,17 @@ static void kvm_set_kvm_shadow_mem(Object *obj, Visitor *v,
     s->kvm_shadow_mem = value;
 }
 
-static void kvm_set_kernel_irqchip(Object *obj, Visitor *v,
-                                   const char *name, void *opaque,
+static void kvm_set_kernel_irqchip(Object *obj, int value,
                                    Error **errp)
 {
     KVMState *s = KVM_STATE(obj);
-    OnOffSplit mode;
 
     if (s->fd != -1) {
         error_setg(errp, "Cannot set properties after the accelerator has been initialized");
         return;
     }
 
-    if (!visit_type_OnOffSplit(v, name, &mode, errp)) {
-        return;
-    }
-    switch (mode) {
+    switch (value) {
     case ON_OFF_SPLIT_ON:
         s->kernel_irqchip_allowed = true;
         s->kernel_irqchip_required = true;
@@ -4174,10 +4170,7 @@ static void kvm_set_kernel_irqchip(Object *obj, Visitor *v,
         s->kernel_irqchip_split = ON_OFF_AUTO_ON;
         break;
     default:
-        /* The value was checked in visit_type_OnOffSplit() above. If
-         * we get here, then something is wrong in QEMU.
-         */
-        abort();
+        g_assert_not_reached();
     }
 }
 
@@ -4306,11 +4299,12 @@ static void kvm_accel_class_init(ObjectClass *oc, const void *data)
     ac->allowed = &kvm_allowed;
     ac->gdbstub_supported_sstep_flags = kvm_gdbstub_sstep_flags;
 
-    object_class_property_add(oc, "kernel-irqchip", "on|off|split",
-        NULL, kvm_set_kernel_irqchip,
-        NULL, NULL);
-    object_class_property_set_description(oc, "kernel-irqchip",
-        "Configure KVM in-kernel irqchip");
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = "kernel-irqchip",
+        .qapi_type = &OnOffSplit_type_info,
+        .set = kvm_set_kernel_irqchip,
+        .description = "Configure KVM in-kernel irqchip",
+    ));
 
     object_class_property_add(oc, "kvm-shadow-mem", "int",
         kvm_get_kvm_shadow_mem, kvm_set_kvm_shadow_mem,

-- 
2.54.0



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

* [PATCH 27/54] whpx: convert OnOffSplit property to QAPI-aware registration
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (25 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 26/54] accel/kvm: convert OnOffSplit property " Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 28/54] ppc/spapr-caps: convert to QAPI-aware property registration Marc-André Lureau
                   ` (27 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Convert the OnOffSplit property from manual visitor-based
callbacks to property_add_qapi_enum().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 accel/whpx/whpx-common.c | 29 ++++++++++-------------------
 1 file changed, 10 insertions(+), 19 deletions(-)

diff --git a/accel/whpx/whpx-common.c b/accel/whpx/whpx-common.c
index 187938c02b5..5d4b405e56d 100644
--- a/accel/whpx/whpx-common.c
+++ b/accel/whpx/whpx-common.c
@@ -434,18 +434,12 @@ error:
     return false;
 }
 
-static void whpx_set_kernel_irqchip(Object *obj, Visitor *v,
-                                   const char *name, void *opaque,
-                                   Error **errp)
+static void whpx_set_kernel_irqchip(Object *obj, int value,
+                                    Error **errp)
 {
     struct whpx_state *whpx = &whpx_global;
-    OnOffSplit mode;
 
-    if (!visit_type_OnOffSplit(v, name, &mode, errp)) {
-        return;
-    }
-
-    switch (mode) {
+    switch (value) {
     case ON_OFF_SPLIT_ON:
         whpx->kernel_irqchip_allowed = true;
         whpx->kernel_irqchip_required = true;
@@ -463,11 +457,7 @@ static void whpx_set_kernel_irqchip(Object *obj, Visitor *v,
         break;
 
     default:
-        /*
-         * The value was checked in visit_type_OnOffSplit() above. If
-         * we get here, then something is wrong in QEMU.
-         */
-        abort();
+        g_assert_not_reached();
     }
 }
 
@@ -518,11 +508,12 @@ static void whpx_accel_class_init(ObjectClass *oc, const void *data)
     ac->pre_resume_vm = whpx_pre_resume_vm;
     ac->allowed = &whpx_allowed;
 
-    object_class_property_add(oc, "kernel-irqchip", "on|off|split",
-        NULL, whpx_set_kernel_irqchip,
-        NULL, NULL);
-    object_class_property_set_description(oc, "kernel-irqchip",
-        "Configure WHPX in-kernel irqchip");
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = "kernel-irqchip",
+        .qapi_type = &OnOffSplit_type_info,
+        .set = whpx_set_kernel_irqchip,
+        .description = "Configure WHPX in-kernel irqchip",
+    ));
     object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
         .name = "hyperv",
         .description = "Configure Hyper-V enlightenments",

-- 
2.54.0



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

* [PATCH 28/54] ppc/spapr-caps: convert to QAPI-aware property registration
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (26 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 27/54] whpx: " Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 29/54] system/memory: fix "priority" property typename Marc-André Lureau
                   ` (26 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/ppc/spapr_caps.c | 39 ++++++++++++++++++++-------------------
 1 file changed, 20 insertions(+), 19 deletions(-)

diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
index f4a26a85b50..779a5605a8f 100644
--- a/hw/ppc/spapr_caps.c
+++ b/hw/ppc/spapr_caps.c
@@ -24,6 +24,7 @@
 
 #include "qemu/osdep.h"
 #include "qemu/error-report.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/error.h"
 #include "qapi/visitor.h"
 #include "system/hw_accel.h"
@@ -59,7 +60,7 @@ typedef struct SpaprCapabilityInfo {
     /* Getter and Setter Function Pointers */
     ObjectPropertyAccessor *get;
     ObjectPropertyAccessor *set;
-    const char *type;
+    const QAPITypeInfo *type;
     /* Possible values if this is a custom string type */
     SpaprCapPossible *possible;
     /* Make sure the virtual hardware can support this capability */
@@ -725,7 +726,7 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
         .index = SPAPR_CAP_HTM,
         .get = spapr_cap_get_bool,
         .set = spapr_cap_set_bool,
-        .type = "bool",
+        .type = &bool_type_info,
         .apply = cap_htm_apply,
     },
     [SPAPR_CAP_VSX] = {
@@ -734,7 +735,7 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
         .index = SPAPR_CAP_VSX,
         .get = spapr_cap_get_bool,
         .set = spapr_cap_set_bool,
-        .type = "bool",
+        .type = &bool_type_info,
         .apply = cap_vsx_apply,
     },
     [SPAPR_CAP_DFP] = {
@@ -743,7 +744,7 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
         .index = SPAPR_CAP_DFP,
         .get = spapr_cap_get_bool,
         .set = spapr_cap_set_bool,
-        .type = "bool",
+        .type = &bool_type_info,
         .apply = cap_dfp_apply,
     },
     [SPAPR_CAP_CFPC] = {
@@ -752,7 +753,7 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
         .index = SPAPR_CAP_CFPC,
         .get = spapr_cap_get_string,
         .set = spapr_cap_set_string,
-        .type = "string",
+        .type = &str_type_info,
         .possible = &cap_cfpc_possible,
         .apply = cap_safe_cache_apply,
     },
@@ -762,7 +763,7 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
         .index = SPAPR_CAP_SBBC,
         .get = spapr_cap_get_string,
         .set = spapr_cap_set_string,
-        .type = "string",
+        .type = &str_type_info,
         .possible = &cap_sbbc_possible,
         .apply = cap_safe_bounds_check_apply,
     },
@@ -774,7 +775,7 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
         .index = SPAPR_CAP_IBS,
         .get = spapr_cap_get_string,
         .set = spapr_cap_set_string,
-        .type = "string",
+        .type = &str_type_info,
         .possible = &cap_ibs_possible,
         .apply = cap_safe_indirect_branch_apply,
     },
@@ -784,7 +785,7 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
         .index = SPAPR_CAP_HPT_MAXPAGESIZE,
         .get = spapr_cap_get_pagesize,
         .set = spapr_cap_set_pagesize,
-        .type = "int",
+        .type = &size_type_info,
         .apply = cap_hpt_maxpagesize_apply,
         .cpu_apply = cap_hpt_maxpagesize_cpu_apply,
     },
@@ -794,7 +795,7 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
         .index = SPAPR_CAP_NESTED_KVM_HV,
         .get = spapr_cap_get_bool,
         .set = spapr_cap_set_bool,
-        .type = "bool",
+        .type = &bool_type_info,
         .apply = cap_nested_kvm_hv_apply,
     },
     [SPAPR_CAP_NESTED_PAPR] = {
@@ -803,7 +804,7 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
         .index = SPAPR_CAP_NESTED_PAPR,
         .get = spapr_cap_get_bool,
         .set = spapr_cap_set_bool,
-        .type = "bool",
+        .type = &bool_type_info,
         .apply = cap_nested_papr_apply,
     },
     [SPAPR_CAP_LARGE_DECREMENTER] = {
@@ -812,7 +813,7 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
         .index = SPAPR_CAP_LARGE_DECREMENTER,
         .get = spapr_cap_get_bool,
         .set = spapr_cap_set_bool,
-        .type = "bool",
+        .type = &bool_type_info,
         .apply = cap_large_decr_apply,
         .cpu_apply = cap_large_decr_cpu_apply,
     },
@@ -822,7 +823,7 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
         .index = SPAPR_CAP_CCF_ASSIST,
         .get = spapr_cap_get_bool,
         .set = spapr_cap_set_bool,
-        .type = "bool",
+        .type = &bool_type_info,
         .apply = cap_ccf_assist_apply,
     },
     [SPAPR_CAP_FWNMI] = {
@@ -831,7 +832,7 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
         .index = SPAPR_CAP_FWNMI,
         .get = spapr_cap_get_bool,
         .set = spapr_cap_set_bool,
-        .type = "bool",
+        .type = &bool_type_info,
         .apply = cap_fwnmi_apply,
     },
     [SPAPR_CAP_RPT_INVALIDATE] = {
@@ -840,7 +841,7 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
         .index = SPAPR_CAP_RPT_INVALIDATE,
         .get = spapr_cap_get_bool,
         .set = spapr_cap_set_bool,
-        .type = "bool",
+        .type = &bool_type_info,
         .apply = cap_rpt_invalidate_apply,
     },
     [SPAPR_CAP_AIL_MODE_3] = {
@@ -849,7 +850,7 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
         .index = SPAPR_CAP_AIL_MODE_3,
         .get = spapr_cap_get_bool,
         .set = spapr_cap_set_bool,
-        .type = "bool",
+        .type = &bool_type_info,
         .apply = cap_ail_mode_3_apply,
     },
     [SPAPR_CAP_DAWR1] = {
@@ -858,7 +859,7 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
         .index = SPAPR_CAP_DAWR1,
         .get = spapr_cap_get_bool,
         .set = spapr_cap_set_bool,
-        .type = "bool",
+        .type = &bool_type_info,
         .apply = cap_dawr1_apply,
     },
 };
@@ -1069,9 +1070,9 @@ void spapr_caps_add_properties(SpaprMachineClass *smc)
         g_autofree char *name = g_strdup_printf("cap-%s", cap->name);
         g_autofree char *desc = g_strdup(cap->description);
 
-        object_class_property_add(klass, name, cap->type,
-                                  cap->get, cap->set,
-                                  NULL, cap);
+        object_class_property_add_qapi(klass, name, cap->type,
+                                       cap->get, cap->set,
+                                       NULL, cap);
 
         object_class_property_set_description(klass, name, desc);
     }

-- 
2.54.0



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

* [PATCH 29/54] system/memory: fix "priority" property typename
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (27 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 28/54] ppc/spapr-caps: convert to QAPI-aware property registration Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 30/54] hw/mem/nvdimm: fix "size" " Marc-André Lureau
                   ` (25 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

The value and the getter are int32.

Fixes: d33382da9ab ("memory: MemoryRegion: Add may-overlap and priority props")
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 system/memory.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/system/memory.c b/system/memory.c
index 739ba11da6f..aaf5ec40230 100644
--- a/system/memory.c
+++ b/system/memory.c
@@ -1316,7 +1316,7 @@ static void memory_region_initfn(Object *obj)
 
     object_property_add_uint64_ptr(OBJECT(mr), "addr",
                                    &mr->addr, OBJ_PROP_FLAG_READ);
-    object_property_add(OBJECT(mr), "priority", "uint32",
+    object_property_add(OBJECT(mr), "priority", "int32",
                         memory_region_get_priority,
                         NULL, /* memory_region_set_priority */
                         NULL, NULL);

-- 
2.54.0



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

* [PATCH 30/54] hw/mem/nvdimm: fix "size" property typename
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (28 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 29/54] system/memory: fix "priority" property typename Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 31/54] qom: convert scalar properties to QAPI-aware registration Marc-André Lureau
                   ` (24 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

The getter/setter use visit_type_size().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/mem/nvdimm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/mem/nvdimm.c b/hw/mem/nvdimm.c
index b7032525271..cf8a4d8c5f2 100644
--- a/hw/mem/nvdimm.c
+++ b/hw/mem/nvdimm.c
@@ -99,7 +99,7 @@ static void nvdimm_set_uuid(Object *obj, Visitor *v, const char *name,
 
 static void nvdimm_init(Object *obj)
 {
-    object_property_add(obj, NVDIMM_LABEL_SIZE_PROP, "int",
+    object_property_add(obj, NVDIMM_LABEL_SIZE_PROP, "size",
                         nvdimm_get_label_size, nvdimm_set_label_size, NULL,
                         NULL);
 

-- 
2.54.0



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

* [PATCH 31/54] qom: convert scalar properties to QAPI-aware registration
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (29 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 30/54] hw/mem/nvdimm: fix "size" " Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 32/54] i386/cpu: convert strList property " Marc-André Lureau
                   ` (23 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 accel/kvm/kvm-all.c                 |  5 ++-
 accel/nitro/nitro-accel.c           |  3 +-
 accel/tcg/tcg-all.c                 |  3 +-
 backends/cryptodev.c                |  7 ++--
 backends/hostmem-file.c             |  4 +-
 backends/hostmem-memfd.c            |  3 +-
 backends/hostmem.c                  |  6 +--
 block/throttle-groups.c             |  5 ++-
 crypto/secret_keyring.c             |  9 +++--
 event-loop-base.c                   |  7 ++--
 hw/acpi/ich9.c                      |  3 +-
 hw/acpi/pci.c                       |  5 ++-
 hw/arm/virt.c                       |  4 +-
 hw/core/clock.c                     |  3 +-
 hw/core/machine.c                   |  2 +-
 hw/cpu/core.c                       | 10 +++--
 hw/cxl/cxl-host.c                   |  2 +-
 hw/gpio/aspeed_gpio.c               |  5 ++-
 hw/gpio/aspeed_sgpio.c              |  3 +-
 hw/gpio/pca9552.c                   |  6 ++-
 hw/gpio/pca9554.c                   |  6 ++-
 hw/gpio/stm32l4x5_gpio.c            |  5 ++-
 hw/i386/pc.c                        |  6 +--
 hw/i386/sgx-epc.c                   |  3 +-
 hw/i386/x86.c                       |  6 +--
 hw/ide/ide-dev.c                    |  3 +-
 hw/intc/apic_common.c               |  3 +-
 hw/loongarch/virt.c                 |  2 +-
 hw/mem/nvdimm.c                     |  7 ++--
 hw/mem/pc-dimm.c                    |  3 +-
 hw/misc/aspeed_lpc.c                | 73 +++++++++++++++++++++++++------------
 hw/misc/aspeed_sdmc.c               |  3 +-
 hw/misc/npcm7xx_mft.c               |  3 +-
 hw/net/ne2000-isa.c                 |  3 +-
 hw/nvme/ctrl.c                      |  3 +-
 hw/pci-bridge/pci_expander_bridge.c |  3 +-
 hw/pci-host/i440fx.c                | 35 ++++++++++--------
 hw/pci-host/pnv_phb3.c              |  5 ++-
 hw/pci-host/pnv_phb4.c              |  5 ++-
 hw/pci-host/q35.c                   |  9 +++--
 hw/ppc/spapr_drc.c                  |  3 +-
 hw/riscv/microchip_pfsoc.c          |  3 +-
 hw/s390x/sclpcpi.c                  |  8 ++--
 hw/s390x/virtio-ccw-mem.c           |  3 +-
 hw/sensor/adm1266.c                 |  3 +-
 hw/sensor/adm1272.c                 |  9 +++--
 hw/sensor/emc141x.c                 |  9 +++--
 hw/sensor/isl_pmbus_vr.c            | 19 +++++-----
 hw/sensor/lsm303dlhc_mag.c          |  9 +++--
 hw/sensor/max34451.c                |  5 ++-
 hw/sensor/tmp105.c                  |  3 +-
 hw/sensor/tmp421.c                  |  9 +++--
 hw/usb/dev-storage-classic.c        |  3 +-
 hw/virtio/virtio-balloon.c          |  3 +-
 hw/virtio/virtio-mem-pci.c          |  3 +-
 hw/virtio/virtio-mem.c              | 18 +++++----
 hw/xen/xen-pvh-common.c             |  9 +++--
 iothread.c                          |  9 +++--
 net/colo-compare.c                  |  7 ++--
 net/dump.c                          |  6 ++-
 net/filter-buffer.c                 |  3 +-
 qom/object.c                        | 42 ++++++++++-----------
 system/bootdevice.c                 |  3 +-
 system/memory.c                     |  5 ++-
 target/arm/cpu64.c                  | 11 +++---
 target/arm/kvm.c                    |  3 +-
 target/arm/tcg/cpu64.c              |  5 ++-
 target/i386/cpu.c                   | 12 +++---
 target/i386/kvm/kvm.c               |  8 ++--
 target/i386/sev.c                   |  2 +-
 target/ppc/compat.c                 |  3 +-
 target/riscv/cpu.c                  | 11 +++---
 target/riscv/kvm/kvm-cpu.c          |  7 ++--
 target/riscv/tcg/tcg-cpu.c          |  7 ++--
 target/s390x/cpu_models.c           |  5 ++-
 tests/unit/test-qdev-global-props.c | 11 ++++--
 ui/console.c                        |  3 +-
 util/thread-context.c               |  7 ++--
 78 files changed, 336 insertions(+), 234 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 94b64cde621..84033b77473 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -24,6 +24,7 @@
 #include "qemu/config-file.h"
 #include "qemu/error-report.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "hw/pci/msi.h"
 #include "hw/pci/msix.h"
 #include "hw/s390x/adapter.h"
@@ -4306,13 +4307,13 @@ static void kvm_accel_class_init(ObjectClass *oc, const void *data)
         .description = "Configure KVM in-kernel irqchip",
     ));
 
-    object_class_property_add(oc, "kvm-shadow-mem", "int",
+    object_class_property_add_qapi(oc, "kvm-shadow-mem", &int_type_info,
         kvm_get_kvm_shadow_mem, kvm_set_kvm_shadow_mem,
         NULL, NULL);
     object_class_property_set_description(oc, "kvm-shadow-mem",
         "KVM shadow MMU size");
 
-    object_class_property_add(oc, "dirty-ring-size", "uint32",
+    object_class_property_add_qapi(oc, "dirty-ring-size", &uint32_type_info,
         kvm_get_dirty_ring_size, kvm_set_dirty_ring_size,
         NULL, NULL);
     object_class_property_set_description(oc, "dirty-ring-size",
diff --git a/accel/nitro/nitro-accel.c b/accel/nitro/nitro-accel.c
index a1e97a9162e..05841c1277d 100644
--- a/accel/nitro/nitro-accel.c
+++ b/accel/nitro/nitro-accel.c
@@ -29,6 +29,7 @@
 #include "qemu/osdep.h"
 #include "qemu/error-report.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "qemu/module.h"
 #include "qemu/rcu.h"
@@ -238,7 +239,7 @@ static void nitro_accel_class_init(ObjectClass *oc, const void *data)
     object_class_property_set_description(oc, "debug-mode",
         "Start enclave in debug mode (enables console output)");
 
-    object_class_property_add(oc, "enclave-cid", "uint64",
+    object_class_property_add_qapi(oc, "enclave-cid", &uint64_type_info,
                               nitro_get_enclave_cid,
                               nitro_set_enclave_cid,
                               NULL, NULL);
diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
index 8eb4a6b89e8..4e9d7a1da33 100644
--- a/accel/tcg/tcg-all.c
+++ b/accel/tcg/tcg-all.c
@@ -29,6 +29,7 @@
 #include "exec/icount.h"
 #include "tcg/startup.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qemu/error-report.h"
 #include "qemu/accel.h"
 #include "qemu/atomic.h"
@@ -272,7 +273,7 @@ static void tcg_accel_class_init(ObjectClass *oc, const void *data)
                                   tcg_get_thread,
                                   tcg_set_thread);
 
-    object_class_property_add(oc, "tb-size", "int",
+    object_class_property_add_qapi(oc, "tb-size", &int_type_info,
         tcg_get_tb_size, tcg_set_tb_size,
         NULL, NULL);
     object_class_property_set_description(oc, "tb-size",
diff --git a/backends/cryptodev.c b/backends/cryptodev.c
index 79f8882d3be..014774d60fd 100644
--- a/backends/cryptodev.c
+++ b/backends/cryptodev.c
@@ -25,6 +25,7 @@
 #include "system/cryptodev.h"
 #include "system/stats.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/qapi-commands-cryptodev.h"
 #include "qapi/qapi-types-stats.h"
 #include "qapi/visitor.h"
@@ -616,15 +617,15 @@ cryptodev_backend_class_init(ObjectClass *oc, const void *data)
     ucc->can_be_deleted = cryptodev_backend_can_be_deleted;
 
     QTAILQ_INIT(&crypto_clients);
-    object_class_property_add(oc, "queues", "uint32",
+    object_class_property_add_qapi(oc, "queues", &uint32_type_info,
                               cryptodev_backend_get_queues,
                               cryptodev_backend_set_queues,
                               NULL, NULL);
-    object_class_property_add(oc, "throttle-bps", "uint64",
+    object_class_property_add_qapi(oc, "throttle-bps", &uint64_type_info,
                               cryptodev_backend_get_bps,
                               cryptodev_backend_set_bps,
                               NULL, NULL);
-    object_class_property_add(oc, "throttle-ops", "uint64",
+    object_class_property_add_qapi(oc, "throttle-ops", &uint64_type_info,
                               cryptodev_backend_get_ops,
                               cryptodev_backend_set_ops,
                               NULL, NULL);
diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index 52b62f71533..399aae02e2c 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -275,11 +275,11 @@ file_backend_class_init(ObjectClass *oc, const void *data)
         file_memory_backend_get_discard_data, file_memory_backend_set_discard_data);
     object_class_property_add_str(oc, "mem-path",
         get_mem_path, set_mem_path);
-    object_class_property_add(oc, "align", "int",
+    object_class_property_add_qapi(oc, "align", &int_type_info,
         file_memory_backend_get_align,
         file_memory_backend_set_align,
         NULL, NULL);
-    object_class_property_add(oc, "offset", "int",
+    object_class_property_add_qapi(oc, "offset", &int_type_info,
         file_memory_backend_get_offset,
         file_memory_backend_set_offset,
         NULL, NULL);
diff --git a/backends/hostmem-memfd.c b/backends/hostmem-memfd.c
index 923239f9cf6..ab069a70379 100644
--- a/backends/hostmem-memfd.c
+++ b/backends/hostmem-memfd.c
@@ -16,6 +16,7 @@
 #include "qemu/memfd.h"
 #include "qemu/module.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qom/object.h"
 #include "migration/cpr.h"
 
@@ -145,7 +146,7 @@ memfd_backend_class_init(ObjectClass *oc, const void *data)
                                        memfd_backend_set_hugetlb);
         object_class_property_set_description(oc, "hugetlb",
                                               "Use huge pages");
-        object_class_property_add(oc, "hugetlbsize", "int",
+        object_class_property_add_qapi(oc, "hugetlbsize", &int_type_info,
                                   memfd_backend_get_hugetlbsize,
                                   memfd_backend_set_hugetlbsize,
                                   NULL, NULL);
diff --git a/backends/hostmem.c b/backends/hostmem.c
index d0977552b40..ab20e9b79dc 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -526,7 +526,7 @@ host_memory_backend_class_init(ObjectClass *oc, const void *data)
         host_memory_backend_set_prealloc);
     object_class_property_set_description(oc, "prealloc",
         "Preallocate memory");
-    object_class_property_add(oc, "prealloc-threads", "int",
+    object_class_property_add_qapi(oc, "prealloc-threads", &int_type_info,
         host_memory_backend_get_prealloc_threads,
         host_memory_backend_set_prealloc_threads,
         NULL, NULL);
@@ -537,13 +537,13 @@ host_memory_backend_class_init(ObjectClass *oc, const void *data)
         object_property_allow_set_link, OBJ_PROP_LINK_STRONG);
     object_class_property_set_description(oc, "prealloc-context",
         "Context to use for creating CPU threads for preallocation");
-    object_class_property_add(oc, "size", "int",
+    object_class_property_add_qapi(oc, "size", &int_type_info,
         host_memory_backend_get_size,
         host_memory_backend_set_size,
         NULL, NULL);
     object_class_property_set_description(oc, "size",
         "Size of the memory region (ex: 500M)");
-    object_class_property_add(oc, "host-nodes", "int",
+    object_class_property_add_qapi(oc, "host-nodes", &int_type_info,
         host_memory_backend_get_host_nodes,
         host_memory_backend_set_host_nodes,
         NULL, NULL);
diff --git a/block/throttle-groups.c b/block/throttle-groups.c
index b161576432a..2a17ae79f74 100644
--- a/block/throttle-groups.c
+++ b/block/throttle-groups.c
@@ -31,6 +31,7 @@
 #include "qemu/thread.h"
 #include "system/qtest.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/qapi-type-infos-block-core.h"
 #include "qapi/qapi-visit-block-core.h"
 #include "qom/object.h"
@@ -977,9 +978,9 @@ static void throttle_group_obj_class_init(ObjectClass *klass,
 
     /* individual properties */
     for (i = 0; i < sizeof(properties) / sizeof(ThrottleParamInfo); i++) {
-        object_class_property_add(klass,
+        object_class_property_add_qapi(klass,
                                   properties[i].name,
-                                  "int",
+                                  &int_type_info,
                                   throttle_group_get,
                                   throttle_group_set,
                                   NULL, &properties[i]);
diff --git a/crypto/secret_keyring.c b/crypto/secret_keyring.c
index 78d7f09b3b9..de813e79d8d 100644
--- a/crypto/secret_keyring.c
+++ b/crypto/secret_keyring.c
@@ -21,6 +21,7 @@
 #include "qemu/osdep.h"
 #include <asm/unistd.h>
 #include <linux/keyctl.h>
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/error.h"
 #include "qom/object_interfaces.h"
 #include "trace.h"
@@ -108,10 +109,10 @@ qcrypto_secret_keyring_class_init(ObjectClass *oc, const void *data)
     QCryptoSecretCommonClass *sic = QCRYPTO_SECRET_COMMON_CLASS(oc);
     sic->load_data = qcrypto_secret_keyring_load_data;
 
-    object_class_property_add(oc, "serial", "int32_t",
-                                  qcrypto_secret_prop_get_key,
-                                  qcrypto_secret_prop_set_key,
-                                  NULL, NULL);
+    object_class_property_add_qapi(oc, "serial", &int32_type_info,
+                                   qcrypto_secret_prop_get_key,
+                                   qcrypto_secret_prop_set_key,
+                                   NULL, NULL);
 }
 
 
diff --git a/event-loop-base.c b/event-loop-base.c
index 8ca143bea43..284f2f56b85 100644
--- a/event-loop-base.c
+++ b/event-loop-base.c
@@ -14,6 +14,7 @@
 #include "qemu/osdep.h"
 #include "qom/object_interfaces.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "block/thread-pool.h"
 #include "system/event-loop-base.h"
 
@@ -104,15 +105,15 @@ static void event_loop_base_class_init(ObjectClass *klass,
     ucc->complete = event_loop_base_complete;
     ucc->can_be_deleted = event_loop_base_can_be_deleted;
 
-    object_class_property_add(klass, "aio-max-batch", "int",
+    object_class_property_add_qapi(klass, "aio-max-batch", &int_type_info,
                               event_loop_base_get_param,
                               event_loop_base_set_param,
                               NULL, &aio_max_batch_info);
-    object_class_property_add(klass, "thread-pool-min", "int",
+    object_class_property_add_qapi(klass, "thread-pool-min", &int_type_info,
                               event_loop_base_get_param,
                               event_loop_base_set_param,
                               NULL, &thread_pool_min_info);
-    object_class_property_add(klass, "thread-pool-max", "int",
+    object_class_property_add_qapi(klass, "thread-pool-max", &int_type_info,
                               event_loop_base_get_param,
                               event_loop_base_set_param,
                               NULL, &thread_pool_max_info);
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 5c7dfb2c69d..f8196c771f2 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -26,6 +26,7 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "hw/pci/pci.h"
 #include "migration/vmstate.h"
@@ -405,7 +406,7 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm)
                              (Object **)&pm->acpi_pci_hotplug.root,
                              object_property_allow_set_link,
                              OBJ_PROP_LINK_STRONG);
-    object_property_add(obj, ACPI_PM_PROP_GPE0_BLK, "uint32",
+    object_property_add_qapi(obj, ACPI_PM_PROP_GPE0_BLK, &uint32_type_info,
                         ich9_pm_get_gpe0_blk,
                         NULL, NULL, pm);
     object_property_add_uint32_ptr(obj, ACPI_PM_PROP_GPE0_BLK_LEN,
diff --git a/hw/acpi/pci.c b/hw/acpi/pci.c
index 8c7ed104796..727f3aade4a 100644
--- a/hw/acpi/pci.c
+++ b/hw/acpi/pci.c
@@ -27,6 +27,7 @@
 #include "qemu/error-report.h"
 #include "qom/object_interfaces.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "hw/core/boards.h"
 #include "hw/acpi/aml-build.h"
 #include "hw/acpi/pci.h"
@@ -139,7 +140,7 @@ static void acpi_generic_initiator_class_init(ObjectClass *oc, const void *data)
         acpi_generic_initiator_set_pci_device);
     object_class_property_set_description(oc, "pci-dev",
         "PCI device to associate with the node");
-    object_class_property_add(oc, "node", "int", NULL,
+    object_class_property_add_qapi(oc, "node", &int_type_info, NULL,
         acpi_generic_initiator_set_node, NULL, NULL);
     object_class_property_set_description(oc, "node",
         "NUMA node associated with the PCI device");
@@ -253,7 +254,7 @@ static void acpi_generic_port_class_init(ObjectClass *oc, const void *data)
         acpi_generic_port_set_pci_bus);
     object_class_property_set_description(oc, "pci-bus",
        "PCI Bus of the host bridge associated with this GP affinity structure");
-    object_class_property_add(oc, "node", "int", NULL,
+    object_class_property_add_qapi(oc, "node", &int_type_info, NULL,
         acpi_generic_port_set_node, NULL, NULL);
     object_class_property_set_description(oc, "node",
        "The NUMA node like ID to index HMAT/SLIT NUMA properties involving GP");
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index e4c75cb1bae..b045b4f8cc0 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -3918,7 +3918,7 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data)
                                           "Set on/off to enable/disable high "
                                           "memory region for PCI MMIO");
 
-    object_class_property_add(oc, "highmem-mmio-size", "size",
+    object_class_property_add_qapi(oc, "highmem-mmio-size", &size_type_info,
                                    virt_get_highmem_mmio_size,
                                    virt_set_highmem_mmio_size,
                                    NULL, NULL);
@@ -3926,7 +3926,7 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data)
                                           "Set the high memory region size "
                                           "for PCI MMIO");
 
-    object_class_property_add(oc, "virtio-mmio-transports", "uint8",
+    object_class_property_add_qapi(oc, "virtio-mmio-transports", &uint8_type_info,
                                    virt_get_virtio_transports,
                                    virt_set_virtio_transports,
                                    NULL, NULL);
diff --git a/hw/core/clock.c b/hw/core/clock.c
index 3fc98a0c65d..f55cb17af77 100644
--- a/hw/core/clock.c
+++ b/hw/core/clock.c
@@ -13,6 +13,7 @@
 
 #include "qemu/osdep.h"
 #include "qemu/cutils.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "system/qtest.h"
 #include "hw/core/clock.h"
@@ -185,7 +186,7 @@ static void clock_initfn(Object *obj)
     QLIST_INIT(&clk->children);
 
     if (qtest_enabled()) {
-        object_property_add(obj, "qtest-clock-period", "uint64",
+        object_property_add_qapi(obj, "qtest-clock-period", &uint64_type_info,
                             clock_period_prop_get, NULL, NULL, NULL);
     }
 }
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 1dd5375caea..862e6174fef 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -1113,7 +1113,7 @@ static void machine_class_init(ObjectClass *oc, const void *data)
     object_class_property_set_description(oc, "smp-cache",
         "Cache properties list for SMP machine");
 
-    object_class_property_add(oc, "phandle-start", "int",
+    object_class_property_add_qapi(oc, "phandle-start", &int_type_info,
         machine_get_phandle_start, machine_set_phandle_start,
         NULL, NULL);
     object_class_property_set_description(oc, "phandle-start",
diff --git a/hw/cpu/core.c b/hw/cpu/core.c
index 26e488f3d8e..d7c89f47ab0 100644
--- a/hw/cpu/core.c
+++ b/hw/cpu/core.c
@@ -12,6 +12,7 @@
 #include "hw/core/boards.h"
 #include "hw/cpu/core.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 
 static void core_prop_get_core_id(Object *obj, Visitor *v, const char *name,
@@ -82,10 +83,11 @@ static void cpu_core_class_init(ObjectClass *oc, const void *data)
     DeviceClass *dc = DEVICE_CLASS(oc);
 
     set_bit(DEVICE_CATEGORY_CPU, dc->categories);
-    object_class_property_add(oc, "core-id", "int", core_prop_get_core_id,
-                              core_prop_set_core_id, NULL, NULL);
-    object_class_property_add(oc, "nr-threads", "int", core_prop_get_nr_threads,
-                              core_prop_set_nr_threads, NULL, NULL);
+    object_class_property_add_qapi(oc, "core-id", &int_type_info, core_prop_get_core_id,
+                                   core_prop_set_core_id, NULL, NULL);
+    object_class_property_add_qapi(oc, "nr-threads", &int_type_info,
+                                   core_prop_get_nr_threads, core_prop_set_nr_threads,
+                                   NULL, NULL);
 }
 
 static const TypeInfo cpu_core_type_info = {
diff --git a/hw/cxl/cxl-host.c b/hw/cxl/cxl-host.c
index 87067b94b34..e94ce29a00f 100644
--- a/hw/cxl/cxl-host.c
+++ b/hw/cxl/cxl-host.c
@@ -345,7 +345,7 @@ static void machine_set_cfmw(Object *obj, Visitor *v, const char *name,
 
 void cxl_machine_init(Object *obj, CXLState *state)
 {
-    object_property_add(obj, "cxl", "bool", machine_get_cxl,
+    object_property_add_qapi(obj, "cxl", &bool_type_info, machine_get_cxl,
                         machine_set_cxl, NULL, state);
     object_property_set_description(obj, "cxl",
                                     "Set on/off to enable/disable "
diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c
index 7d0f87e90c3..3b8dd66f086 100644
--- a/hw/gpio/aspeed_gpio.c
+++ b/hw/gpio/aspeed_gpio.c
@@ -12,6 +12,7 @@
 #include "hw/gpio/aspeed_gpio.h"
 #include "hw/misc/aspeed_scu.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "hw/core/irq.h"
 #include "migration/vmstate.h"
@@ -1481,7 +1482,7 @@ static void aspeed_gpio_init(Object *obj)
             int pin_idx = j % GPIOS_PER_GROUP;
             const char *group = &props->group_label[group_idx][0];
             char *name = g_strdup_printf("gpio%s%d", group, pin_idx);
-            object_property_add(obj, name, "bool", aspeed_gpio_get_pin,
+            object_property_add_qapi(obj, name, &bool_type_info, aspeed_gpio_get_pin,
                                 aspeed_gpio_set_pin, NULL, NULL);
             g_free(name);
         }
@@ -1489,7 +1490,7 @@ static void aspeed_gpio_init(Object *obj)
 
     for (int i = 0; i < agc->nr_gpio_sets; i++) {
         g_autofree char *name = g_strdup_printf("gpio-set[%d]", i);
-        object_property_add(obj, name, "uint32", aspeed_gpio_get_set,
+        object_property_add_qapi(obj, name, &uint32_type_info, aspeed_gpio_get_set,
         aspeed_gpio_set_set, NULL, NULL);
     }
 }
diff --git a/hw/gpio/aspeed_sgpio.c b/hw/gpio/aspeed_sgpio.c
index 0c53b03464e..9234ae291d4 100644
--- a/hw/gpio/aspeed_sgpio.c
+++ b/hw/gpio/aspeed_sgpio.c
@@ -11,6 +11,7 @@
 #include "qemu/log.h"
 #include "qemu/error-report.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "hw/core/irq.h"
 #include "hw/core/qdev-properties.h"
@@ -300,7 +301,7 @@ static void aspeed_sgpio_init(Object *obj)
 {
     for (int i = 0; i < ASPEED_SGPIO_MAX_PIN_PAIR * 2; i++) {
         g_autofree char *name = g_strdup_printf("sgpio%03d", i);
-        object_property_add(obj, name, "bool", aspeed_sgpio_get_pin,
+        object_property_add_qapi(obj, name, &bool_type_info, aspeed_sgpio_get_pin,
                             aspeed_sgpio_set_pin, NULL, NULL);
     }
 }
diff --git a/hw/gpio/pca9552.c b/hw/gpio/pca9552.c
index dd3f1536b65..8132011736d 100644
--- a/hw/gpio/pca9552.c
+++ b/hw/gpio/pca9552.c
@@ -20,6 +20,7 @@
 #include "hw/core/irq.h"
 #include "migration/vmstate.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "trace.h"
 #include "qom/object.h"
@@ -437,8 +438,9 @@ static void pca955x_initfn(Object *obj)
         char *name;
 
         name = g_strdup_printf("led%d", led);
-        object_property_add(obj, name, "bool", pca955x_get_led, pca955x_set_led,
-                            NULL, NULL);
+        object_property_add_qapi(obj, name, &bool_type_info,
+                                 pca955x_get_led, pca955x_set_led,
+                                 NULL, NULL);
         g_free(name);
     }
 }
diff --git a/hw/gpio/pca9554.c b/hw/gpio/pca9554.c
index 8427e01e9b2..8ec1f94bb5c 100644
--- a/hw/gpio/pca9554.c
+++ b/hw/gpio/pca9554.c
@@ -16,6 +16,7 @@
 #include "hw/core/irq.h"
 #include "migration/vmstate.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "trace.h"
 #include "qom/object.h"
@@ -253,8 +254,9 @@ static void pca9554_initfn(Object *obj)
         char *name;
 
         name = g_strdup_printf("pin%d", pin);
-        object_property_add(obj, name, "bool", pca9554_get_pin, pca9554_set_pin,
-                            NULL, NULL);
+        object_property_add_qapi(obj, name, &bool_type_info,
+                                 pca9554_get_pin, pca9554_set_pin,
+                                 NULL, NULL);
         g_free(name);
     }
 }
diff --git a/hw/gpio/stm32l4x5_gpio.c b/hw/gpio/stm32l4x5_gpio.c
index 92fa397fbaf..d349d41e41a 100644
--- a/hw/gpio/stm32l4x5_gpio.c
+++ b/hw/gpio/stm32l4x5_gpio.c
@@ -25,6 +25,7 @@
 #include "hw/core/qdev-properties.h"
 #include "qapi/visitor.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "migration/vmstate.h"
 #include "trace.h"
 
@@ -409,10 +410,10 @@ static void stm32l4x5_gpio_init(Object *obj)
 
     s->clk = qdev_init_clock_in(DEVICE(s), "clk", NULL, s, 0);
 
-    object_property_add(obj, "disconnected-pins", "uint16",
+    object_property_add_qapi(obj, "disconnected-pins", &uint16_type_info,
                         disconnected_pins_get, disconnected_pins_set,
                         NULL, &s->disconnected_pins);
-    object_property_add(obj, "clock-freq-hz", "uint32",
+    object_property_add_qapi(obj, "clock-freq-hz", &uint32_type_info,
                         clock_freq_get, NULL, NULL, NULL);
 }
 
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 6a4fe126bc0..b8dc955478c 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1671,7 +1671,7 @@ static void pc_machine_class_init(ObjectClass *oc, const void *data)
     mc->default_ram_id = "pc.ram";
     pcmc->default_smbios_ep_type = SMBIOS_ENTRY_POINT_TYPE_AUTO;
 
-    object_class_property_add(oc, PC_MACHINE_MAX_RAM_BELOW_4G, "size",
+    object_class_property_add_qapi(oc, PC_MACHINE_MAX_RAM_BELOW_4G, &size_type_info,
         pc_machine_get_max_ram_below_4g, pc_machine_set_max_ram_below_4g,
         NULL, NULL);
     object_class_property_set_description(oc, PC_MACHINE_MAX_RAM_BELOW_4G,
@@ -1709,13 +1709,13 @@ static void pc_machine_class_init(ObjectClass *oc, const void *data)
         pc_machine_get_default_bus_bypass_iommu,
         pc_machine_set_default_bus_bypass_iommu);
 
-    object_class_property_add(oc, PC_MACHINE_MAX_FW_SIZE, "size",
+    object_class_property_add_qapi(oc, PC_MACHINE_MAX_FW_SIZE, &size_type_info,
         pc_machine_get_max_fw_size, pc_machine_set_max_fw_size,
         NULL, NULL);
     object_class_property_set_description(oc, PC_MACHINE_MAX_FW_SIZE,
         "Maximum combined firmware size");
 
-    object_class_property_add(oc, PC_MACHINE_SMBIOS_EP, "str",
+    object_class_property_add_qapi(oc, PC_MACHINE_SMBIOS_EP, &str_type_info,
         pc_machine_get_smbios_ep, pc_machine_set_smbios_ep,
         NULL, NULL);
     object_class_property_set_description(oc, PC_MACHINE_SMBIOS_EP,
diff --git a/hw/i386/sgx-epc.c b/hw/i386/sgx-epc.c
index d3fe10028c5..d9b9ab3f7a9 100644
--- a/hw/i386/sgx-epc.c
+++ b/hw/i386/sgx-epc.c
@@ -15,6 +15,7 @@
 #include "hw/mem/memory-device.h"
 #include "hw/core/qdev-properties.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "target/i386/cpu.h"
 #include "system/address-spaces.h"
@@ -43,7 +44,7 @@ static void sgx_epc_get_size(Object *obj, Visitor *v, const char *name,
 
 static void sgx_epc_init(Object *obj)
 {
-    object_property_add(obj, SGX_EPC_SIZE_PROP, "uint64", sgx_epc_get_size,
+    object_property_add_qapi(obj, SGX_EPC_SIZE_PROP, &uint64_type_info, sgx_epc_get_size,
                         NULL, NULL, NULL);
 }
 
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index b76926a00bd..3ff54c6f3f9 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -412,9 +412,9 @@ static void x86_machine_class_init(ObjectClass *oc, const void *data)
                                           "in ACPI table header."
                                           "The string may be up to 8 bytes in size");
 
-    object_class_property_add(oc, X86_MACHINE_BUS_LOCK_RATELIMIT, "uint64_t",
-                                x86_machine_get_bus_lock_ratelimit,
-                                x86_machine_set_bus_lock_ratelimit, NULL, NULL);
+    object_class_property_add_qapi(oc, X86_MACHINE_BUS_LOCK_RATELIMIT, &uint64_type_info,
+                                   x86_machine_get_bus_lock_ratelimit,
+                                   x86_machine_set_bus_lock_ratelimit, NULL, NULL);
     object_class_property_set_description(oc, X86_MACHINE_BUS_LOCK_RATELIMIT,
             "Set the ratelimit for the bus locks acquired in VMs");
 
diff --git a/hw/ide/ide-dev.c b/hw/ide/ide-dev.c
index 5d478588c61..e2dd2439991 100644
--- a/hw/ide/ide-dev.c
+++ b/hw/ide/ide-dev.c
@@ -19,6 +19,7 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/qapi-types-block.h"
 #include "qemu/error-report.h"
 #include "qemu/module.h"
@@ -174,7 +175,7 @@ out:
 
 static void ide_dev_instance_init(Object *obj)
 {
-    object_property_add(obj, "bootindex", "int32",
+    object_property_add_qapi(obj, "bootindex", &int32_type_info,
                         ide_dev_get_bootindex,
                         ide_dev_set_bootindex, NULL, NULL);
     object_property_set_int(obj, "bootindex", -1, NULL);
diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
index bf4abc21d7b..d6c1a806727 100644
--- a/hw/intc/apic_common.c
+++ b/hw/intc/apic_common.c
@@ -22,6 +22,7 @@
 #include "qemu/error-report.h"
 #include "qemu/module.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "hw/i386/apic.h"
 #include "hw/i386/apic_internal.h"
@@ -439,7 +440,7 @@ static void apic_common_initfn(Object *obj)
     APICCommonState *s = APIC_COMMON(obj);
 
     s->id = s->initial_apic_id = -1;
-    object_property_add(obj, "id", "uint32",
+    object_property_add_qapi(obj, "id", &uint32_type_info,
                         apic_common_get_id,
                         apic_common_set_id, NULL, NULL);
 }
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index b301398d1bd..9ab550c231b 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -1521,7 +1521,7 @@ static void virt_class_init(ObjectClass *oc, const void *data)
     object_class_property_set_description(oc, "highmem-mmio",
                                           "Set on/off to enable/disable high "
                                           "memory region for PCI MMIO");
-    object_class_property_add(oc, "highmem-mmio-size", "size",
+    object_class_property_add_qapi(oc, "highmem-mmio-size", &size_type_info,
                                    virt_get_highmem_mmio_size,
                                    virt_set_highmem_mmio_size,
                                    NULL, NULL);
diff --git a/hw/mem/nvdimm.c b/hw/mem/nvdimm.c
index cf8a4d8c5f2..123ddc93854 100644
--- a/hw/mem/nvdimm.c
+++ b/hw/mem/nvdimm.c
@@ -26,6 +26,7 @@
 #include "qemu/module.h"
 #include "qemu/pmem.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "hw/mem/nvdimm.h"
 #include "hw/core/qdev-properties.h"
@@ -99,9 +100,9 @@ static void nvdimm_set_uuid(Object *obj, Visitor *v, const char *name,
 
 static void nvdimm_init(Object *obj)
 {
-    object_property_add(obj, NVDIMM_LABEL_SIZE_PROP, "size",
-                        nvdimm_get_label_size, nvdimm_set_label_size, NULL,
-                        NULL);
+    object_property_add_qapi(obj, NVDIMM_LABEL_SIZE_PROP, &size_type_info,
+                             nvdimm_get_label_size, nvdimm_set_label_size, NULL,
+                             NULL);
 
     object_property_add(obj, NVDIMM_UUID_PROP, "QemuUUID", nvdimm_get_uuid,
                         nvdimm_set_uuid, NULL, NULL);
diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c
index 3efe47f499a..1328f1cfec0 100644
--- a/hw/mem/pc-dimm.c
+++ b/hw/mem/pc-dimm.c
@@ -26,6 +26,7 @@
 #include "hw/mem/nvdimm.h"
 #include "hw/mem/memory-device.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "qemu/module.h"
 #include "system/hostmem.h"
@@ -176,7 +177,7 @@ static void pc_dimm_get_size(Object *obj, Visitor *v, const char *name,
 
 static void pc_dimm_init(Object *obj)
 {
-    object_property_add(obj, PC_DIMM_SIZE_PROP, "uint64", pc_dimm_get_size,
+    object_property_add_qapi(obj, PC_DIMM_SIZE_PROP, &uint64_type_info, pc_dimm_get_size,
                         NULL, NULL, NULL);
 }
 
diff --git a/hw/misc/aspeed_lpc.c b/hw/misc/aspeed_lpc.c
index 68f0f6334bc..67a53a12725 100644
--- a/hw/misc/aspeed_lpc.c
+++ b/hw/misc/aspeed_lpc.c
@@ -12,6 +12,7 @@
 #include "qemu/error-report.h"
 #include "hw/misc/aspeed_lpc.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "hw/core/irq.h"
 #include "hw/core/qdev-properties.h"
@@ -417,30 +418,54 @@ static void aspeed_lpc_realize(DeviceState *dev, Error **errp)
 
 static void aspeed_lpc_init(Object *obj)
 {
-    object_property_add(obj, "idr1", "uint32", aspeed_kcs_get_register_property,
-                        aspeed_kcs_set_register_property, NULL, NULL);
-    object_property_add(obj, "odr1", "uint32", aspeed_kcs_get_register_property,
-                        aspeed_kcs_set_register_property, NULL, NULL);
-    object_property_add(obj, "str1", "uint32", aspeed_kcs_get_register_property,
-                        aspeed_kcs_set_register_property, NULL, NULL);
-    object_property_add(obj, "idr2", "uint32", aspeed_kcs_get_register_property,
-                        aspeed_kcs_set_register_property, NULL, NULL);
-    object_property_add(obj, "odr2", "uint32", aspeed_kcs_get_register_property,
-                        aspeed_kcs_set_register_property, NULL, NULL);
-    object_property_add(obj, "str2", "uint32", aspeed_kcs_get_register_property,
-                        aspeed_kcs_set_register_property, NULL, NULL);
-    object_property_add(obj, "idr3", "uint32", aspeed_kcs_get_register_property,
-                        aspeed_kcs_set_register_property, NULL, NULL);
-    object_property_add(obj, "odr3", "uint32", aspeed_kcs_get_register_property,
-                        aspeed_kcs_set_register_property, NULL, NULL);
-    object_property_add(obj, "str3", "uint32", aspeed_kcs_get_register_property,
-                        aspeed_kcs_set_register_property, NULL, NULL);
-    object_property_add(obj, "idr4", "uint32", aspeed_kcs_get_register_property,
-                        aspeed_kcs_set_register_property, NULL, NULL);
-    object_property_add(obj, "odr4", "uint32", aspeed_kcs_get_register_property,
-                        aspeed_kcs_set_register_property, NULL, NULL);
-    object_property_add(obj, "str4", "uint32", aspeed_kcs_get_register_property,
-                        aspeed_kcs_set_register_property, NULL, NULL);
+    object_property_add_qapi(obj, "idr1", &uint32_type_info,
+                             aspeed_kcs_get_register_property,
+                             aspeed_kcs_set_register_property,
+                             NULL, NULL);
+    object_property_add_qapi(obj, "odr1", &uint32_type_info,
+                             aspeed_kcs_get_register_property,
+                             aspeed_kcs_set_register_property,
+                             NULL, NULL);
+    object_property_add_qapi(obj, "str1", &uint32_type_info,
+                             aspeed_kcs_get_register_property,
+                             aspeed_kcs_set_register_property,
+                             NULL, NULL);
+    object_property_add_qapi(obj, "idr2", &uint32_type_info,
+                             aspeed_kcs_get_register_property,
+                             aspeed_kcs_set_register_property,
+                             NULL, NULL);
+    object_property_add_qapi(obj, "odr2", &uint32_type_info,
+                             aspeed_kcs_get_register_property,
+                             aspeed_kcs_set_register_property,
+                             NULL, NULL);
+    object_property_add_qapi(obj, "str2", &uint32_type_info,
+                             aspeed_kcs_get_register_property,
+                             aspeed_kcs_set_register_property,
+                             NULL, NULL);
+    object_property_add_qapi(obj, "idr3", &uint32_type_info,
+                             aspeed_kcs_get_register_property,
+                             aspeed_kcs_set_register_property,
+                             NULL, NULL);
+    object_property_add_qapi(obj, "odr3", &uint32_type_info,
+                             aspeed_kcs_get_register_property,
+                             aspeed_kcs_set_register_property,
+                             NULL, NULL);
+    object_property_add_qapi(obj, "str3", &uint32_type_info,
+                             aspeed_kcs_get_register_property,
+                             aspeed_kcs_set_register_property,
+                             NULL, NULL);
+    object_property_add_qapi(obj, "idr4", &uint32_type_info,
+                             aspeed_kcs_get_register_property,
+                             aspeed_kcs_set_register_property,
+                             NULL, NULL);
+    object_property_add_qapi(obj, "odr4", &uint32_type_info,
+                             aspeed_kcs_get_register_property,
+                             aspeed_kcs_set_register_property,
+                             NULL, NULL);
+    object_property_add_qapi(obj, "str4", &uint32_type_info,
+                             aspeed_kcs_get_register_property,
+                             aspeed_kcs_set_register_property,
+                             NULL, NULL);
 }
 
 static const VMStateDescription vmstate_aspeed_lpc = {
diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
index 59b4a9a4264..4f4331ec7e4 100644
--- a/hw/misc/aspeed_sdmc.c
+++ b/hw/misc/aspeed_sdmc.c
@@ -15,6 +15,7 @@
 #include "hw/core/qdev-properties.h"
 #include "migration/vmstate.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "trace.h"
 #include "qemu/units.h"
 #include "qemu/cutils.h"
@@ -259,7 +260,7 @@ static void aspeed_sdmc_set_ram_size(Object *obj, Visitor *v, const char *name,
 
 static void aspeed_sdmc_initfn(Object *obj)
 {
-    object_property_add(obj, "ram-size", "int",
+    object_property_add_qapi(obj, "ram-size", &int_type_info,
                         aspeed_sdmc_get_ram_size, aspeed_sdmc_set_ram_size,
                         NULL, NULL);
 }
diff --git a/hw/misc/npcm7xx_mft.c b/hw/misc/npcm7xx_mft.c
index 742166c4e82..99e9e49788c 100644
--- a/hw/misc/npcm7xx_mft.c
+++ b/hw/misc/npcm7xx_mft.c
@@ -23,6 +23,7 @@
 #include "hw/core/registerfields.h"
 #include "migration/vmstate.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "qemu/bitops.h"
 #include "qemu/error-report.h"
@@ -491,7 +492,7 @@ static void npcm7xx_mft_init(Object *obj)
     s->clock_2 = qdev_init_clock_out(dev, "clock2");
 
     for (int i = 0; i < NPCM7XX_PWM_PER_MODULE; ++i) {
-        object_property_add(obj, "max_rpm[*]", "uint32",
+        object_property_add_qapi(obj, "max_rpm[*]", &uint32_type_info,
                             npcm7xx_mft_get_max_rpm,
                             npcm7xx_mft_set_max_rpm,
                             NULL, &s->max_rpm[i]);
diff --git a/hw/net/ne2000-isa.c b/hw/net/ne2000-isa.c
index 673c785abc9..63e0d40ee72 100644
--- a/hw/net/ne2000-isa.c
+++ b/hw/net/ne2000-isa.c
@@ -29,6 +29,7 @@
 #include "ne2000.h"
 #include "system/system.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "qemu/module.h"
 #include "qom/object.h"
@@ -131,7 +132,7 @@ out:
 
 static void isa_ne2000_instance_init(Object *obj)
 {
-    object_property_add(obj, "bootindex", "int32",
+    object_property_add_qapi(obj, "bootindex", &int32_type_info,
                         isa_ne2000_get_bootindex,
                         isa_ne2000_set_bootindex, NULL, NULL);
     object_property_set_int(obj, "bootindex", -1, NULL);
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index be6c7028cb5..b10b45f157e 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -200,6 +200,7 @@
 #include "qemu/units.h"
 #include "qemu/range.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "system/system.h"
 #include "system/block-backend.h"
@@ -9536,7 +9537,7 @@ static void nvme_instance_init(Object *obj)
                                   "bootindex", "/namespace@1,0",
                                   DEVICE(obj));
 
-    object_property_add(obj, "smart_critical_warning", "uint8",
+    object_property_add_qapi(obj, "smart_critical_warning", &uint8_type_info,
                         nvme_get_smart_warning,
                         nvme_set_smart_warning, NULL, NULL);
 }
diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c
index 11623a5666f..f19dbe668aa 100644
--- a/hw/pci-bridge/pci_expander_bridge.c
+++ b/hw/pci-bridge/pci_expander_bridge.c
@@ -12,6 +12,7 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "hw/pci/pci.h"
 #include "hw/pci/pci_bus.h"
 #include "hw/pci/pci_host.h"
@@ -97,7 +98,7 @@ static void pxb_bus_class_init(ObjectClass *class, const void *data)
     pbc->bus_num = pxb_bus_num;
     pbc->numa_node = pxb_bus_numa_node;
 
-    object_class_property_add(class, "acpi_uid", "uint32",
+    object_class_property_add_qapi(class, "acpi_uid", &uint32_type_info,
                               prop_pxb_uid_get, NULL, NULL, NULL);
     object_class_property_set_description(class, "acpi_uid",
         "ACPI Unique ID used to distinguish this PCI Host Bridge / ACPI00016");
diff --git a/hw/pci-host/i440fx.c b/hw/pci-host/i440fx.c
index e7d638b296c..ada73d238ab 100644
--- a/hw/pci-host/i440fx.c
+++ b/hw/pci-host/i440fx.c
@@ -32,6 +32,7 @@
 #include "hw/core/qdev-properties.h"
 #include "hw/core/sysbus.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "migration/vmstate.h"
 #include "qapi/visitor.h"
 #include "qemu/error-report.h"
@@ -376,21 +377,25 @@ static void i440fx_pcihost_class_init(ObjectClass *klass, const void *data)
     /* Reason: needs to be wired up by pc_init1 */
     dc->user_creatable = false;
 
-    object_class_property_add(klass, PCI_HOST_PROP_PCI_HOLE_START, "uint32",
-                              i440fx_pcihost_get_pci_hole_start,
-                              NULL, NULL, NULL);
-
-    object_class_property_add(klass, PCI_HOST_PROP_PCI_HOLE_END, "uint32",
-                              i440fx_pcihost_get_pci_hole_end,
-                              NULL, NULL, NULL);
-
-    object_class_property_add(klass, PCI_HOST_PROP_PCI_HOLE64_START, "uint64",
-                              i440fx_pcihost_get_pci_hole64_start,
-                              NULL, NULL, NULL);
-
-    object_class_property_add(klass, PCI_HOST_PROP_PCI_HOLE64_END, "uint64",
-                              i440fx_pcihost_get_pci_hole64_end,
-                              NULL, NULL, NULL);
+    object_class_property_add_qapi(klass, PCI_HOST_PROP_PCI_HOLE_START,
+                                   &uint32_type_info,
+                                   i440fx_pcihost_get_pci_hole_start,
+                                   NULL, NULL, NULL);
+
+    object_class_property_add_qapi(klass, PCI_HOST_PROP_PCI_HOLE_END,
+                                   &uint32_type_info,
+                                   i440fx_pcihost_get_pci_hole_end,
+                                   NULL, NULL, NULL);
+
+    object_class_property_add_qapi(klass, PCI_HOST_PROP_PCI_HOLE64_START,
+                                   &uint64_type_info,
+                                   i440fx_pcihost_get_pci_hole64_start,
+                                   NULL, NULL, NULL);
+
+    object_class_property_add_qapi(klass, PCI_HOST_PROP_PCI_HOLE64_END,
+                                   &uint64_type_info,
+                                   i440fx_pcihost_get_pci_hole64_end,
+                                   NULL, NULL, NULL);
 }
 
 static const TypeInfo i440fx_pcihost_info = {
diff --git a/hw/pci-host/pnv_phb3.c b/hw/pci-host/pnv_phb3.c
index d6ab5153374..9af3059900f 100644
--- a/hw/pci-host/pnv_phb3.c
+++ b/hw/pci-host/pnv_phb3.c
@@ -11,6 +11,7 @@
 #include "qemu/bswap.h"
 #include "qapi/visitor.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "hw/pci-host/pnv_phb3_regs.h"
 #include "hw/pci-host/pnv_phb.h"
 #include "hw/pci-host/pnv_phb3.h"
@@ -1154,12 +1155,12 @@ static void pnv_phb3_root_bus_class_init(ObjectClass *klass, const void *data)
 {
     BusClass *k = BUS_CLASS(klass);
 
-    object_class_property_add(klass, "phb-id", "int",
+    object_class_property_add_qapi(klass, "phb-id", &int_type_info,
                               pnv_phb3_root_bus_get_prop,
                               pnv_phb3_root_bus_set_prop,
                               NULL, NULL);
 
-    object_class_property_add(klass, "chip-id", "int",
+    object_class_property_add_qapi(klass, "chip-id", &int_type_info,
                               pnv_phb3_root_bus_get_prop,
                               pnv_phb3_root_bus_set_prop,
                               NULL, NULL);
diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c
index 396bc47817d..e301a54bab5 100644
--- a/hw/pci-host/pnv_phb4.c
+++ b/hw/pci-host/pnv_phb4.c
@@ -11,6 +11,7 @@
 #include "qemu/bswap.h"
 #include "qapi/visitor.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "target/ppc/cpu.h"
 #include "hw/pci-host/pnv_phb4_regs.h"
 #include "hw/pci-host/pnv_phb4.h"
@@ -1766,12 +1767,12 @@ static void pnv_phb4_root_bus_class_init(ObjectClass *klass, const void *data)
 {
     BusClass *k = BUS_CLASS(klass);
 
-    object_class_property_add(klass, "phb-id", "int",
+    object_class_property_add_qapi(klass, "phb-id", &int_type_info,
                               pnv_phb4_root_bus_get_prop,
                               pnv_phb4_root_bus_set_prop,
                               NULL, NULL);
 
-    object_class_property_add(klass, "chip-id", "int",
+    object_class_property_add_qapi(klass, "chip-id", &int_type_info,
                               pnv_phb4_root_bus_get_prop,
                               pnv_phb4_root_bus_set_prop,
                               NULL, NULL);
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index e85e4227b37..093049037cd 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -35,6 +35,7 @@
 #include "hw/core/qdev-properties.h"
 #include "migration/vmstate.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "qemu/module.h"
 
@@ -215,19 +216,19 @@ static void q35_host_initfn(Object *obj)
     qdev_prop_set_uint64(DEVICE(s), PCI_HOST_PROP_PCI_HOLE64_SIZE,
                          Q35_PCI_HOST_HOLE64_SIZE_DEFAULT);
 
-    object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "uint32",
+    object_property_add_qapi(obj, PCI_HOST_PROP_PCI_HOLE_START, &uint32_type_info,
                         q35_host_get_pci_hole_start,
                         NULL, NULL, NULL);
 
-    object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_END, "uint32",
+    object_property_add_qapi(obj, PCI_HOST_PROP_PCI_HOLE_END, &uint32_type_info,
                         q35_host_get_pci_hole_end,
                         NULL, NULL, NULL);
 
-    object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_START, "uint64",
+    object_property_add_qapi(obj, PCI_HOST_PROP_PCI_HOLE64_START, &uint64_type_info,
                         q35_host_get_pci_hole64_start,
                         NULL, NULL, NULL);
 
-    object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_END, "uint64",
+    object_property_add_qapi(obj, PCI_HOST_PROP_PCI_HOLE64_END, &uint64_type_info,
                         q35_host_get_pci_hole64_end,
                         NULL, NULL, NULL);
 
diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index 9bc65c760ea..62baf38a00e 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -12,6 +12,7 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qobject/qnull.h"
 #include "qemu/cutils.h"
 #include "hw/ppc/spapr_drc.h"
@@ -583,7 +584,7 @@ static void spapr_dr_connector_instance_init(Object *obj)
     SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
 
     object_property_add_uint32_ptr(obj, "id", &drc->id, OBJ_PROP_FLAG_READ);
-    object_property_add(obj, "index", "uint32", prop_get_index,
+    object_property_add_qapi(obj, "index", &uint32_type_info, prop_get_index,
                         NULL, NULL, NULL);
     object_property_add(obj, "fdt", "struct", prop_get_fdt,
                         NULL, NULL, NULL);
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
index 743f31f0057..7bfa0d4a47a 100644
--- a/hw/riscv/microchip_pfsoc.c
+++ b/hw/riscv/microchip_pfsoc.c
@@ -39,6 +39,7 @@
 #include "qemu/units.h"
 #include "qemu/cutils.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "hw/core/boards.h"
 #include "hw/core/loader.h"
@@ -737,7 +738,7 @@ static void microchip_icicle_kit_machine_class_init(ObjectClass *oc,
      */
     mc->default_ram_size = 1537 * MiB;
 
-    object_class_property_add(oc, "clint-timebase-frequency", "uint32_t",
+    object_class_property_add_qapi(oc, "clint-timebase-frequency", &uint32_type_info,
                               microchip_icicle_kit_get_clint_timebase_freq,
                               microchip_icicle_kit_set_clint_timebase_freq,
                               NULL, NULL);
diff --git a/hw/s390x/sclpcpi.c b/hw/s390x/sclpcpi.c
index 68fc1b809bf..307eba9f765 100644
--- a/hw/s390x/sclpcpi.c
+++ b/hw/s390x/sclpcpi.c
@@ -53,6 +53,7 @@
 #include "qemu/timer.h"
 #include "hw/s390x/event-facility.h"
 #include "hw/s390x/ebcdic.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/qapi-visit-machine.h"
 #include "qapi/qapi-events-machine-s390x.h"
 #include "migration/vmstate.h"
@@ -190,12 +191,13 @@ static void cpi_class_init(ObjectClass *klass, const void *data)
             "name of the cluster which the VM belongs to, if any"
             " e.g. \"PLEX    \"");
 
-    object_class_property_add(klass, "system_level", "uint64", get_system_level,
-                              NULL, NULL, NULL);
+    object_class_property_add_qapi(klass, "system_level",
+                                   &uint64_type_info, get_system_level,
+                                   NULL, NULL, NULL);
     object_class_property_set_description(klass, "system_level",
             "distribution and kernel version in Linux e.g. 74872343805430528");
 
-    object_class_property_add(klass, "timestamp", "uint64", get_timestamp,
+    object_class_property_add_qapi(klass, "timestamp", &uint64_type_info, get_timestamp,
                               NULL, NULL, NULL);
     object_class_property_set_description(klass, "timestamp",
             "latest update of CPI data in nanoseconds since the UNIX EPOCH");
diff --git a/hw/s390x/virtio-ccw-mem.c b/hw/s390x/virtio-ccw-mem.c
index dea30aacfb3..046dfd544cf 100644
--- a/hw/s390x/virtio-ccw-mem.c
+++ b/hw/s390x/virtio-ccw-mem.c
@@ -13,6 +13,7 @@
 #include "qemu/osdep.h"
 #include "hw/core/qdev-properties.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qemu/module.h"
 #include "virtio-ccw-mem.h"
 #include "hw/mem/memory-device.h"
@@ -205,7 +206,7 @@ static void virtio_ccw_mem_instance_init(Object *obj)
                               OBJECT(&dev->vdev), VIRTIO_MEM_BLOCK_SIZE_PROP);
     object_property_add_alias(obj, VIRTIO_MEM_SIZE_PROP, OBJECT(&dev->vdev),
                               VIRTIO_MEM_SIZE_PROP);
-    object_property_add(obj, VIRTIO_MEM_REQUESTED_SIZE_PROP, "size",
+    object_property_add_qapi(obj, VIRTIO_MEM_REQUESTED_SIZE_PROP, &size_type_info,
                         virtio_ccw_mem_get_requested_size,
                         virtio_ccw_mem_set_requested_size, NULL, NULL);
 }
diff --git a/hw/sensor/adm1266.c b/hw/sensor/adm1266.c
index 37d1cffd57a..62f563af7a7 100644
--- a/hw/sensor/adm1266.c
+++ b/hw/sensor/adm1266.c
@@ -14,6 +14,7 @@
 #include "hw/core/irq.h"
 #include "migration/vmstate.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
@@ -217,7 +218,7 @@ static void adm1266_init(Object *obj)
     for (int i = 0; i < ADM1266_NUM_PAGES; i++) {
         pmbus_page_config(pmdev, i, flags);
 
-        object_property_add(obj, "vout[*]", "uint16",
+        object_property_add_qapi(obj, "vout[*]", &uint16_type_info,
                             adm1266_get,
                             adm1266_set, NULL, &pmdev->pages[i].read_vout);
     }
diff --git a/hw/sensor/adm1272.c b/hw/sensor/adm1272.c
index 0aa2a865568..e1c1bf1c54d 100644
--- a/hw/sensor/adm1272.c
+++ b/hw/sensor/adm1272.c
@@ -12,6 +12,7 @@
 #include "hw/core/irq.h"
 #include "migration/vmstate.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
@@ -493,19 +494,19 @@ static void adm1272_init(Object *obj)
 
     pmbus_page_config(pmdev, 0, flags);
 
-    object_property_add(obj, "vin", "uint16",
+    object_property_add_qapi(obj, "vin", &uint16_type_info,
                         adm1272_get,
                         adm1272_set, NULL, &pmdev->pages[0].read_vin);
 
-    object_property_add(obj, "vout", "uint16",
+    object_property_add_qapi(obj, "vout", &uint16_type_info,
                         adm1272_get,
                         adm1272_set, NULL, &pmdev->pages[0].read_vout);
 
-    object_property_add(obj, "iout", "uint16",
+    object_property_add_qapi(obj, "iout", &uint16_type_info,
                         adm1272_get,
                         adm1272_set, NULL, &pmdev->pages[0].read_iout);
 
-    object_property_add(obj, "pin", "uint16",
+    object_property_add_qapi(obj, "pin", &uint16_type_info,
                         adm1272_get,
                         adm1272_set, NULL, &pmdev->pages[0].read_pin);
 
diff --git a/hw/sensor/emc141x.c b/hw/sensor/emc141x.c
index a51fc44395a..5efe94643ca 100644
--- a/hw/sensor/emc141x.c
+++ b/hw/sensor/emc141x.c
@@ -22,6 +22,7 @@
 #include "hw/i2c/i2c.h"
 #include "migration/vmstate.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "qemu/module.h"
 #include "qom/object.h"
@@ -251,16 +252,16 @@ static void emc141x_reset(DeviceState *dev)
 
 static void emc141x_initfn(Object *obj)
 {
-    object_property_add(obj, "temperature0", "int",
+    object_property_add_qapi(obj, "temperature0", &int_type_info,
                         emc141x_get_temperature,
                         emc141x_set_temperature, NULL, NULL);
-    object_property_add(obj, "temperature1", "int",
+    object_property_add_qapi(obj, "temperature1", &int_type_info,
                         emc141x_get_temperature,
                         emc141x_set_temperature, NULL, NULL);
-    object_property_add(obj, "temperature2", "int",
+    object_property_add_qapi(obj, "temperature2", &int_type_info,
                         emc141x_get_temperature,
                         emc141x_set_temperature, NULL, NULL);
-    object_property_add(obj, "temperature3", "int",
+    object_property_add_qapi(obj, "temperature3", &int_type_info,
                         emc141x_get_temperature,
                         emc141x_set_temperature, NULL, NULL);
 }
diff --git a/hw/sensor/isl_pmbus_vr.c b/hw/sensor/isl_pmbus_vr.c
index 0fad04def77..8923e9e8751 100644
--- a/hw/sensor/isl_pmbus_vr.c
+++ b/hw/sensor/isl_pmbus_vr.c
@@ -9,6 +9,7 @@
 #include "qemu/osdep.h"
 #include "hw/sensor/isl_pmbus_vr.h"
 #include "hw/core/qdev-properties.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
@@ -136,63 +137,63 @@ static void isl_pmbus_vr_add_props(Object *obj, uint64_t *flags, uint8_t pages)
     PMBusDevice *pmdev = PMBUS_DEVICE(obj);
     for (int i = 0; i < pages; i++) {
         if (flags[i] & PB_HAS_VIN) {
-            object_property_add(obj, "vin[*]", "uint16",
+            object_property_add_qapi(obj, "vin[*]", &uint16_type_info,
                                 isl_pmbus_vr_get,
                                 isl_pmbus_vr_set,
                                 NULL, &pmdev->pages[i].read_vin);
         }
 
         if (flags[i] & PB_HAS_VOUT) {
-            object_property_add(obj, "vout[*]", "uint16",
+            object_property_add_qapi(obj, "vout[*]", &uint16_type_info,
                                 isl_pmbus_vr_get,
                                 isl_pmbus_vr_set,
                                 NULL, &pmdev->pages[i].read_vout);
         }
 
         if (flags[i] & PB_HAS_IIN) {
-            object_property_add(obj, "iin[*]", "uint16",
+            object_property_add_qapi(obj, "iin[*]", &uint16_type_info,
                                 isl_pmbus_vr_get,
                                 isl_pmbus_vr_set,
                                 NULL, &pmdev->pages[i].read_iin);
         }
 
         if (flags[i] & PB_HAS_IOUT) {
-            object_property_add(obj, "iout[*]", "uint16",
+            object_property_add_qapi(obj, "iout[*]", &uint16_type_info,
                                 isl_pmbus_vr_get,
                                 isl_pmbus_vr_set,
                                 NULL, &pmdev->pages[i].read_iout);
         }
 
         if (flags[i] & PB_HAS_PIN) {
-            object_property_add(obj, "pin[*]", "uint16",
+            object_property_add_qapi(obj, "pin[*]", &uint16_type_info,
                                 isl_pmbus_vr_get,
                                 isl_pmbus_vr_set,
                                 NULL, &pmdev->pages[i].read_pin);
         }
 
         if (flags[i] & PB_HAS_POUT) {
-            object_property_add(obj, "pout[*]", "uint16",
+            object_property_add_qapi(obj, "pout[*]", &uint16_type_info,
                                 isl_pmbus_vr_get,
                                 isl_pmbus_vr_set,
                                 NULL, &pmdev->pages[i].read_pout);
         }
 
         if (flags[i] & PB_HAS_TEMPERATURE) {
-            object_property_add(obj, "temp1[*]", "uint16",
+            object_property_add_qapi(obj, "temp1[*]", &uint16_type_info,
                                 isl_pmbus_vr_get,
                                 isl_pmbus_vr_set,
                                 NULL, &pmdev->pages[i].read_temperature_1);
         }
 
         if (flags[i] & PB_HAS_TEMP2) {
-            object_property_add(obj, "temp2[*]", "uint16",
+            object_property_add_qapi(obj, "temp2[*]", &uint16_type_info,
                                 isl_pmbus_vr_get,
                                 isl_pmbus_vr_set,
                                 NULL, &pmdev->pages[i].read_temperature_2);
         }
 
         if (flags[i] & PB_HAS_TEMP3) {
-            object_property_add(obj, "temp3[*]", "uint16",
+            object_property_add_qapi(obj, "temp3[*]", &uint16_type_info,
                                 isl_pmbus_vr_get,
                                 isl_pmbus_vr_set,
                                 NULL, &pmdev->pages[i].read_temperature_3);
diff --git a/hw/sensor/lsm303dlhc_mag.c b/hw/sensor/lsm303dlhc_mag.c
index cd5773ae64e..c8085739ca4 100644
--- a/hw/sensor/lsm303dlhc_mag.c
+++ b/hw/sensor/lsm303dlhc_mag.c
@@ -25,6 +25,7 @@
 #include "hw/i2c/i2c.h"
 #include "migration/vmstate.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "qemu/module.h"
 #include "qemu/log.h"
@@ -509,19 +510,19 @@ static void lsm303dlhc_mag_reset(DeviceState *dev)
  */
 static void lsm303dlhc_mag_initfn(Object *obj)
 {
-    object_property_add(obj, "mag-x", "int",
+    object_property_add_qapi(obj, "mag-x", &int_type_info,
                 lsm303dlhc_mag_get_x,
                 lsm303dlhc_mag_set_x, NULL, NULL);
 
-    object_property_add(obj, "mag-y", "int",
+    object_property_add_qapi(obj, "mag-y", &int_type_info,
                 lsm303dlhc_mag_get_y,
                 lsm303dlhc_mag_set_y, NULL, NULL);
 
-    object_property_add(obj, "mag-z", "int",
+    object_property_add_qapi(obj, "mag-z", &int_type_info,
                 lsm303dlhc_mag_get_z,
                 lsm303dlhc_mag_set_z, NULL, NULL);
 
-    object_property_add(obj, "temperature", "int",
+    object_property_add_qapi(obj, "temperature", &int_type_info,
                 lsm303dlhc_mag_get_temperature,
                 lsm303dlhc_mag_set_temperature, NULL, NULL);
 }
diff --git a/hw/sensor/max34451.c b/hw/sensor/max34451.c
index 4d64434f3af..3c8fa3d4a86 100644
--- a/hw/sensor/max34451.c
+++ b/hw/sensor/max34451.c
@@ -11,6 +11,7 @@
 #include "hw/core/irq.h"
 #include "migration/vmstate.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
@@ -727,7 +728,7 @@ static void max34451_init(Object *obj)
 
     /* get and set the voltage in millivolts, max is 32767 mV */
     for (int i = 0; i < MAX34451_NUM_PWR_DEVICES; i++) {
-        object_property_add(obj, "vout[*]", "uint16",
+        object_property_add_qapi(obj, "vout[*]", &uint16_type_info,
                             max34451_get,
                             max34451_set, NULL, &pmdev->pages[i].read_vout);
     }
@@ -737,7 +738,7 @@ static void max34451_init(Object *obj)
      * centidegrees Celsius i.e.: 2500 -> 25.00 C, max is 327.67 C
      */
     for (int i = 0; i < MAX34451_NUM_TEMP_DEVICES; i++) {
-        object_property_add(obj, "temperature[*]", "uint16",
+        object_property_add_qapi(obj, "temperature[*]", &uint16_type_info,
                             max34451_get,
                             max34451_set,
                             NULL,
diff --git a/hw/sensor/tmp105.c b/hw/sensor/tmp105.c
index c5089d74f4b..ce4ff4856af 100644
--- a/hw/sensor/tmp105.c
+++ b/hw/sensor/tmp105.c
@@ -24,6 +24,7 @@
 #include "migration/vmstate.h"
 #include "hw/sensor/tmp105.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "qemu/module.h"
 #include "hw/core/registerfields.h"
@@ -308,7 +309,7 @@ static void tmp105_realize(DeviceState *dev, Error **errp)
 
 static void tmp105_initfn(Object *obj)
 {
-    object_property_add(obj, "temperature", "int",
+    object_property_add_qapi(obj, "temperature", &int_type_info,
                         tmp105_get_temperature,
                         tmp105_set_temperature, NULL, NULL);
 }
diff --git a/hw/sensor/tmp421.c b/hw/sensor/tmp421.c
index 127edd0ba56..60844e76b21 100644
--- a/hw/sensor/tmp421.c
+++ b/hw/sensor/tmp421.c
@@ -28,6 +28,7 @@
 #include "hw/i2c/i2c.h"
 #include "migration/vmstate.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "qemu/module.h"
 #include "qom/object.h"
@@ -350,16 +351,16 @@ static void tmp421_class_init(ObjectClass *klass, const void *data)
     dc->vmsd = &vmstate_tmp421;
     sc->dev = (DeviceInfo *) data;
 
-    object_class_property_add(klass, "temperature0", "int",
+    object_class_property_add_qapi(klass, "temperature0", &int_type_info,
                               tmp421_get_temperature,
                               tmp421_set_temperature, NULL, NULL);
-    object_class_property_add(klass, "temperature1", "int",
+    object_class_property_add_qapi(klass, "temperature1", &int_type_info,
                               tmp421_get_temperature,
                               tmp421_set_temperature, NULL, NULL);
-    object_class_property_add(klass, "temperature2", "int",
+    object_class_property_add_qapi(klass, "temperature2", &int_type_info,
                               tmp421_get_temperature,
                               tmp421_set_temperature, NULL, NULL);
-    object_class_property_add(klass, "temperature3", "int",
+    object_class_property_add_qapi(klass, "temperature3", &int_type_info,
                               tmp421_get_temperature,
                               tmp421_set_temperature, NULL, NULL);
 }
diff --git a/hw/usb/dev-storage-classic.c b/hw/usb/dev-storage-classic.c
index 977151c4a08..06584092bca 100644
--- a/hw/usb/dev-storage-classic.c
+++ b/hw/usb/dev-storage-classic.c
@@ -9,6 +9,7 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "hw/usb/usb.h"
 #include "hw/usb/desc.h"
@@ -122,7 +123,7 @@ out:
 
 static void usb_msd_instance_init(Object *obj)
 {
-    object_property_add(obj, "bootindex", "int32",
+    object_property_add_qapi(obj, "bootindex", &int32_type_info,
                         usb_msd_get_bootindex,
                         usb_msd_set_bootindex, NULL, NULL);
     object_property_set_int(obj, "bootindex", -1, NULL);
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index 4c5f486ba23..9e43948128f 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -27,6 +27,7 @@
 #include "hw/virtio/virtio-balloon.h"
 #include "system/address-spaces.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/qapi-events-machine.h"
 #include "qapi/visitor.h"
 #include "trace.h"
@@ -1022,7 +1023,7 @@ static void virtio_balloon_instance_init(Object *obj)
     object_property_add(obj, "guest-stats", "guest statistics",
                         balloon_stats_get_all, NULL, NULL, NULL);
 
-    object_property_add(obj, "guest-stats-polling-interval", "int",
+    object_property_add_qapi(obj, "guest-stats-polling-interval", &int_type_info,
                         balloon_stats_get_poll_interval,
                         balloon_stats_set_poll_interval,
                         NULL, NULL);
diff --git a/hw/virtio/virtio-mem-pci.c b/hw/virtio/virtio-mem-pci.c
index f592eb1a784..80e9bfedd9f 100644
--- a/hw/virtio/virtio-mem-pci.c
+++ b/hw/virtio/virtio-mem-pci.c
@@ -14,6 +14,7 @@
 #include "virtio-mem-pci.h"
 #include "hw/mem/memory-device.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/qapi-events-machine.h"
 #include "qapi/qapi-events-misc.h"
 
@@ -211,7 +212,7 @@ static void virtio_mem_pci_instance_init(Object *obj)
                               OBJECT(&dev->vdev), VIRTIO_MEM_BLOCK_SIZE_PROP);
     object_property_add_alias(obj, VIRTIO_MEM_SIZE_PROP, OBJECT(&dev->vdev),
                               VIRTIO_MEM_SIZE_PROP);
-    object_property_add(obj, VIRTIO_MEM_REQUESTED_SIZE_PROP, "size",
+    object_property_add_qapi(obj, VIRTIO_MEM_REQUESTED_SIZE_PROP, &size_type_info,
                         virtio_mem_pci_get_requested_size,
                         virtio_mem_pci_set_requested_size, NULL, NULL);
 }
diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
index a4b71974a1c..8cdaab50505 100644
--- a/hw/virtio/virtio-mem.c
+++ b/hw/virtio/virtio-mem.c
@@ -25,6 +25,7 @@
 #include "hw/virtio/virtio-bus.h"
 #include "hw/virtio/virtio-mem.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "migration/misc.h"
 #include "hw/core/boards.h"
@@ -1652,14 +1653,15 @@ static void virtio_mem_instance_init(Object *obj)
     notifier_list_init(&vmem->size_change_notifiers);
     QLIST_INIT(&vmem->rdl_list);
 
-    object_property_add(obj, VIRTIO_MEM_SIZE_PROP, "size", virtio_mem_get_size,
-                        NULL, NULL, NULL);
-    object_property_add(obj, VIRTIO_MEM_REQUESTED_SIZE_PROP, "size",
-                        virtio_mem_get_requested_size,
-                        virtio_mem_set_requested_size, NULL, NULL);
-    object_property_add(obj, VIRTIO_MEM_BLOCK_SIZE_PROP, "size",
-                        virtio_mem_get_block_size, virtio_mem_set_block_size,
-                        NULL, NULL);
+    object_property_add_qapi(obj, VIRTIO_MEM_SIZE_PROP, &size_type_info,
+                             virtio_mem_get_size,
+                             NULL, NULL, NULL);
+    object_property_add_qapi(obj, VIRTIO_MEM_REQUESTED_SIZE_PROP, &size_type_info,
+                             virtio_mem_get_requested_size,
+                             virtio_mem_set_requested_size, NULL, NULL);
+    object_property_add_qapi(obj, VIRTIO_MEM_BLOCK_SIZE_PROP, &size_type_info,
+                             virtio_mem_get_block_size, virtio_mem_set_block_size,
+                             NULL, NULL);
 }
 
 static void virtio_mem_instance_finalize(Object *obj)
diff --git a/hw/xen/xen-pvh-common.c b/hw/xen/xen-pvh-common.c
index cca37202ffb..7b4fd933a8f 100644
--- a/hw/xen/xen-pvh-common.c
+++ b/hw/xen/xen-pvh-common.c
@@ -9,6 +9,7 @@
 #include "qemu/osdep.h"
 #include "qemu/error-report.h"
 #include "qemu/units.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "hw/core/boards.h"
 #include "hw/core/irq.h"
@@ -413,7 +414,7 @@ void xen_pvh_class_setup_common_props(XenPVHMachineClass *xpc)
 
 #define OC_MEMMAP_PROP_BASE(c, prop_name, name)                           \
 do {                                                                      \
-    object_class_property_add(c, prop_name "-base", "uint64_t",           \
+    object_class_property_add_qapi(c, prop_name "-base", &uint64_type_info,\
                               xen_pvh_get_ ## name ## _base,              \
                               xen_pvh_set_ ## name ## _base, NULL, NULL); \
     object_class_property_set_description(oc, prop_name "-base",          \
@@ -422,7 +423,7 @@ do {                                                                      \
 
 #define OC_MEMMAP_PROP_SIZE(c, prop_name, name)                           \
 do {                                                                      \
-    object_class_property_add(c, prop_name "-size", "uint64_t",           \
+    object_class_property_add_qapi(c, prop_name "-size", &size_type_info, \
                               xen_pvh_get_ ## name ## _size,              \
                               xen_pvh_set_ ## name ## _size, NULL, NULL); \
     object_class_property_set_description(oc, prop_name "-size",          \
@@ -458,7 +459,7 @@ do {                                                                      \
         OC_MEMMAP_PROP(oc, "pci-mmio", pci_mmio);
         OC_MEMMAP_PROP(oc, "pci-mmio-high", pci_mmio_high);
 
-        object_class_property_add(oc, "pci-intx-irq-base", "uint32_t",
+        object_class_property_add_qapi(oc, "pci-intx-irq-base", &uint32_type_info,
                                   xen_pvh_get_pci_intx_irq_base,
                                   xen_pvh_set_pci_intx_irq_base,
                                   NULL, NULL);
@@ -468,7 +469,7 @@ do {                                                                      \
 
 #ifdef CONFIG_TPM
     if (xpc->has_tpm) {
-        object_class_property_add(oc, "tpm-base-addr", "uint64_t",
+        object_class_property_add_qapi(oc, "tpm-base-addr", &uint64_type_info,
                                   xen_pvh_get_tpm_base,
                                   xen_pvh_set_tpm_base,
                                   NULL, NULL);
diff --git a/iothread.c b/iothread.c
index 3558535b40f..21fd5a91c5e 100644
--- a/iothread.c
+++ b/iothread.c
@@ -20,6 +20,7 @@
 #include "system/event-loop-base.h"
 #include "system/iothread.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/qapi-commands-misc.h"
 #include "qemu/error-report.h"
 #include "qemu/rcu.h"
@@ -315,19 +316,19 @@ static void iothread_class_init(ObjectClass *klass, const void *class_data)
     bc->init = iothread_init;
     bc->update_params = iothread_set_aio_context_params;
 
-    object_class_property_add(klass, "poll-max-ns", "int",
+    object_class_property_add_qapi(klass, "poll-max-ns", &int_type_info,
                               iothread_get_poll_param,
                               iothread_set_poll_param,
                               NULL, &poll_max_ns_info);
-    object_class_property_add(klass, "poll-grow", "int",
+    object_class_property_add_qapi(klass, "poll-grow", &int_type_info,
                               iothread_get_poll_param,
                               iothread_set_poll_param,
                               NULL, &poll_grow_info);
-    object_class_property_add(klass, "poll-shrink", "int",
+    object_class_property_add_qapi(klass, "poll-shrink", &int_type_info,
                               iothread_get_poll_param,
                               iothread_set_poll_param,
                               NULL, &poll_shrink_info);
-    object_class_property_add(klass, "poll-weight", "int",
+    object_class_property_add_qapi(klass, "poll-weight", &int_type_info,
                               iothread_get_poll_param,
                               iothread_set_poll_param,
                               NULL, &poll_weight_info);
diff --git a/net/colo-compare.c b/net/colo-compare.c
index abc1326b704..27d1499d4b4 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -16,6 +16,7 @@
 #include "qemu/error-report.h"
 #include "trace.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "net/net.h"
 #include "net/eth.h"
 #include "qom/object_interfaces.h"
@@ -1377,15 +1378,15 @@ static void colo_compare_init(Object *obj)
     object_property_add_str(obj, "notify_dev",
                             compare_get_notify_dev, compare_set_notify_dev);
 
-    object_property_add(obj, "compare_timeout", "uint64",
+    object_property_add_qapi(obj, "compare_timeout", &uint64_type_info,
                         compare_get_timeout,
                         compare_set_timeout, NULL, NULL);
 
-    object_property_add(obj, "expired_scan_cycle", "uint32",
+    object_property_add_qapi(obj, "expired_scan_cycle", &uint32_type_info,
                         compare_get_expired_scan_cycle,
                         compare_set_expired_scan_cycle, NULL, NULL);
 
-    object_property_add(obj, "max_queue_size", "uint32",
+    object_property_add_qapi(obj, "max_queue_size", &uint32_type_info,
                         get_max_queue_size,
                         set_max_queue_size, NULL, NULL);
 
diff --git a/net/dump.c b/net/dump.c
index 0c39f09892c..3d7bb36182e 100644
--- a/net/dump.c
+++ b/net/dump.c
@@ -25,6 +25,7 @@
 #include "qemu/osdep.h"
 #include "clients.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qemu/error-report.h"
 #include "qemu/iov.h"
 #include "qemu/module.h"
@@ -238,8 +239,9 @@ static void filter_dump_class_init(ObjectClass *oc, const void *data)
 {
     NetFilterClass *nfc = NETFILTER_CLASS(oc);
 
-    object_class_property_add(oc, "maxlen", "uint32", filter_dump_get_maxlen,
-                              filter_dump_set_maxlen, NULL, NULL);
+    object_class_property_add_qapi(oc, "maxlen", &uint32_type_info,
+                                   filter_dump_get_maxlen,
+                                   filter_dump_set_maxlen, NULL, NULL);
     object_class_property_add_str(oc, "file", file_dump_get_filename,
                                   file_dump_set_filename);
 
diff --git a/net/filter-buffer.c b/net/filter-buffer.c
index 427da24097f..9d7a9f5cb2c 100644
--- a/net/filter-buffer.c
+++ b/net/filter-buffer.c
@@ -10,6 +10,7 @@
 #include "net/filter.h"
 #include "net/queue.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qemu/timer.h"
 #include "qemu/iov.h"
 #include "qapi/qapi-builtin-visit.h"
@@ -182,7 +183,7 @@ static void filter_buffer_class_init(ObjectClass *oc, const void *data)
 {
     NetFilterClass *nfc = NETFILTER_CLASS(oc);
 
-    object_class_property_add(oc, "interval", "uint32",
+    object_class_property_add_qapi(oc, "interval", &uint32_type_info,
                               filter_buffer_get_interval,
                               filter_buffer_set_interval, NULL, NULL);
 
diff --git a/qom/object.c b/qom/object.c
index 48d7a88ee43..7f4d301cd86 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -22,9 +22,9 @@
 #include "qapi/string-output-visitor.h"
 #include "qapi/qobject-input-visitor.h"
 #include "qapi/forward-visitor.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/qapi-builtin-visit.h"
 #include "qapi/qapi-type-info.h"
-#include "qobject/qjson.h"
 #include "trace.h"
 
 /* TODO: replace QObject with a simpler visitor to avoid a dependency
@@ -2258,7 +2258,7 @@ object_property_add_str(Object *obj, const char *name,
     prop->get = get;
     prop->set = set;
 
-    return object_property_add(obj, name, "string",
+    return object_property_add_qapi(obj, name, &str_type_info,
                                get ? property_get_str : NULL,
                                set ? property_set_str : NULL,
                                property_release_data,
@@ -2276,7 +2276,7 @@ object_class_property_add_str(ObjectClass *klass, const char *name,
     prop->get = get;
     prop->set = set;
 
-    return object_class_property_add(klass, name, "string",
+    return object_class_property_add_qapi(klass, name, &str_type_info,
                                      get ? property_get_str : NULL,
                                      set ? property_set_str : NULL,
                                      NULL,
@@ -2328,7 +2328,7 @@ object_property_add_bool(Object *obj, const char *name,
     prop->get = get;
     prop->set = set;
 
-    return object_property_add(obj, name, "bool",
+    return object_property_add_qapi(obj, name, &bool_type_info,
                                get ? property_get_bool : NULL,
                                set ? property_set_bool : NULL,
                                property_release_data,
@@ -2345,7 +2345,7 @@ object_class_property_add_bool(ObjectClass *klass, const char *name,
     prop->get = get;
     prop->set = set;
 
-    return object_class_property_add(klass, name, "bool",
+    return object_class_property_add_qapi(klass, name, &bool_type_info,
                                      get ? property_get_bool : NULL,
                                      set ? property_set_bool : NULL,
                                      NULL,
@@ -2634,8 +2634,8 @@ object_property_add_uint8_ptr(Object *obj, const char *name,
         setter = property_set_uint8_ptr;
     }
 
-    return object_property_add(obj, name, "uint8",
-                               getter, setter, NULL, (void *)v);
+    return object_property_add_qapi(obj, name, &uint8_type_info,
+                                    getter, setter, NULL, (void *)v);
 }
 
 ObjectProperty *
@@ -2654,8 +2654,8 @@ object_class_property_add_uint8_ptr(ObjectClass *klass, const char *name,
         setter = property_set_uint8_ptr;
     }
 
-    return object_class_property_add(klass, name, "uint8",
-                                     getter, setter, NULL, (void *)v);
+    return object_class_property_add_qapi(klass, name, &uint8_type_info,
+                                          getter, setter, NULL, (void *)v);
 }
 
 ObjectProperty *
@@ -2674,8 +2674,8 @@ object_property_add_uint16_ptr(Object *obj, const char *name,
         setter = property_set_uint16_ptr;
     }
 
-    return object_property_add(obj, name, "uint16",
-                               getter, setter, NULL, (void *)v);
+    return object_property_add_qapi(obj, name, &uint16_type_info,
+                                    getter, setter, NULL, (void *)v);
 }
 
 ObjectProperty *
@@ -2694,8 +2694,8 @@ object_class_property_add_uint16_ptr(ObjectClass *klass, const char *name,
         setter = property_set_uint16_ptr;
     }
 
-    return object_class_property_add(klass, name, "uint16",
-                                     getter, setter, NULL, (void *)v);
+    return object_class_property_add_qapi(klass, name, &uint16_type_info,
+                                          getter, setter, NULL, (void *)v);
 }
 
 ObjectProperty *
@@ -2714,8 +2714,8 @@ object_property_add_uint32_ptr(Object *obj, const char *name,
         setter = property_set_uint32_ptr;
     }
 
-    return object_property_add(obj, name, "uint32",
-                               getter, setter, NULL, (void *)v);
+    return object_property_add_qapi(obj, name, &uint32_type_info,
+                                    getter, setter, NULL, (void *)v);
 }
 
 ObjectProperty *
@@ -2734,8 +2734,8 @@ object_class_property_add_uint32_ptr(ObjectClass *klass, const char *name,
         setter = property_set_uint32_ptr;
     }
 
-    return object_class_property_add(klass, name, "uint32",
-                                     getter, setter, NULL, (void *)v);
+    return object_class_property_add_qapi(klass, name, &uint32_type_info,
+                                          getter, setter, NULL, (void *)v);
 }
 
 ObjectProperty *
@@ -2754,8 +2754,8 @@ object_property_add_uint64_ptr(Object *obj, const char *name,
         setter = property_set_uint64_ptr;
     }
 
-    return object_property_add(obj, name, "uint64",
-                               getter, setter, NULL, (void *)v);
+    return object_property_add_qapi(obj, name, &uint64_type_info,
+                                    getter, setter, NULL, (void *)v);
 }
 
 ObjectProperty *
@@ -2774,8 +2774,8 @@ object_class_property_add_uint64_ptr(ObjectClass *klass, const char *name,
         setter = property_set_uint64_ptr;
     }
 
-    return object_class_property_add(klass, name, "uint64",
-                                     getter, setter, NULL, (void *)v);
+    return object_class_property_add_qapi(klass, name, &uint64_type_info,
+                                          getter, setter, NULL, (void *)v);
 }
 
 typedef struct {
diff --git a/system/bootdevice.c b/system/bootdevice.c
index 9538b08983f..7789e464186 100644
--- a/system/bootdevice.c
+++ b/system/bootdevice.c
@@ -24,6 +24,7 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "system/system.h"
 #include "qapi/visitor.h"
 #include "qemu/error-report.h"
@@ -336,7 +337,7 @@ void device_add_bootindex_property(Object *obj, int32_t *bootindex,
     prop->suffix = suffix;
     prop->dev = dev;
 
-    object_property_add(obj, name, "int32",
+    object_property_add_qapi(obj, name, &int32_type_info,
                         device_get_bootindex,
                         device_set_bootindex,
                         property_release_bootindex,
diff --git a/system/memory.c b/system/memory.c
index aaf5ec40230..1f2d44ce8b4 100644
--- a/system/memory.c
+++ b/system/memory.c
@@ -16,6 +16,7 @@
 #include "qemu/osdep.h"
 #include "qemu/log.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "system/memory.h"
 #include "qapi/visitor.h"
 #include "qemu/bitops.h"
@@ -1316,11 +1317,11 @@ static void memory_region_initfn(Object *obj)
 
     object_property_add_uint64_ptr(OBJECT(mr), "addr",
                                    &mr->addr, OBJ_PROP_FLAG_READ);
-    object_property_add(OBJECT(mr), "priority", "int32",
+    object_property_add_qapi(OBJECT(mr), "priority", &int32_type_info,
                         memory_region_get_priority,
                         NULL, /* memory_region_set_priority */
                         NULL, NULL);
-    object_property_add(OBJECT(mr), "size", "uint64",
+    object_property_add_qapi(OBJECT(mr), "size", &uint64_type_info,
                         memory_region_get_size,
                         NULL, /* memory_region_set_size, */
                         NULL, NULL);
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index a93ad2da5ad..67baeed8a3b 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -20,6 +20,7 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "cpu.h"
 #include "cpregs.h"
 #include "qemu/module.h"
@@ -320,7 +321,7 @@ static void prop_bool_set_false(Object *obj, Visitor *v, const char *name,
 
 static void prop_add_stub_bool(Object *obj, const char *name)
 {
-    object_property_add(obj, name, "bool", prop_bool_get_false,
+    object_property_add_qapi(obj, name, &bool_type_info, prop_bool_get_false,
                         prop_bool_set_false, NULL, NULL);
 }
 
@@ -510,13 +511,13 @@ void aarch64_add_sve_properties(Object *obj)
     for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
         char name[8];
         snprintf(name, sizeof(name), "sve%d", vq * 128);
-        object_property_add(obj, name, "bool", cpu_arm_get_vq,
+        object_property_add_qapi(obj, name, &bool_type_info, cpu_arm_get_vq,
                             cpu_arm_set_vq, NULL, &cpu->sve_vq);
     }
 
 #ifdef CONFIG_USER_ONLY
     /* Mirror linux /proc/sys/abi/sve_default_vector_length. */
-    object_property_add(obj, "sve-default-vector-length", "int32",
+    object_property_add_qapi(obj, "sve-default-vector-length", &int32_type_info,
                         cpu_arm_get_default_vec_len,
                         cpu_arm_set_default_vec_len, NULL,
                         &cpu->sve_default_vq);
@@ -535,13 +536,13 @@ void aarch64_add_sme_properties(Object *obj)
     for (vq = 1; vq <= ARM_MAX_VQ; vq <<= 1) {
         char name[8];
         snprintf(name, sizeof(name), "sme%d", vq * 128);
-        object_property_add(obj, name, "bool", cpu_arm_get_vq,
+        object_property_add_qapi(obj, name, &bool_type_info, cpu_arm_get_vq,
                             cpu_arm_set_vq, NULL, &cpu->sme_vq);
     }
 
 #ifdef CONFIG_USER_ONLY
     /* Mirror linux /proc/sys/abi/sme_default_vector_length. */
-    object_property_add(obj, "sme-default-vector-length", "int32",
+    object_property_add_qapi(obj, "sme-default-vector-length", &int32_type_info,
                         cpu_arm_get_default_vec_len,
                         cpu_arm_set_default_vec_len, NULL,
                         &cpu->sme_default_vq);
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 7d194ea112b..0aeb9b91a5e 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -20,6 +20,7 @@
 #include "qemu/main-loop.h"
 #include "qom/object.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "system/system.h"
 #include "system/runstate.h"
 #include "system/ramblock.h"
@@ -1775,7 +1776,7 @@ static void kvm_arch_set_eager_split_size(Object *obj, Visitor *v,
 
 void kvm_arch_accel_class_init(ObjectClass *oc)
 {
-    object_class_property_add(oc, "eager-split-size", "size",
+    object_class_property_add_qapi(oc, "eager-split-size", &size_type_info,
                               kvm_arch_get_eager_split_size,
                               kvm_arch_set_eager_split_size, NULL, NULL);
 
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
index 649d854a65b..270d4ff1343 100644
--- a/target/arm/tcg/cpu64.c
+++ b/target/arm/tcg/cpu64.c
@@ -20,6 +20,7 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "cpu.h"
 #include "qemu/module.h"
 #include "qapi/visitor.h"
@@ -1401,10 +1402,10 @@ void aarch64_max_tcg_initfn(Object *obj)
     aarch64_add_pauth_properties(obj);
     aarch64_add_sve_properties(obj);
     aarch64_add_sme_properties(obj);
-    object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
+    object_property_add_qapi(obj, "sve-max-vq", &uint32_type_info, cpu_max_get_sve_max_vq,
                         cpu_max_set_sve_max_vq, NULL, NULL);
     object_property_add_bool(obj, "x-rme", cpu_arm_get_rme, cpu_arm_set_rme);
-    object_property_add(obj, "x-l0gptsz", "uint32", cpu_max_get_l0gptsz,
+    object_property_add_qapi(obj, "x-l0gptsz", &uint32_type_info, cpu_max_get_l0gptsz,
                         cpu_max_set_l0gptsz, NULL, NULL);
     qdev_property_add_static(DEVICE(obj), &arm_cpu_lpa2_property);
 }
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index a98bcc218ba..e902d0e6d3f 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -10423,7 +10423,7 @@ static void x86_cpu_register_bit_prop(X86CPUClass *xcc,
         fp = g_new0(BitProperty, 1);
         fp->w = w;
         fp->mask = mask;
-        object_class_property_add(oc, prop_name, "bool",
+        object_class_property_add_qapi(oc, prop_name, &bool_type_info,
                                   x86_cpu_get_bit_prop,
                                   x86_cpu_set_bit_prop,
                                   NULL, fp);
@@ -10939,13 +10939,13 @@ static void x86_cpu_common_class_init(ObjectClass *oc, const void *data)
 
     dc->user_creatable = true;
 
-    object_class_property_add(oc, "family", "int",
+    object_class_property_add_qapi(oc, "family", &int_type_info,
                               x86_cpuid_version_get_family,
                               x86_cpuid_version_set_family, NULL, NULL);
-    object_class_property_add(oc, "model", "int",
+    object_class_property_add_qapi(oc, "model", &int_type_info,
                               x86_cpuid_version_get_model,
                               x86_cpuid_version_set_model, NULL, NULL);
-    object_class_property_add(oc, "stepping", "int",
+    object_class_property_add_qapi(oc, "stepping", &int_type_info,
                               x86_cpuid_version_get_stepping,
                               x86_cpuid_version_set_stepping, NULL, NULL);
     object_class_property_add_str(oc, "vendor",
@@ -10954,7 +10954,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, const void *data)
     object_class_property_add_str(oc, "model-id",
                                   x86_cpuid_get_model_id,
                                   x86_cpuid_set_model_id);
-    object_class_property_add(oc, "tsc-frequency", "int",
+    object_class_property_add_qapi(oc, "tsc-frequency", &int_type_info,
                               x86_cpuid_get_tsc_freq,
                               x86_cpuid_set_tsc_freq, NULL, NULL);
     /*
@@ -10967,7 +10967,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, const void *data)
                               x86_cpu_get_unavailable_features,
                               NULL, NULL, NULL);
 
-    object_class_property_add(oc, "avx10-version",  "uint8",
+    object_class_property_add_qapi(oc, "avx10-version",  &uint8_type_info,
                               x86_cpuid_get_avx10_version,
                               x86_cpuid_set_avx10_version,
                               NULL, NULL);
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index ecf0c76fcdf..9b41d04259b 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -7096,7 +7096,7 @@ void kvm_arch_accel_class_init(ObjectClass *oc)
         .set = kvm_arch_set_notify_vmexit,
     ));
 
-    object_class_property_add(oc, "notify-window", "uint32",
+    object_class_property_add_qapi(oc, "notify-window", &uint32_type_info,
                               kvm_arch_get_notify_window,
                               kvm_arch_set_notify_window,
                               NULL, NULL);
@@ -7104,7 +7104,7 @@ void kvm_arch_accel_class_init(ObjectClass *oc)
                                           "Clock cycles without an event window "
                                           "after which a notification VM exit occurs");
 
-    object_class_property_add(oc, "xen-version", "uint32",
+    object_class_property_add_qapi(oc, "xen-version", &uint32_type_info,
                               kvm_arch_get_xen_version,
                               kvm_arch_set_xen_version,
                               NULL, NULL);
@@ -7113,14 +7113,14 @@ void kvm_arch_accel_class_init(ObjectClass *oc)
                                           "(in XENVER_version form "
                                           "e.g. 0x4000a for 4.10)");
 
-    object_class_property_add(oc, "xen-gnttab-max-frames", "uint16",
+    object_class_property_add_qapi(oc, "xen-gnttab-max-frames", &uint16_type_info,
                               kvm_arch_get_xen_gnttab_max_frames,
                               kvm_arch_set_xen_gnttab_max_frames,
                               NULL, NULL);
     object_class_property_set_description(oc, "xen-gnttab-max-frames",
                                           "Maximum number of grant table frames");
 
-    object_class_property_add(oc, "xen-evtchn-max-pirq", "uint16",
+    object_class_property_add_qapi(oc, "xen-evtchn-max-pirq", &uint16_type_info,
                               kvm_arch_get_xen_evtchn_max_pirq,
                               kvm_arch_set_xen_evtchn_max_pirq,
                               NULL, NULL);
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 50a9bfc35d7..65570e032dc 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -3156,7 +3156,7 @@ sev_snp_guest_class_init(ObjectClass *oc, const void *data)
     x86_klass->adjust_cpuid_features = sev_snp_adjust_cpuid_features;
     x86_klass->kvm_type = sev_snp_kvm_type;
 
-    object_class_property_add(oc, "policy", "uint64",
+    object_class_property_add_qapi(oc, "policy", &uint64_type_info,
                               sev_snp_guest_get_policy,
                               sev_snp_guest_set_policy, NULL, NULL);
     object_class_property_add_str(oc, "guest-visible-workarounds",
diff --git a/target/ppc/compat.c b/target/ppc/compat.c
index 55de3bd5d5d..4d81225de37 100644
--- a/target/ppc/compat.c
+++ b/target/ppc/compat.c
@@ -23,6 +23,7 @@
 #include "kvm_ppc.h"
 #include "system/cpus.h"
 #include "qemu/error-report.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/error.h"
 #include "qapi/visitor.h"
 #include "cpu-models.h"
@@ -335,7 +336,7 @@ void ppc_compat_add_property(Object *obj, const char *name,
     gchar *names, *desc;
     int i;
 
-    object_property_add(obj, name, "string",
+    object_property_add_qapi(obj, name, &str_type_info,
                         ppc_compat_prop_get, ppc_compat_prop_set, NULL,
                         compat_pvr);
 
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index a13727c0d4b..7d0cf88d48d 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -25,6 +25,7 @@
 #include "cpu_vendorid.h"
 #include "internals.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "qemu/error-report.h"
 #include "hw/core/qdev-properties.h"
@@ -1001,16 +1002,16 @@ void riscv_add_satp_mode_properties(Object *obj)
     RISCVCPU *cpu = RISCV_CPU(obj);
 
     if (cpu->env.misa_mxl == MXL_RV32) {
-        object_property_add(obj, "sv32", "bool", cpu_riscv_get_satp,
+        object_property_add_qapi(obj, "sv32", &bool_type_info, cpu_riscv_get_satp,
                             cpu_riscv_set_satp, NULL, &cpu->satp_modes);
     } else {
-        object_property_add(obj, "sv39", "bool", cpu_riscv_get_satp,
+        object_property_add_qapi(obj, "sv39", &bool_type_info, cpu_riscv_get_satp,
                             cpu_riscv_set_satp, NULL, &cpu->satp_modes);
-        object_property_add(obj, "sv48", "bool", cpu_riscv_get_satp,
+        object_property_add_qapi(obj, "sv48", &bool_type_info, cpu_riscv_get_satp,
                             cpu_riscv_set_satp, NULL, &cpu->satp_modes);
-        object_property_add(obj, "sv57", "bool", cpu_riscv_get_satp,
+        object_property_add_qapi(obj, "sv57", &bool_type_info, cpu_riscv_get_satp,
                             cpu_riscv_set_satp, NULL, &cpu->satp_modes);
-        object_property_add(obj, "sv64", "bool", cpu_riscv_get_satp,
+        object_property_add_qapi(obj, "sv64", &bool_type_info, cpu_riscv_get_satp,
                             cpu_riscv_set_satp, NULL, &cpu->satp_modes);
     }
 }
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index b047ffa9c0c..9e4eb2a6b08 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -24,6 +24,7 @@
 
 #include "qemu/timer.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qemu/error-report.h"
 #include "qemu/main-loop.h"
 #include "qapi/visitor.h"
@@ -519,7 +520,7 @@ static void riscv_cpu_add_kvm_unavail_prop(Object *obj, const char *prop_name)
      * unknown to KVM and error out if the user attempts
      * to enable any of them.
      */
-    object_property_add(obj, prop_name, "bool",
+    object_property_add_qapi(obj, prop_name, &bool_type_info,
                         cpu_get_cfg_unavailable,
                         cpu_set_cfg_unavailable,
                         NULL, (void *)prop_name);
@@ -550,7 +551,7 @@ static void kvm_riscv_add_cpu_user_properties(Object *cpu_obj)
         misa_cfg->name = riscv_get_misa_ext_name(bit);
         misa_cfg->description = riscv_get_misa_ext_description(bit);
 
-        object_property_add(cpu_obj, misa_cfg->name, "bool",
+        object_property_add_qapi(cpu_obj, misa_cfg->name, &bool_type_info,
                             kvm_cpu_get_misa_ext_cfg,
                             kvm_cpu_set_misa_ext_cfg,
                             NULL, misa_cfg);
@@ -566,7 +567,7 @@ static void kvm_riscv_add_cpu_user_properties(Object *cpu_obj)
     for (i = 0; i < ARRAY_SIZE(kvm_multi_ext_cfgs); i++) {
         KVMCPUConfig *multi_cfg = &kvm_multi_ext_cfgs[i];
 
-        object_property_add(cpu_obj, multi_cfg->name, "bool",
+        object_property_add_qapi(cpu_obj, multi_cfg->name, &bool_type_info,
                             kvm_cpu_get_multi_ext_cfg,
                             kvm_cpu_set_multi_ext_cfg,
                             NULL, multi_cfg);
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 02c98cc2dbb..1c311ea0aaf 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -26,6 +26,7 @@
 #include "pmu.h"
 #include "time_helper.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "qemu/accel.h"
 #include "qemu/error-report.h"
@@ -1437,7 +1438,7 @@ static void riscv_cpu_add_misa_properties(Object *cpu_obj)
             continue;
         }
 
-        object_property_add(cpu_obj, name, "bool",
+        object_property_add_qapi(cpu_obj, name, &bool_type_info,
                             cpu_get_misa_ext_cfg,
                             cpu_set_misa_ext_cfg,
                             NULL, (void *)misa_cfg);
@@ -1491,7 +1492,7 @@ static void riscv_cpu_add_profiles(Object *cpu_obj)
     for (int i = 0; riscv_profiles[i] != NULL; i++) {
         RISCVCPUProfile *profile = riscv_profiles[i];
 
-        object_property_add(cpu_obj, profile->name, "bool",
+        object_property_add_qapi(cpu_obj, profile->name, &bool_type_info,
                             cpu_get_profile, cpu_set_profile,
                             NULL, (void *)profile);
 
@@ -1554,7 +1555,7 @@ static void cpu_add_multi_ext_prop(Object *cpu_obj,
 {
     bool generic_cpu = riscv_cpu_is_generic(cpu_obj);
 
-    object_property_add(cpu_obj, multi_cfg->name, "bool",
+    object_property_add_qapi(cpu_obj, multi_cfg->name, &bool_type_info,
                         cpu_get_multi_ext_cfg,
                         cpu_set_multi_ext_cfg,
                         NULL, (void *)multi_cfg);
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index 0b88868289b..bbf983afee9 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -17,6 +17,7 @@
 #include "system/kvm.h"
 #include "system/tcg.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qemu/error-report.h"
 #include "qapi/visitor.h"
 #include "qemu/module.h"
@@ -906,13 +907,13 @@ void s390_cpu_model_class_register_props(ObjectClass *oc)
 
     for (feat = 0; feat < S390_FEAT_MAX; feat++) {
         const S390FeatDef *def = s390_feat_def(feat);
-        object_class_property_add(oc, def->name, "bool", get_feature,
+        object_class_property_add_qapi(oc, def->name, &bool_type_info, get_feature,
                                   set_feature, NULL, (void *) feat);
         object_class_property_set_description(oc, def->name, def->desc);
     }
     for (group = 0; group < S390_FEAT_GROUP_MAX; group++) {
         const S390FeatGroupDef *def = s390_feat_group_def(group);
-        object_class_property_add(oc, def->name, "bool", get_feature_group,
+        object_class_property_add_qapi(oc, def->name, &bool_type_info, get_feature_group,
                                   set_feature_group, NULL, (void *) group);
         object_class_property_set_description(oc, def->name, def->desc);
     }
diff --git a/tests/unit/test-qdev-global-props.c b/tests/unit/test-qdev-global-props.c
index 8ea362cbb90..204436fb727 100644
--- a/tests/unit/test-qdev-global-props.c
+++ b/tests/unit/test-qdev-global-props.c
@@ -27,6 +27,7 @@
 #include "hw/core/qdev-properties.h"
 #include "qom/object.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 
 
@@ -171,10 +172,12 @@ static void prop2_accessor(Object *obj, Visitor *v, const char *name,
 
 static void dynamic_instance_init(Object *obj)
 {
-    object_property_add(obj, "prop1", "uint32", prop1_accessor, prop1_accessor,
-                        NULL, NULL);
-    object_property_add(obj, "prop2", "uint32", prop2_accessor, prop2_accessor,
-                        NULL, NULL);
+    object_property_add_qapi(obj, "prop1", &uint32_type_info,
+                             prop1_accessor, prop1_accessor,
+                             NULL, NULL);
+    object_property_add_qapi(obj, "prop2", &uint32_type_info,
+                             prop2_accessor, prop2_accessor,
+                             NULL, NULL);
 }
 
 static void dynamic_class_init(ObjectClass *oc, const void *data)
diff --git a/ui/console.c b/ui/console.c
index 799d61ec1a5..e048d694c35 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -27,6 +27,7 @@
 #include "ui/vgafont.h"
 #include "hw/core/qdev.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/qapi-commands-ui.h"
 #include "qapi/visitor.h"
 #include "qemu/coroutine.h"
@@ -488,7 +489,7 @@ qemu_graphic_console_class_init(ObjectClass *oc, const void *data)
                                    offsetof(QemuGraphicConsole, device),
                                    object_property_allow_set_link,
                                    OBJ_PROP_LINK_STRONG);
-    object_class_property_add(oc, "head", "uint32",
+    object_class_property_add_qapi(oc, "head", &uint32_type_info,
                               qemu_graphic_console_prop_get_head,
                               NULL, NULL, NULL);
 
diff --git a/util/thread-context.c b/util/thread-context.c
index 0146154fa56..ee90d8d5d99 100644
--- a/util/thread-context.c
+++ b/util/thread-context.c
@@ -13,6 +13,7 @@
 #include "qemu/osdep.h"
 #include "qemu/thread-context.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/qapi-builtin-visit.h"
 #include "qapi/visitor.h"
 #include "qemu/config-file.h"
@@ -278,13 +279,13 @@ static void thread_context_class_init(ObjectClass *oc, const void *data)
     UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
 
     ucc->complete = thread_context_instance_complete;
-    object_class_property_add(oc, "thread-id", "int",
+    object_class_property_add_qapi(oc, "thread-id", &int_type_info,
                               thread_context_get_thread_id, NULL, NULL,
                               NULL);
-    object_class_property_add(oc, "cpu-affinity", "int",
+    object_class_property_add_qapi(oc, "cpu-affinity", &int_type_info,
                               thread_context_get_cpu_affinity,
                               thread_context_set_cpu_affinity, NULL, NULL);
-    object_class_property_add(oc, "node-affinity", "int", NULL,
+    object_class_property_add_qapi(oc, "node-affinity", &int_type_info, NULL,
                               thread_context_set_node_affinity, NULL, NULL);
 }
 

-- 
2.54.0



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

* [PATCH 32/54] i386/cpu: convert strList property to QAPI-aware registration
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (30 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 31/54] qom: convert scalar properties to QAPI-aware registration Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 33/54] accel/hvf: convert OnOffSplit " Marc-André Lureau
                   ` (22 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 target/i386/cpu.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index e902d0e6d3f..b7f5cf6ddb7 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -10963,7 +10963,8 @@ static void x86_cpu_common_class_init(ObjectClass *oc, const void *data)
      * QMP command: they list the features that would have prevented the
      * CPU from running if the "enforce" flag was set.
      */
-    object_class_property_add(oc, "unavailable-features", "strList",
+    object_class_property_add_qapi(oc, "unavailable-features",
+                              &strList_type_info,
                               x86_cpu_get_unavailable_features,
                               NULL, NULL, NULL);
 

-- 
2.54.0



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

* [PATCH 33/54] accel/hvf: convert OnOffSplit property to QAPI-aware registration
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (31 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 32/54] i386/cpu: convert strList property " Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 34/54] i386/x86: convert SgxEPCList " Marc-André Lureau
                   ` (21 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Convert the OnOffSplit property from manual visitor-based
callbacks to property_add_qapi_enum().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 accel/hvf/hvf-all.c | 29 +++++++++++------------------
 1 file changed, 11 insertions(+), 18 deletions(-)

diff --git a/accel/hvf/hvf-all.c b/accel/hvf/hvf-all.c
index 946dbca59d0..982072d17ea 100644
--- a/accel/hvf/hvf-all.c
+++ b/accel/hvf/hvf-all.c
@@ -11,6 +11,7 @@
 #include "qemu/osdep.h"
 #include "qemu/error-report.h"
 #include "qapi/error.h"
+#include "qapi/qapi-type-infos-common.h"
 #include "qapi/qapi-visit-common.h"
 #include "accel/accel-ops.h"
 #include "exec/cpu-common.h"
@@ -233,18 +234,12 @@ static int hvf_gdbstub_sstep_flags(AccelState *as)
     return SSTEP_ENABLE | SSTEP_NOIRQ;
 }
 
-static void hvf_set_kernel_irqchip(Object *obj, Visitor *v,
-                                   const char *name, void *opaque,
+static void hvf_set_kernel_irqchip(Object *obj, int value,
                                    Error **errp)
 {
-    OnOffSplit mode;
-
     hvf_kernel_irqchip_override = true;
-    if (!visit_type_OnOffSplit(v, name, &mode, errp)) {
-        return;
-    }
 
-    switch (mode) {
+    switch (value) {
     case ON_OFF_SPLIT_ON:
 #ifdef HOST_X86_64
         /* macOS 12 onwards exposes an HVF virtual APIC. */
@@ -264,11 +259,7 @@ static void hvf_set_kernel_irqchip(Object *obj, Visitor *v,
         break;
 
     default:
-        /*
-         * The value was checked in visit_type_OnOffSplit() above. If
-         * we get here, then something is wrong in QEMU.
-         */
-        abort();
+        g_assert_not_reached();
     }
 }
 
@@ -281,11 +272,13 @@ static void hvf_accel_class_init(ObjectClass *oc, const void *data)
     ac->gdbstub_supported_sstep_flags = hvf_gdbstub_sstep_flags;
     hvf_kernel_irqchip_override = false;
     hvf_kernel_irqchip = false;
-    object_class_property_add(oc, "kernel-irqchip", "on|off|split",
-        NULL, hvf_set_kernel_irqchip,
-        NULL, NULL);
-    object_class_property_set_description(oc, "kernel-irqchip",
-        "Configure HVF irqchip");
+
+    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
+        .name = "kernel-irqchip",
+        .qapi_type = &OnOffSplit_type_info,
+        .set = hvf_set_kernel_irqchip,
+        .description = "Configure HVF irqchip",
+    ));
 }
 
 static const TypeInfo hvf_accel_type = {

-- 
2.54.0



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

* [PATCH 34/54] i386/x86: convert SgxEPCList property to QAPI-aware registration
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (32 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 33/54] accel/hvf: convert OnOffSplit " Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 35/54] virtio-balloon: convert guest-stats property to QAPI type Marc-André Lureau
                   ` (20 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/i386/x86.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 3ff54c6f3f9..a3b4cc60315 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -25,6 +25,7 @@
 #include "qemu/units.h"
 #include "qapi/error.h"
 #include "qapi/qapi-type-infos-common.h"
+#include "qapi/qapi-type-infos-machine.h"
 #include "qapi/qapi-visit-machine.h"
 #include "qapi/visitor.h"
 #include "system/qtest.h"
@@ -418,7 +419,7 @@ static void x86_machine_class_init(ObjectClass *oc, const void *data)
     object_class_property_set_description(oc, X86_MACHINE_BUS_LOCK_RATELIMIT,
             "Set the ratelimit for the bus locks acquired in VMs");
 
-    object_class_property_add(oc, "sgx-epc", "SgxEPC",
+    object_class_property_add_qapi(oc, "sgx-epc", &SgxEPCList_type_info,
         machine_get_sgx_epc, machine_set_sgx_epc,
         NULL, NULL);
     object_class_property_set_description(oc, "sgx-epc",

-- 
2.54.0



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

* [PATCH 35/54] virtio-balloon: convert guest-stats property to QAPI type
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (33 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 34/54] i386/x86: convert SgxEPCList " Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 36/54] qom: replace object_property_add_tm with StructTm " Marc-André Lureau
                   ` (19 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Define VirtioBalloonStats and VirtioBalloonGuestStats QAPI struct types
in the schema, replacing the hand-rolled visitor in balloon_stats_get_all()
with a generated visit_type_VirtioBalloonGuestStats() call.

The wire format is preserved: the JSON output from qom-get is identical
to the previous hand-rolled visitor output.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 docs/interop/virtio-balloon-stats.rst | 22 +--------
 qapi/machine.json                     | 92 +++++++++++++++++++++++++++++++++++
 hw/virtio/virtio-balloon.c            | 86 ++++++++++++--------------------
 3 files changed, 124 insertions(+), 76 deletions(-)

diff --git a/docs/interop/virtio-balloon-stats.rst b/docs/interop/virtio-balloon-stats.rst
index b9a6a6edb22..88d3271bbb0 100644
--- a/docs/interop/virtio-balloon-stats.rst
+++ b/docs/interop/virtio-balloon-stats.rst
@@ -22,27 +22,7 @@ polling the guest's balloon driver for new stats in the specified time
 interval.
 
 To retrieve those stats, clients have to query the guest-stats property,
-which will return a dictionary containing:
-
-  * A key named 'stats', containing all available stats. If the guest
-    doesn't support a particular stat, or if it couldn't be retrieved,
-    its value will be -1. Currently, the following stats are supported:
-
-      - stat-swap-in
-      - stat-swap-out
-      - stat-major-faults
-      - stat-minor-faults
-      - stat-free-memory
-      - stat-total-memory
-      - stat-available-memory
-      - stat-disk-caches
-      - stat-htlb-pgalloc
-      - stat-htlb-pgfail
-
-  * A key named last-update, which contains the last stats update
-    timestamp in seconds. Since this timestamp is generated by the host,
-    a buggy guest can't influence its value. The value is 0 if the guest
-    has not updated the stats (yet).
+which will return a VirtioBalloonGuestStats (see QAPI documentation).
 
 It's also important to note the following:
 
diff --git a/qapi/machine.json b/qapi/machine.json
index 685e4e29b87..3327f985be2 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -1131,6 +1131,98 @@
 ##
 { 'struct': 'BalloonInfo', 'data': {'actual': 'int' } }
 
+##
+# @VirtioBalloonStats:
+#
+# VirtIO balloon device guest memory statistics.
+#
+# If the guest doesn't support a particular stat, or if it couldn't
+# be retrieved, its value will be -1.
+#
+# @stat-swap-in: The amount of memory that has been
+#     swapped in (in bytes).
+#
+# @stat-swap-out: The amount of memory that has been
+#     swapped out to disk (in bytes).
+#
+# @stat-major-faults: The number of major page faults
+#     that have occurred.
+#
+# @stat-minor-faults: The number of minor page faults
+#     that have occurred.
+#
+# @stat-free-memory: The amount of memory not being used
+#     for any purpose (in bytes).
+#
+# @stat-total-memory: The total amount of memory available
+#     (in bytes).
+#
+# @stat-available-memory: An estimate of how much memory is available
+#     (in bytes) for starting new applications, without pushing the
+#     system to swap.
+#
+# @stat-disk-caches: The amount of memory, in bytes, that can be
+#     quickly reclaimed without additional I/O.  Typically these pages
+#     are used for caching files from disk.
+#
+# @stat-htlb-pgalloc: The number of successful hugetlb page
+#     allocations
+#
+# @stat-htlb-pgfail: The number of failed hugetlb page
+#     allocations
+#
+# @stat-oom-kills: The number of OOM killer invocations
+#
+# @stat-alloc-stalls: The number of memory allocation stalls
+#
+# @stat-async-scans: The number of memory scanned asynchronously
+#
+# @stat-direct-scans: The number of memory scanned directly
+#
+# @stat-async-reclaims: The number of memory reclaimed asynchronously
+#
+# @stat-direct-reclaims: The number of memory reclaimed directly
+#
+# Since: 11.1
+##
+{ 'struct': 'VirtioBalloonStats',
+  'data': {
+    'stat-swap-in': 'uint64',
+    'stat-swap-out': 'uint64',
+    'stat-major-faults': 'uint64',
+    'stat-minor-faults': 'uint64',
+    'stat-free-memory': 'uint64',
+    'stat-total-memory': 'uint64',
+    'stat-available-memory': 'uint64',
+    'stat-disk-caches': 'uint64',
+    'stat-htlb-pgalloc': 'uint64',
+    'stat-htlb-pgfail': 'uint64',
+    'stat-oom-kills': 'uint64',
+    'stat-alloc-stalls': 'uint64',
+    'stat-async-scans': 'uint64',
+    'stat-direct-scans': 'uint64',
+    'stat-async-reclaims': 'uint64',
+    'stat-direct-reclaims': 'uint64' } }
+
+##
+# @VirtioBalloonGuestStats:
+#
+# Guest statistics from the VirtIO balloon device.
+#
+# @last-update: timestamp in seconds of the last stats
+#     update from the guest (since this timestamp is generated
+#     by the host, a buggy guest can't influence its value),
+#     or 0 if no update has been received yet.
+#
+# @stats: balloon memory statistics
+#
+# Since: 11.1
+##
+{ 'struct': 'VirtioBalloonGuestStats',
+  'data': {
+    'last-update': 'int',
+    'stats': 'VirtioBalloonStats' } }
+
 ##
 # @query-balloon:
 #
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index 9e43948128f..c9873f8cf0c 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -29,6 +29,8 @@
 #include "qapi/error.h"
 #include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/qapi-events-machine.h"
+#include "qapi/qapi-type-infos-machine.h"
+#include "qapi/qapi-visit-machine.h"
 #include "qapi/visitor.h"
 #include "trace.h"
 #include "qemu/error-report.h"
@@ -169,33 +171,8 @@ static void balloon_deflate_page(VirtIOBalloon *balloon,
     }
 }
 
-/*
- * All stats upto VIRTIO_BALLOON_S_NR /must/ have a
- * non-NULL name declared here, since these are used
- * as keys for populating the QDict with stats
- */
-static const char *balloon_stat_names[] = {
-   [VIRTIO_BALLOON_S_SWAP_IN] = "stat-swap-in",
-   [VIRTIO_BALLOON_S_SWAP_OUT] = "stat-swap-out",
-   [VIRTIO_BALLOON_S_MAJFLT] = "stat-major-faults",
-   [VIRTIO_BALLOON_S_MINFLT] = "stat-minor-faults",
-   [VIRTIO_BALLOON_S_MEMFREE] = "stat-free-memory",
-
-   [VIRTIO_BALLOON_S_MEMTOT] = "stat-total-memory",
-   [VIRTIO_BALLOON_S_AVAIL] = "stat-available-memory",
-   [VIRTIO_BALLOON_S_CACHES] = "stat-disk-caches",
-   [VIRTIO_BALLOON_S_HTLB_PGALLOC] = "stat-htlb-pgalloc",
-   [VIRTIO_BALLOON_S_HTLB_PGFAIL] = "stat-htlb-pgfail",
-
-   [VIRTIO_BALLOON_S_OOM_KILL] = "stat-oom-kills",
-   [VIRTIO_BALLOON_S_ALLOC_STALL] = "stat-alloc-stalls",
-   [VIRTIO_BALLOON_S_ASYNC_SCAN] = "stat-async-scans",
-   [VIRTIO_BALLOON_S_DIRECT_SCAN] = "stat-direct-scans",
-   [VIRTIO_BALLOON_S_ASYNC_RECLAIM] = "stat-async-reclaims",
-
-   [VIRTIO_BALLOON_S_DIRECT_RECLAIM] = "stat-direct-reclaims",
-};
-G_STATIC_ASSERT(G_N_ELEMENTS(balloon_stat_names) == VIRTIO_BALLOON_S_NR);
+/* Update VirtioBalloonStats QAPI type when new stats are added */
+G_STATIC_ASSERT(VIRTIO_BALLOON_S_NR == 16);
 
 /*
  * reset_stats - Mark all items in the stats array as unset
@@ -257,33 +234,31 @@ static void balloon_stats_get_all(Object *obj, Visitor *v, const char *name,
                                   void *opaque, Error **errp)
 {
     VirtIOBalloon *s = VIRTIO_BALLOON(obj);
-    bool ok = false;
-    int i;
-
-    if (!visit_start_struct(v, name, NULL, 0, errp)) {
-        return;
-    }
-    if (!visit_type_int(v, "last-update", &s->stats_last_update, errp)) {
-        goto out_end;
-    }
-
-    if (!visit_start_struct(v, "stats", NULL, 0, errp)) {
-        goto out_end;
-    }
-    for (i = 0; i < VIRTIO_BALLOON_S_NR; i++) {
-        if (!visit_type_uint64(v, balloon_stat_names[i], &s->stats[i], errp)) {
-            goto out_nested;
-        }
-    }
-    ok = visit_check_struct(v, errp);
-out_nested:
-    visit_end_struct(v, NULL);
-
-    if (ok) {
-        visit_check_struct(v, errp);
-    }
-out_end:
-    visit_end_struct(v, NULL);
+    VirtioBalloonStats stats = {
+        .stat_swap_in = s->stats[VIRTIO_BALLOON_S_SWAP_IN],
+        .stat_swap_out = s->stats[VIRTIO_BALLOON_S_SWAP_OUT],
+        .stat_major_faults = s->stats[VIRTIO_BALLOON_S_MAJFLT],
+        .stat_minor_faults = s->stats[VIRTIO_BALLOON_S_MINFLT],
+        .stat_free_memory = s->stats[VIRTIO_BALLOON_S_MEMFREE],
+        .stat_total_memory = s->stats[VIRTIO_BALLOON_S_MEMTOT],
+        .stat_available_memory = s->stats[VIRTIO_BALLOON_S_AVAIL],
+        .stat_disk_caches = s->stats[VIRTIO_BALLOON_S_CACHES],
+        .stat_htlb_pgalloc = s->stats[VIRTIO_BALLOON_S_HTLB_PGALLOC],
+        .stat_htlb_pgfail = s->stats[VIRTIO_BALLOON_S_HTLB_PGFAIL],
+        .stat_oom_kills = s->stats[VIRTIO_BALLOON_S_OOM_KILL],
+        .stat_alloc_stalls = s->stats[VIRTIO_BALLOON_S_ALLOC_STALL],
+        .stat_async_scans = s->stats[VIRTIO_BALLOON_S_ASYNC_SCAN],
+        .stat_direct_scans = s->stats[VIRTIO_BALLOON_S_DIRECT_SCAN],
+        .stat_async_reclaims = s->stats[VIRTIO_BALLOON_S_ASYNC_RECLAIM],
+        .stat_direct_reclaims = s->stats[VIRTIO_BALLOON_S_DIRECT_RECLAIM],
+    };
+    VirtioBalloonGuestStats guest_stats = {
+        .last_update = s->stats_last_update,
+        .stats = &stats,
+    };
+    VirtioBalloonGuestStats *argp = &guest_stats;
+
+    visit_type_VirtioBalloonGuestStats(v, name, &argp, errp);
 }
 
 static void balloon_stats_get_poll_interval(Object *obj, Visitor *v,
@@ -1020,7 +995,8 @@ static void virtio_balloon_instance_init(Object *obj)
     s->free_page_hint_cmd_id = VIRTIO_BALLOON_FREE_PAGE_HINT_CMD_ID_MIN;
     s->free_page_hint_notify.notify = virtio_balloon_free_page_hint_notify;
 
-    object_property_add(obj, "guest-stats", "guest statistics",
+    object_property_add_qapi(obj, "guest-stats",
+                        &VirtioBalloonGuestStats_type_info,
                         balloon_stats_get_all, NULL, NULL, NULL);
 
     object_property_add_qapi(obj, "guest-stats-polling-interval", &int_type_info,

-- 
2.54.0



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

* [PATCH 36/54] qom: replace object_property_add_tm with StructTm QAPI type
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (34 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 35/54] virtio-balloon: convert guest-stats property to QAPI type Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 37/54] hw/nvdimm: convert UUID property to QAPI-aware registration Marc-André Lureau
                   ` (18 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Define a StructTm QAPI struct in common.json matching the existing
"struct tm" property wire format (tm_year, tm_mon, tm_mday, tm_hour,
tm_min, tm_sec as int32).

Convert the two callers (mc146818rtc and spapr_rtc) to use
object_property_add_qapi() with a standard ObjectPropertyAccessor
that populates a StructTm and calls the generated visitor.

Remove object_property_add_tm(), object_class_property_add_tm(),
the TMProperty type, and the property_get_tm() helper from
qom/object.c, along with their declarations in object.h.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 qapi/common.json     | 28 +++++++++++++++++++++
 qapi/pragma.json     |  1 +
 include/qom/object.h | 18 --------------
 hw/ppc/spapr_rtc.c   | 18 +++++++++++---
 hw/rtc/mc146818rtc.c | 16 +++++++++---
 qom/object.c         | 69 ----------------------------------------------------
 6 files changed, 57 insertions(+), 93 deletions(-)

diff --git a/qapi/common.json b/qapi/common.json
index af7e3d618a7..68b29126cbc 100644
--- a/qapi/common.json
+++ b/qapi/common.json
@@ -228,3 +228,31 @@
 ##
 { 'enum': 'EndianMode',
   'data': [ 'unspecified', 'little', 'big' ] }
+
+##
+# @StructTm:
+#
+# Broken-down time.  Field semantics match C ``struct tm``.
+#
+# @tm_year: years since 1900
+#
+# @tm_mon: months since January (0-11)
+#
+# @tm_mday: day of the month (1-31)
+#
+# @tm_hour: hours since midnight (0-23)
+#
+# @tm_min: minutes after the hour (0-59)
+#
+# @tm_sec: seconds after the minute (0-59, 60-61 for leap seconds)
+#
+# Since: 11.1
+##
+{ 'struct': 'StructTm',
+  'data': {
+    'tm_year': 'int32',
+    'tm_mon': 'int32',
+    'tm_mday': 'int32',
+    'tm_hour': 'int32',
+    'tm_min': 'int32',
+    'tm_sec': 'int32' } }
diff --git a/qapi/pragma.json b/qapi/pragma.json
index 24aebbe8f5f..8283149693d 100644
--- a/qapi/pragma.json
+++ b/qapi/pragma.json
@@ -108,6 +108,7 @@
         'QKeyCode',                 # send-key, input-sent-event
         'QapiErrorClass',           # QMP error replies
         'SshHostKeyCheckMode',      # blockdev-add, -blockdev
+        'StructTm',                 # qom-get of RTC date property
         'SysEmuTarget',             # query-cpu-fast, query-target
         'UuidInfo',                 # query-uuid
         'VncClientInfo',            # query-vnc, query-vnc-servers, ...
diff --git a/include/qom/object.h b/include/qom/object.h
index 14238e4b844..d0134a94281 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1893,24 +1893,6 @@ object_class_property_add_qapi(ObjectClass *klass,
                                ObjectPropertyRelease *release,
                                void *opaque);
 
-/**
- * object_property_add_tm:
- * @obj: the object to add a property to
- * @name: the name of the property
- * @get: the getter or NULL if the property is write-only.
- *
- * Add a read-only struct tm valued property using a getter function.
- * This function will add a property of type 'struct tm'.
- *
- * Returns: The newly added property on success, or %NULL on failure.
- */
-ObjectProperty *object_property_add_tm(Object *obj, const char *name,
-                            void (*get)(Object *, struct tm *, Error **));
-
-ObjectProperty *object_class_property_add_tm(ObjectClass *klass,
-                            const char *name,
-                            void (*get)(Object *, struct tm *, Error **));
-
 typedef enum {
     /* Automatically add a getter to the property */
     OBJ_PROP_FLAG_READ = 1 << 0,
diff --git a/hw/ppc/spapr_rtc.c b/hw/ppc/spapr_rtc.c
index 1f7d2d8f898..a4a2b3237e2 100644
--- a/hw/ppc/spapr_rtc.c
+++ b/hw/ppc/spapr_rtc.c
@@ -33,6 +33,9 @@
 #include "migration/vmstate.h"
 #include "qapi/error.h"
 #include "qapi/qapi-events-misc.h"
+#include "qapi/qapi-type-infos-common.h"
+#include "qapi/qapi-visit-common.h"
+#include "qapi/visitor.h"
 #include "qemu/cutils.h"
 #include "qemu/module.h"
 
@@ -131,9 +134,17 @@ static void rtas_set_time_of_day(PowerPCCPU *cpu, SpaprMachineState *spapr,
     rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 }
 
-static void spapr_rtc_qom_date(Object *obj, struct tm *current_tm, Error **errp)
+static void spapr_rtc_qom_date(Object *obj, Visitor *v, const char *name,
+                               void *opaque, Error **errp)
 {
-    spapr_rtc_read(SPAPR_RTC(obj), current_tm, NULL);
+    struct tm value;
+    StructTm tm, *tmp = &tm;
+
+    spapr_rtc_read(SPAPR_RTC(obj), &value, NULL);
+
+    tm = (StructTm) { value.tm_year, value.tm_mon, value.tm_mday,
+                      value.tm_hour, value.tm_min, value.tm_sec };
+    visit_type_StructTm(v, name, &tmp, errp);
 }
 
 static void spapr_rtc_realize(DeviceState *dev, Error **errp)
@@ -150,7 +161,8 @@ static void spapr_rtc_realize(DeviceState *dev, Error **errp)
     rtc_ns = qemu_clock_get_ns(rtc_clock);
     rtc->ns_offset = host_s * NANOSECONDS_PER_SECOND - rtc_ns;
 
-    object_property_add_tm(OBJECT(rtc), "date", spapr_rtc_qom_date);
+    object_property_add_qapi(OBJECT(rtc), "date", &StructTm_type_info,
+                             spapr_rtc_qom_date, NULL, NULL, NULL);
 }
 
 static const VMStateDescription vmstate_spapr_rtc = {
diff --git a/hw/rtc/mc146818rtc.c b/hw/rtc/mc146818rtc.c
index ccbb2797169..e130cb4eaf7 100644
--- a/hw/rtc/mc146818rtc.c
+++ b/hw/rtc/mc146818rtc.c
@@ -42,6 +42,8 @@
 #include "migration/vmstate.h"
 #include "qapi/error.h"
 #include "qapi/qapi-events-misc.h"
+#include "qapi/qapi-type-infos-common.h"
+#include "qapi/qapi-visit-common.h"
 #include "qapi/visitor.h"
 #include "trace.h"
 
@@ -855,12 +857,19 @@ static const MemoryRegionOps cmos_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-static void rtc_get_date(Object *obj, struct tm *current_tm, Error **errp)
+static void rtc_get_date(Object *obj, Visitor *v, const char *name,
+                         void *opaque, Error **errp)
 {
     MC146818RtcState *s = MC146818_RTC(obj);
+    struct tm value;
+    StructTm tm, *tmp = &tm;
 
     rtc_update_time(s);
-    rtc_get_time(s, current_tm);
+    rtc_get_time(s, &value);
+
+    tm = (StructTm) { value.tm_year, value.tm_mon, value.tm_mday,
+                      value.tm_hour, value.tm_min, value.tm_sec };
+    visit_type_StructTm(v, name, &tmp, errp);
 }
 
 static void rtc_realizefn(DeviceState *dev, Error **errp)
@@ -921,7 +930,8 @@ static void rtc_realizefn(DeviceState *dev, Error **errp)
     memory_region_add_subregion(&s->io, 0, &s->coalesced_io);
     memory_region_add_coalescing(&s->coalesced_io, 0, 1);
 
-    object_property_add_tm(OBJECT(s), "date", rtc_get_date);
+    object_property_add_qapi(OBJECT(s), "date", &StructTm_type_info,
+                             rtc_get_date, NULL, NULL, NULL);
 
     qdev_init_gpio_out(dev, &s->irq, 1);
 }
diff --git a/qom/object.c b/qom/object.c
index 7f4d301cd86..1e6c3a9f91d 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -2463,75 +2463,6 @@ object_class_property_add_qapi(ObjectClass *klass, const char *name,
     return prop;
 }
 
-typedef struct TMProperty {
-    void (*get)(Object *, struct tm *, Error **);
-} TMProperty;
-
-static void property_get_tm(Object *obj, Visitor *v, const char *name,
-                            void *opaque, Error **errp)
-{
-    TMProperty *prop = opaque;
-    Error *err = NULL;
-    struct tm value;
-
-    prop->get(obj, &value, &err);
-    if (err) {
-        error_propagate(errp, err);
-        return;
-    }
-
-    if (!visit_start_struct(v, name, NULL, 0, errp)) {
-        return;
-    }
-    if (!visit_type_int32(v, "tm_year", &value.tm_year, errp)) {
-        goto out_end;
-    }
-    if (!visit_type_int32(v, "tm_mon", &value.tm_mon, errp)) {
-        goto out_end;
-    }
-    if (!visit_type_int32(v, "tm_mday", &value.tm_mday, errp)) {
-        goto out_end;
-    }
-    if (!visit_type_int32(v, "tm_hour", &value.tm_hour, errp)) {
-        goto out_end;
-    }
-    if (!visit_type_int32(v, "tm_min", &value.tm_min, errp)) {
-        goto out_end;
-    }
-    if (!visit_type_int32(v, "tm_sec", &value.tm_sec, errp)) {
-        goto out_end;
-    }
-    visit_check_struct(v, errp);
-out_end:
-    visit_end_struct(v, NULL);
-}
-
-ObjectProperty *
-object_property_add_tm(Object *obj, const char *name,
-                       void (*get)(Object *, struct tm *, Error **))
-{
-    TMProperty *prop = g_malloc0(sizeof(*prop));
-
-    prop->get = get;
-
-    return object_property_add(obj, name, "struct tm",
-                               get ? property_get_tm : NULL, NULL,
-                               property_release_data,
-                               prop);
-}
-
-ObjectProperty *
-object_class_property_add_tm(ObjectClass *klass, const char *name,
-                             void (*get)(Object *, struct tm *, Error **))
-{
-    TMProperty *prop = g_malloc0(sizeof(*prop));
-
-    prop->get = get;
-
-    return object_class_property_add(klass, name, "struct tm",
-                                     get ? property_get_tm : NULL,
-                                     NULL, NULL, prop);
-}
 
 static char *object_get_type(Object *obj, Error **errp)
 {

-- 
2.54.0



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

* [PATCH 37/54] hw/nvdimm: convert UUID property to QAPI-aware registration
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (35 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 36/54] qom: replace object_property_add_tm with StructTm " Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 38/54] hw/s390-virtio-ccw: convert loadparm " Marc-André Lureau
                   ` (17 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Add a QemuUUID_type_info and use object_property_add_qapi() instead of
object_property_add() for the nvdimm UUID property.

The type info is defined manually in uuid.c rather than generated,
since QAPI does not yet support string typedefs. An alternative would
be to extend the QAPI schema language with a 'typedef' construct
(e.g. { 'typedef': 'UUID', 'data': 'str' }), which would let the
generator produce the type info, C typedef, and introspection entry
automatically.

Alternatively, the exposed type being a string, we could change the
property to be str_type_info.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/qemu/uuid.h | 4 ++++
 hw/mem/nvdimm.c     | 4 ++--
 util/uuid.c         | 4 ++++
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/include/qemu/uuid.h b/include/qemu/uuid.h
index 869f84af09d..ed0c62327d4 100644
--- a/include/qemu/uuid.h
+++ b/include/qemu/uuid.h
@@ -16,6 +16,8 @@
 #ifndef QEMU_UUID_H
 #define QEMU_UUID_H
 
+#include "qapi/qapi-type-info.h"
+
 
 /* Version 4 UUID (pseudo random numbers), RFC4122 4.4. */
 
@@ -99,4 +101,6 @@ QemuUUID qemu_uuid_bswap(QemuUUID uuid);
 
 uint32_t qemu_uuid_hash(const void *uuid);
 
+extern const QAPITypeInfo QemuUUID_type_info;
+
 #endif
diff --git a/hw/mem/nvdimm.c b/hw/mem/nvdimm.c
index 123ddc93854..b7ccb5c9367 100644
--- a/hw/mem/nvdimm.c
+++ b/hw/mem/nvdimm.c
@@ -104,8 +104,8 @@ static void nvdimm_init(Object *obj)
                              nvdimm_get_label_size, nvdimm_set_label_size, NULL,
                              NULL);
 
-    object_property_add(obj, NVDIMM_UUID_PROP, "QemuUUID", nvdimm_get_uuid,
-                        nvdimm_set_uuid, NULL, NULL);
+    object_property_add_qapi(obj, NVDIMM_UUID_PROP, &QemuUUID_type_info,
+                             nvdimm_get_uuid, nvdimm_set_uuid, NULL, NULL);
 }
 
 static void nvdimm_finalize(Object *obj)
diff --git a/util/uuid.c b/util/uuid.c
index 234619dd5e6..4468520c414 100644
--- a/util/uuid.c
+++ b/util/uuid.c
@@ -17,6 +17,10 @@
 #include "qemu/uuid.h"
 #include "qemu/bswap.h"
 
+const QAPITypeInfo QemuUUID_type_info = {
+    .name = "QemuUUID",
+};
+
 void qemu_uuid_generate(QemuUUID *uuid)
 {
     int i;

-- 
2.54.0



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

* [PATCH 38/54] hw/s390-virtio-ccw: convert loadparm property to QAPI-aware registration
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (36 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 37/54] hw/nvdimm: convert UUID property to QAPI-aware registration Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 39/54] hw/ppc/spapr_drc: convert fdt " Marc-André Lureau
                   ` (16 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

The QAPI type is actually a string. Here also, if we had typedef support
we could expose a more specific type.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/s390x/s390-virtio-ccw.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 4d35f9b10bc..638eddfd121 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -43,6 +43,7 @@
 #include "system/hostmem.h"
 #include "target/s390x/kvm/pv.h"
 #include "migration/blocker.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "hw/s390x/cpu-topology.h"
 #include "kvm/kvm_s390x.h"
@@ -849,7 +850,8 @@ static void ccw_machine_class_init(ObjectClass *oc, const void *data)
     object_class_property_set_description(oc, "dea-key-wrap",
             "enable/disable DEA key wrapping using the CPACF wrapping key");
 
-    object_class_property_add(oc, "loadparm", "loadparm",
+    /* if QAPI learns to typedef str, we could expose a more specific type */
+    object_class_property_add_qapi(oc, "loadparm", &str_type_info,
                               machine_get_loadparm, machine_set_loadparm,
                               NULL, NULL);
     object_class_property_set_description(oc, "loadparm",

-- 
2.54.0



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

* [PATCH 39/54] hw/ppc/spapr_drc: convert fdt property to QAPI-aware registration
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (37 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 38/54] hw/s390-virtio-ccw: convert loadparm " Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 40/54] spdm-socket: convert SpdmTransportType to QAPI enum Marc-André Lureau
                   ` (15 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Use object_property_add_qapi() with any_type_info for the "fdt"
property, since the FDT structure is dynamically shaped at runtime and
cannot be represented as a static QAPI type.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/ppc/spapr_drc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index 62baf38a00e..fcafdef7dff 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -586,7 +586,7 @@ static void spapr_dr_connector_instance_init(Object *obj)
     object_property_add_uint32_ptr(obj, "id", &drc->id, OBJ_PROP_FLAG_READ);
     object_property_add_qapi(obj, "index", &uint32_type_info, prop_get_index,
                         NULL, NULL, NULL);
-    object_property_add(obj, "fdt", "struct", prop_get_fdt,
+    object_property_add_qapi(obj, "fdt", &any_type_info, prop_get_fdt,
                         NULL, NULL, NULL);
     drc->state = drck->empty_state;
 }

-- 
2.54.0



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

* [PATCH 40/54] spdm-socket: convert SpdmTransportType to QAPI enum
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (38 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 39/54] hw/ppc/spapr_drc: convert fdt " Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 41/54] hw/pci: change the busnr type to uint8 Marc-André Lureau
                   ` (14 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Replace the hand-written SpdmTransportType C enum and QEnumLookup
table with a QAPI schema definition in qapi/sockets.json. Update
all users in hw/nvme/ctrl.c to use the QAPI-generated enum constants
(SPDM_TRANSPORT_TYPE_* instead of SPDM_SOCKET_TRANSPORT_TYPE_*).

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 qapi/sockets.json            | 20 ++++++++++++++++++++
 include/system/spdm-socket.h | 28 +++++++++++-----------------
 backends/spdm-socket.c       | 23 +++++++----------------
 hw/nvme/ctrl.c               | 26 +++++++++++++-------------
 4 files changed, 51 insertions(+), 46 deletions(-)

diff --git a/qapi/sockets.json b/qapi/sockets.json
index 473be2ac58a..dbb452cfb72 100644
--- a/qapi/sockets.json
+++ b/qapi/sockets.json
@@ -252,3 +252,23 @@
             'unix': 'UnixSocketAddress',
             'vsock': 'VsockSocketAddress',
             'fd': 'FdSocketAddress' } }
+
+##
+# @SpdmTransportType:
+#
+# SPDM transport type
+#
+# @unspecified: Unspecified transport
+#
+# @mctp: MCTP transport
+#
+# @doe: PCI Data Object Exchange (DOE) transport
+#
+# @scsi: SCSI transport
+#
+# @nvme: NVMe transport
+#
+# Since: 11.1
+##
+{ 'enum': 'SpdmTransportType',
+  'data': [ 'unspecified', 'mctp', 'doe', 'scsi', 'nvme' ] }
diff --git a/include/system/spdm-socket.h b/include/system/spdm-socket.h
index 00cb0e97f36..b5a68d3d60b 100644
--- a/include/system/spdm-socket.h
+++ b/include/system/spdm-socket.h
@@ -23,6 +23,8 @@
 #ifndef SPDM_REQUESTER_H
 #define SPDM_REQUESTER_H
 
+#include "qapi/qapi-types-sockets.h"
+
 /**
  * spdm_socket_connect: connect to an external SPDM socket
  * @port: port to connect to
@@ -37,7 +39,7 @@ int spdm_socket_connect(uint16_t port, Error **errp);
 /**
  * spdm_socket_rsp: send and receive a message to a SPDM server
  * @socket: socket returned from spdm_socket_connect()
- * @transport_type: SPDM_SOCKET_TRANSPORT_TYPE_* macro
+ * @transport_type: the SPDM transport type
  * @req: request buffer
  * @req_len: request buffer length
  * @rsp: response buffer
@@ -46,14 +48,14 @@ int spdm_socket_connect(uint16_t port, Error **errp);
  * Send platform data to a SPDM server on socket and then receive
  * a response.
  */
-uint32_t spdm_socket_rsp(const int socket, uint32_t transport_type,
+uint32_t spdm_socket_rsp(const int socket, SpdmTransportType transport_type,
                          void *req, uint32_t req_len,
                          void *rsp, uint32_t rsp_len);
 
 /**
  * spdm_socket_rsp: Receive a message from an SPDM server
  * @socket: socket returned from spdm_socket_connect()
- * @transport_type: SPDM_SOCKET_TRANSPORT_TYPE_* macro
+ * @transport_type: the SPDM transport type
  * @rsp: response buffer
  * @rsp_len: response buffer length
  *
@@ -61,14 +63,14 @@ uint32_t spdm_socket_rsp(const int socket, uint32_t transport_type,
  * received or 0 on failure. This can be used to receive a message from the SPDM
  * server without sending anything first.
  */
-uint32_t spdm_socket_receive(const int socket, uint32_t transport_type,
+uint32_t spdm_socket_receive(const int socket, SpdmTransportType transport_type,
                              void *rsp, uint32_t rsp_len);
 
 /**
  * spdm_socket_rsp: Sends a message to an SPDM server
  * @socket: socket returned from spdm_socket_connect()
  * @socket_cmd: socket command type (normal/if_recv/if_send etc...)
- * @transport_type: SPDM_SOCKET_TRANSPORT_TYPE_* macro
+ * @transport_type: the SPDM transport type
  * @req: request buffer
  * @req_len: request buffer length
  *
@@ -77,16 +79,17 @@ uint32_t spdm_socket_receive(const int socket, uint32_t transport_type,
  * spdm_socket_receive().
  */
 bool spdm_socket_send(const int socket, uint32_t socket_cmd,
-                      uint32_t transport_type, void *req, uint32_t req_len);
+                      SpdmTransportType transport_type, void *req,
+                      uint32_t req_len);
 
 /**
  * spdm_socket_close: send a shutdown command to the server
  * @socket: socket returned from spdm_socket_connect()
- * @transport_type: SPDM_SOCKET_TRANSPORT_TYPE_* macro
+ * @transport_type: the SPDM transport type
  *
  * This will issue a shutdown command to the server.
  */
-void spdm_socket_close(const int socket, uint32_t transport_type);
+void spdm_socket_close(const int socket, SpdmTransportType transport_type);
 
 /*
  * Defines the transport encoding for SPDM, this information shall be passed
@@ -115,15 +118,6 @@ typedef struct {
 #define SPDM_SOCKET_MAX_MESSAGE_BUFFER_SIZE       0x1200
 #define SPDM_SOCKET_MAX_MSG_STATUS_LEN            0x02
 
-typedef enum SpdmTransportType {
-    SPDM_SOCKET_TRANSPORT_TYPE_UNSPEC = 0,
-    SPDM_SOCKET_TRANSPORT_TYPE_MCTP,
-    SPDM_SOCKET_TRANSPORT_TYPE_PCI_DOE,
-    SPDM_SOCKET_TRANSPORT_TYPE_SCSI,
-    SPDM_SOCKET_TRANSPORT_TYPE_NVME,
-    SPDM_SOCKET_TRANSPORT_TYPE_MAX
-} SpdmTransportType;
-
 extern const PropertyInfo qdev_prop_spdm_trans;
 
 #define DEFINE_PROP_SPDM_TRANS(_name, _state, _field, _default) \
diff --git a/backends/spdm-socket.c b/backends/spdm-socket.c
index b625a65d28f..826efc276dc 100644
--- a/backends/spdm-socket.c
+++ b/backends/spdm-socket.c
@@ -13,6 +13,7 @@
 #include "qemu/osdep.h"
 #include "system/spdm-socket.h"
 #include "qapi/error.h"
+#include "qapi/qapi-types-sockets.h"
 #include "hw/core/qdev-properties.h"
 #include "hw/core/qdev-properties-system.h"
 #include "hw/core/qdev-prop-internal.h"
@@ -205,7 +206,7 @@ static bool spdm_socket_command_valid(uint32_t command)
     }
 }
 
-uint32_t spdm_socket_receive(const int socket, uint32_t transport_type,
+uint32_t spdm_socket_receive(const int socket, SpdmTransportType transport_type,
                              void *rsp, uint32_t rsp_len)
 {
     uint32_t command;
@@ -223,13 +224,14 @@ uint32_t spdm_socket_receive(const int socket, uint32_t transport_type,
 }
 
 bool spdm_socket_send(const int socket, uint32_t socket_cmd,
-                      uint32_t transport_type, void *req, uint32_t req_len)
+                      SpdmTransportType transport_type, void *req,
+                      uint32_t req_len)
 {
     return send_platform_data(socket, transport_type, socket_cmd, req,
                               req_len);
 }
 
-uint32_t spdm_socket_rsp(const int socket, uint32_t transport_type,
+uint32_t spdm_socket_rsp(const int socket, SpdmTransportType transport_type,
                          void *req, uint32_t req_len,
                          void *rsp, uint32_t rsp_len)
 {
@@ -244,27 +246,16 @@ uint32_t spdm_socket_rsp(const int socket, uint32_t transport_type,
     return spdm_socket_receive(socket, transport_type, rsp, rsp_len);
 }
 
-void spdm_socket_close(const int socket, uint32_t transport_type)
+void spdm_socket_close(const int socket, SpdmTransportType transport_type)
 {
     send_platform_data(socket, transport_type,
                        SPDM_SOCKET_COMMAND_SHUTDOWN, NULL, 0);
 }
 
-const QEnumLookup SpdmTransport_lookup = {
-    .array = (const char *const[]) {
-        [SPDM_SOCKET_TRANSPORT_TYPE_UNSPEC] = "unspecified",
-        [SPDM_SOCKET_TRANSPORT_TYPE_MCTP] = "mctp",
-        [SPDM_SOCKET_TRANSPORT_TYPE_PCI_DOE] = "doe",
-        [SPDM_SOCKET_TRANSPORT_TYPE_SCSI] = "scsi",
-        [SPDM_SOCKET_TRANSPORT_TYPE_NVME] = "nvme",
-    },
-    .size = SPDM_SOCKET_TRANSPORT_TYPE_MAX
-};
-
 const PropertyInfo qdev_prop_spdm_trans = {
     .type = "SpdmTransportType",
     .description = "Spdm Transport, doe/nvme/mctp/scsi/unspecified",
-    .enum_table = &SpdmTransport_lookup,
+    .enum_table = &SpdmTransportType_lookup,
     .get = qdev_propinfo_get_enum,
     .set = qdev_propinfo_set_enum,
     .set_default_value = qdev_propinfo_set_default_value_enum,
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index b10b45f157e..85ecb910858 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -7363,14 +7363,14 @@ static uint16_t nvme_sec_prot_spdm_send(NvmeCtrl *n, NvmeRequest *req)
     }
 
     spdm_res = spdm_socket_send(n->spdm_socket, SPDM_SOCKET_STORAGE_CMD_IF_SEND,
-                                SPDM_SOCKET_TRANSPORT_TYPE_NVME, sec_buf,
+                                SPDM_TRANSPORT_TYPE_NVME, sec_buf,
                                 transport_transfer_len);
     if (!spdm_res) {
         return NVME_DATA_TRAS_ERROR | NVME_DNR;
     }
 
     /* The responder shall ack with message status */
-    recvd = spdm_socket_receive(n->spdm_socket, SPDM_SOCKET_TRANSPORT_TYPE_NVME,
+    recvd = spdm_socket_receive(n->spdm_socket, SPDM_TRANSPORT_TYPE_NVME,
                                 &nvme_cmd_status,
                                 SPDM_SOCKET_MAX_MSG_STATUS_LEN);
 
@@ -7426,14 +7426,14 @@ static uint16_t nvme_sec_prot_spdm_receive(NvmeCtrl *n, NvmeRequest *req)
 
     /* Forward if_recv to the SPDM Server with SPSP0 */
     spdm_res = spdm_socket_send(n->spdm_socket, SPDM_SOCKET_STORAGE_CMD_IF_RECV,
-                                SPDM_SOCKET_TRANSPORT_TYPE_NVME,
+                                SPDM_TRANSPORT_TYPE_NVME,
                                 &hdr, sizeof(hdr));
     if (!spdm_res) {
         return NVME_DATA_TRAS_ERROR | NVME_DNR;
     }
 
     /* The responder shall ack with message status */
-    recvd = spdm_socket_receive(n->spdm_socket, SPDM_SOCKET_TRANSPORT_TYPE_NVME,
+    recvd = spdm_socket_receive(n->spdm_socket, SPDM_TRANSPORT_TYPE_NVME,
                                 &nvme_cmd_status,
                                 SPDM_SOCKET_MAX_MSG_STATUS_LEN);
     if (recvd < SPDM_SOCKET_MAX_MSG_STATUS_LEN) {
@@ -7453,7 +7453,7 @@ static uint16_t nvme_sec_prot_spdm_receive(NvmeCtrl *n, NvmeRequest *req)
     }
 
     recvd = spdm_socket_receive(n->spdm_socket,
-                                SPDM_SOCKET_TRANSPORT_TYPE_NVME,
+                                SPDM_TRANSPORT_TYPE_NVME,
                                 rsp_spdm_buf, alloc_len);
     if (!recvd) {
         return NVME_DATA_TRAS_ERROR | NVME_DNR;
@@ -8927,7 +8927,7 @@ static bool pcie_doe_spdm_rsp(DOECap *doe_cap)
     uint32_t rsp_len = SPDM_SOCKET_MAX_MESSAGE_BUFFER_SIZE;
 
     uint32_t recvd = spdm_socket_rsp(doe_cap->spdm_socket,
-                             SPDM_SOCKET_TRANSPORT_TYPE_PCI_DOE,
+                             SPDM_TRANSPORT_TYPE_DOE,
                              req, req_len, rsp, rsp_len);
     doe_cap->read_mbox_len += DIV_ROUND_UP(recvd, 4);
 
@@ -9029,7 +9029,7 @@ static bool nvme_init_pci(NvmeCtrl *n, PCIDevice *pci_dev, Error **errp)
         uint16_t doe_offset = PCI_CONFIG_SPACE_SIZE;
 
         switch  (pci_dev->spdm_trans) {
-        case SPDM_SOCKET_TRANSPORT_TYPE_PCI_DOE:
+        case SPDM_TRANSPORT_TYPE_DOE:
             if (n->params.sriov_max_vfs) {
                 doe_offset += PCI_ARI_SIZEOF;
             }
@@ -9044,7 +9044,7 @@ static bool nvme_init_pci(NvmeCtrl *n, PCIDevice *pci_dev, Error **errp)
                 return false;
             }
             break;
-        case SPDM_SOCKET_TRANSPORT_TYPE_NVME:
+        case SPDM_TRANSPORT_TYPE_NVME:
             n->spdm_socket = spdm_socket_connect(pci_dev->spdm_port, errp);
             if (n->spdm_socket < 0) {
                 return false;
@@ -9347,10 +9347,10 @@ static void nvme_exit(PCIDevice *pci_dev)
     assert(!(pci_dev->doe_spdm.spdm_socket > 0 && n->spdm_socket >= 0));
     if (pci_dev->doe_spdm.spdm_socket > 0) {
         spdm_socket_close(pci_dev->doe_spdm.spdm_socket,
-                          SPDM_SOCKET_TRANSPORT_TYPE_PCI_DOE);
+                          SPDM_TRANSPORT_TYPE_DOE);
     } else if (n->spdm_socket >= 0) {
         spdm_socket_close(pci_dev->doe_spdm.spdm_socket,
-                          SPDM_SOCKET_TRANSPORT_TYPE_NVME);
+                          SPDM_TRANSPORT_TYPE_NVME);
     }
 
     if (n->pmr.dev) {
@@ -9406,7 +9406,7 @@ static const Property nvme_props[] = {
     DEFINE_PROP_UINT16("mqes", NvmeCtrl, params.mqes, 0x7ff),
     DEFINE_PROP_UINT16("spdm_port", PCIDevice, spdm_port, 0),
     DEFINE_PROP_SPDM_TRANS("spdm_trans", PCIDevice, spdm_trans,
-                           SPDM_SOCKET_TRANSPORT_TYPE_PCI_DOE),
+                           SPDM_TRANSPORT_TYPE_DOE),
     DEFINE_PROP_BOOL("ctratt.mem", NvmeCtrl, params.ctratt.mem, false),
     DEFINE_PROP_BOOL("atomic.dn", NvmeCtrl, params.atomic_dn, 0),
     DEFINE_PROP_UINT16("atomic.awun", NvmeCtrl, params.atomic_awun, 0),
@@ -9484,7 +9484,7 @@ static void nvme_pci_write_config(PCIDevice *dev, uint32_t address,
 
     /* DOE is only initialised if SPDM over DOE is used */
     if (pcie_find_capability(dev, PCI_EXT_CAP_ID_DOE) &&
-        dev->spdm_trans == SPDM_SOCKET_TRANSPORT_TYPE_PCI_DOE) {
+        dev->spdm_trans == SPDM_TRANSPORT_TYPE_DOE) {
         pcie_doe_write_config(&dev->doe_spdm, address, val, len);
     }
     pci_default_write_config(dev, address, val, len);
@@ -9497,7 +9497,7 @@ static uint32_t nvme_pci_read_config(PCIDevice *dev, uint32_t address, int len)
     uint32_t val;
 
     if (dev->spdm_port && pcie_find_capability(dev, PCI_EXT_CAP_ID_DOE) &&
-        (dev->spdm_trans == SPDM_SOCKET_TRANSPORT_TYPE_PCI_DOE)) {
+        (dev->spdm_trans == SPDM_TRANSPORT_TYPE_DOE)) {
         if (pcie_doe_read_config(&dev->doe_spdm, address, len, &val)) {
             return val;
         }

-- 
2.54.0



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

* [PATCH 41/54] hw/pci: change the busnr type to uint8
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (39 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 40/54] spdm-socket: convert SpdmTransportType to QAPI enum Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 42/54] qdev: add qapi_type field to PropertyInfo with fallback registration Marc-André Lureau
                   ` (13 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

It is effectively a u8. The next changes are going to use the
uint8_type_info for it.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/pci/pci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 4298adf5a0a..c65cf6e089b 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -72,7 +72,7 @@ static void prop_pci_busnr_get(Object *obj, Visitor *v, const char *name,
 }
 
 static const PropertyInfo prop_pci_busnr = {
-    .type = "busnr",
+    .type = "uint8",
     .get = prop_pci_busnr_get,
 };
 

-- 
2.54.0



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

* [PATCH 42/54] qdev: add qapi_type field to PropertyInfo with fallback registration
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (40 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 41/54] hw/pci: change the busnr type to uint8 Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 43/54] qdev: convert core PropertyInfo definitions to use qapi_type Marc-André Lureau
                   ` (12 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Add a qapi_type field to PropertyInfo to prepare for the transition
from string-based type metadata to QAPI type-info.

Add a qdev_prop_qapi_type() helper that resolves the QAPI type for a
property from .qapi_type. It will be later extended to cope with array
types.

Update qdev_property_add_static() and qdev_class_add_property() to
prefer object_property_add_qapi() when a QAPI type is available, falling
back to the old object_property_add() for unconverted properties.

Update the shared enum accessor functions to prefer .qapi_type->lookup
over .enum_table via a new qdev_propinfo_enum_lookup() helper.

No PropertyInfo definitions are changed, all .qapi_type fields
default to NULL, so the fallback paths are always taken. This patch
is no-op for now.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/hw/core/qdev-properties.h |  1 +
 hw/core/qdev-properties.c         | 67 +++++++++++++++++++++++++++++----------
 2 files changed, 52 insertions(+), 16 deletions(-)

diff --git a/include/hw/core/qdev-properties.h b/include/hw/core/qdev-properties.h
index 17543957a6c..441f77a501d 100644
--- a/include/hw/core/qdev-properties.h
+++ b/include/hw/core/qdev-properties.h
@@ -34,6 +34,7 @@ struct PropertyInfo {
     const char *type;
     const char *description;
     const QEnumLookup *enum_table;
+    const QAPITypeInfo *qapi_type;
     bool realized_set_allowed; /* allow setting property on realized device */
     char *(*print)(Object *obj, const Property *prop);
     void (*set_default_value)(ObjectProperty *op, const Property *prop);
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 73539c727b3..eb7caa32557 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -99,13 +99,22 @@ static ObjectPropertyAccessor *field_prop_setter(const PropertyInfo *info)
     return info->set ? field_prop_set : NULL;
 }
 
+static const QEnumLookup *qdev_propinfo_enum_lookup(const PropertyInfo *info)
+{
+    if (info->qapi_type) {
+        assert(info->qapi_type->lookup);
+        return info->qapi_type->lookup;
+    }
+    return info->enum_table;
+}
+
 void qdev_propinfo_get_enum(Object *obj, Visitor *v, const char *name,
                             void *opaque, Error **errp)
 {
     const Property *prop = opaque;
     int *ptr = object_field_prop_ptr(obj, prop);
 
-    visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
+    visit_type_enum(v, name, ptr, qdev_propinfo_enum_lookup(prop->info), errp);
 }
 
 void qdev_propinfo_set_enum(Object *obj, Visitor *v, const char *name,
@@ -114,14 +123,14 @@ void qdev_propinfo_set_enum(Object *obj, Visitor *v, const char *name,
     const Property *prop = opaque;
     int *ptr = object_field_prop_ptr(obj, prop);
 
-    visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
+    visit_type_enum(v, name, ptr, qdev_propinfo_enum_lookup(prop->info), errp);
 }
 
 void qdev_propinfo_set_default_value_enum(ObjectProperty *op,
                                           const Property *prop)
 {
     object_property_set_default_str(op,
-        qapi_enum_lookup(prop->info->enum_table, prop->defval.i));
+        qapi_enum_lookup(qdev_propinfo_enum_lookup(prop->info), prop->defval.i));
 }
 
 /* Bit */
@@ -940,8 +949,8 @@ void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
 
     prop = qdev_prop_find(dev, name);
     object_property_set_str(OBJECT(dev), name,
-                            qapi_enum_lookup(prop->info->enum_table, value),
-                            &error_abort);
+        qapi_enum_lookup(qdev_propinfo_enum_lookup(prop->info), value),
+        &error_abort);
 }
 
 void qdev_prop_set_array(DeviceState *dev, const char *name, QList *values)
@@ -1065,18 +1074,33 @@ const PropertyInfo qdev_prop_link = {
     .create = create_link_property,
 };
 
+static const QAPITypeInfo *qdev_prop_qapi_type(const Property *prop)
+{
+    /* this will be later extended to cope with QAPI array properties */
+    return prop->info->qapi_type;
+}
+
 void qdev_property_add_static(DeviceState *dev, const Property *prop)
 {
     Object *obj = OBJECT(dev);
     ObjectProperty *op;
+    const QAPITypeInfo *qapi_type = qdev_prop_qapi_type(prop);
 
     assert(!prop->info->create);
 
-    op = object_property_add(obj, prop->name, prop->info->type,
-                             field_prop_getter(prop->info),
-                             field_prop_setter(prop->info),
-                             prop->info->release,
-                             (Property *)prop);
+    if (qapi_type) {
+        op = object_property_add_qapi(obj, prop->name, qapi_type,
+                                      field_prop_getter(prop->info),
+                                      field_prop_setter(prop->info),
+                                      prop->info->release,
+                                      (Property *)prop);
+    } else {
+        op = object_property_add(obj, prop->name, prop->info->type,
+                                 field_prop_getter(prop->info),
+                                 field_prop_setter(prop->info),
+                                 prop->info->release,
+                                 (Property *)prop);
+    }
 
     object_property_set_description(obj, prop->name,
                                     prop->info->description);
@@ -1098,12 +1122,23 @@ static void qdev_class_add_property(DeviceClass *klass, const char *name,
     if (prop->info->create) {
         op = prop->info->create(oc, name, prop);
     } else {
-        op = object_class_property_add(oc,
-                                       name, prop->info->type,
-                                       field_prop_getter(prop->info),
-                                       field_prop_setter(prop->info),
-                                       prop->info->release,
-                                       (Property *)prop);
+        const QAPITypeInfo *qapi_type = qdev_prop_qapi_type(prop);
+
+        if (qapi_type) {
+            op = object_class_property_add_qapi(oc,
+                                               name, qapi_type,
+                                               field_prop_getter(prop->info),
+                                               field_prop_setter(prop->info),
+                                               prop->info->release,
+                                               (Property *)prop);
+        } else {
+            op = object_class_property_add(oc,
+                                           name, prop->info->type,
+                                           field_prop_getter(prop->info),
+                                           field_prop_setter(prop->info),
+                                           prop->info->release,
+                                           (Property *)prop);
+        }
     }
     if (prop->set_default) {
         prop->info->set_default_value(op, prop);

-- 
2.54.0



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

* [PATCH 43/54] qdev: convert core PropertyInfo definitions to use qapi_type
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (41 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 42/54] qdev: add qapi_type field to PropertyInfo with fallback registration Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 44/54] qdev: convert system " Marc-André Lureau
                   ` (11 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Replace .type string with .qapi_type pointer on all core PropertyInfo
definitions in qdev-properties.c. Remove .enum_table from enum
definitions, since the lookup is now accessed through .qapi_type->lookup
via the qdev_propinfo_enum_lookup() fallback helper.

Note that qdev_prop_usize now reports "uint32" or "uint64" depending on
the host. If usize is worth preserving, it should be added as a QAPI
builtin type. Or perhaps we should simply use "size" everywhere (u64)?

It's also strange to use type "size" for both u32 (prop_size32) and u64
(prop_size).

The qdev_prop_link and qdev_prop_array definitions are unchanged:
link uses .create for registration, and array will be refactored in
a subsequent patch.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/core/qdev-properties.c | 40 ++++++++++++++++++++++------------------
 1 file changed, 22 insertions(+), 18 deletions(-)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index eb7caa32557..7e562518184 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -12,6 +12,8 @@
 #include "qdev-prop-internal.h"
 #include "qom/compat-properties.h"
 #include "qom/qom-qobject.h"
+#include "qapi/qapi-builtin-type-infos.h"
+#include "qapi/qapi-type-infos-common.h"
 
 void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
                                   Error **errp)
@@ -180,7 +182,7 @@ static void set_default_value_bool(ObjectProperty *op, const Property *prop)
 }
 
 const PropertyInfo qdev_prop_bit = {
-    .type  = "bool",
+    .qapi_type = &bool_type_info,
     .description = "on/off",
     .get   = prop_get_bit,
     .set   = prop_set_bit,
@@ -230,7 +232,7 @@ static void prop_set_bit64(Object *obj, Visitor *v, const char *name,
 }
 
 const PropertyInfo qdev_prop_bit64 = {
-    .type  = "bool",
+    .qapi_type = &bool_type_info,
     .description = "on/off",
     .get   = prop_get_bit64,
     .set   = prop_set_bit64,
@@ -292,9 +294,8 @@ static void prop_set_on_off_auto_bit64(Object *obj, Visitor *v,
 }
 
 const PropertyInfo qdev_prop_on_off_auto_bit64 = {
-    .type = "OnOffAuto",
+    .qapi_type = &OnOffAuto_type_info,
     .description = "on/off/auto",
-    .enum_table = &OnOffAuto_lookup,
     .get = prop_get_on_off_auto_bit64,
     .set = prop_set_on_off_auto_bit64,
     .set_default_value = qdev_propinfo_set_default_value_enum,
@@ -321,7 +322,7 @@ static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
 }
 
 const PropertyInfo qdev_prop_bool = {
-    .type  = "bool",
+    .qapi_type = &bool_type_info,
     .description = "on/off",
     .get   = get_bool,
     .set   = set_bool,
@@ -361,7 +362,7 @@ void qdev_propinfo_set_default_value_uint(ObjectProperty *op,
 }
 
 const PropertyInfo qdev_prop_uint8 = {
-    .type  = "uint8",
+    .qapi_type = &uint8_type_info,
     .get   = get_uint8,
     .set   = set_uint8,
     .set_default_value = qdev_propinfo_set_default_value_uint,
@@ -388,7 +389,7 @@ static void set_uint16(Object *obj, Visitor *v, const char *name,
 }
 
 const PropertyInfo qdev_prop_uint16 = {
-    .type  = "uint16",
+    .qapi_type = &uint16_type_info,
     .get   = get_uint16,
     .set   = set_uint16,
     .set_default_value = qdev_propinfo_set_default_value_uint,
@@ -433,14 +434,14 @@ static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
 }
 
 const PropertyInfo qdev_prop_uint32 = {
-    .type  = "uint32",
+    .qapi_type = &uint32_type_info,
     .get   = get_uint32,
     .set   = set_uint32,
     .set_default_value = qdev_propinfo_set_default_value_uint,
 };
 
 const PropertyInfo qdev_prop_int32 = {
-    .type  = "int32",
+    .qapi_type = &int32_type_info,
     .get   = qdev_propinfo_get_int32,
     .set   = set_int32,
     .set_default_value = qdev_propinfo_set_default_value_int,
@@ -485,14 +486,14 @@ static void set_int64(Object *obj, Visitor *v, const char *name,
 }
 
 const PropertyInfo qdev_prop_uint64 = {
-    .type  = "uint64",
+    .qapi_type = &uint64_type_info,
     .get   = get_uint64,
     .set   = set_uint64,
     .set_default_value = qdev_propinfo_set_default_value_uint,
 };
 
 const PropertyInfo qdev_prop_int64 = {
-    .type  = "int64",
+    .qapi_type = &int64_type_info,
     .get   = get_int64,
     .set   = set_int64,
     .set_default_value = qdev_propinfo_set_default_value_int,
@@ -514,7 +515,7 @@ static void set_uint64_checkmask(Object *obj, Visitor *v, const char *name,
 }
 
 const PropertyInfo qdev_prop_uint64_checkmask = {
-    .type  = "uint64",
+    .qapi_type = &uint64_type_info,
     .get   = get_uint64,
     .set   = set_uint64_checkmask,
 };
@@ -550,7 +551,11 @@ static void set_usize(Object *obj, Visitor *v, const char *name, void *opaque,
 }
 
 const PropertyInfo qdev_prop_usize = {
-    .type  = "usize",
+#if HOST_LONG_BITS == 32
+    .qapi_type = &uint32_type_info,
+#else
+    .qapi_type = &uint64_type_info,
+#endif
     .get   = get_usize,
     .set   = set_usize,
     .set_default_value = qdev_propinfo_set_default_value_uint,
@@ -594,7 +599,7 @@ static void set_string(Object *obj, Visitor *v, const char *name,
 }
 
 const PropertyInfo qdev_prop_string = {
-    .type  = "str",
+    .qapi_type = &str_type_info,
     .release = release_string,
     .get   = get_string,
     .set   = set_string,
@@ -603,9 +608,8 @@ const PropertyInfo qdev_prop_string = {
 /* --- on/off/auto --- */
 
 const PropertyInfo qdev_prop_on_off_auto = {
-    .type = "OnOffAuto",
+    .qapi_type = &OnOffAuto_type_info,
     .description = "on/off/auto",
-    .enum_table = &OnOffAuto_lookup,
     .get = qdev_propinfo_get_enum,
     .set = qdev_propinfo_set_enum,
     .set_default_value = qdev_propinfo_set_default_value_enum,
@@ -646,7 +650,7 @@ static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
 }
 
 const PropertyInfo qdev_prop_size32 = {
-    .type  = "size",
+    .qapi_type = &size_type_info,
     .get = qdev_propinfo_get_size32,
     .set = set_size32,
     .set_default_value = qdev_propinfo_set_default_value_uint,
@@ -1052,7 +1056,7 @@ static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
 }
 
 const PropertyInfo qdev_prop_size = {
-    .type  = "size",
+    .qapi_type = &size_type_info,
     .get = get_size,
     .set = set_size,
     .set_default_value = qdev_propinfo_set_default_value_uint,

-- 
2.54.0



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

* [PATCH 44/54] qdev: convert system PropertyInfo definitions to use qapi_type
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (42 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 43/54] qdev: convert core PropertyInfo definitions to use qapi_type Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 45/54] hw: convert device-local " Marc-André Lureau
                   ` (10 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Replace .type string and .enum_table pointer with .qapi_type in all
PropertyInfo definitions in qdev-properties-system.c

Update file-private enum accessor functions to use .qapi_type->lookup
instead of .enum_table.

Note, this should be a faithful conversion, but it would be worth to
consider better types than just "str" for references (block node names,
chardev/netdev IDs, MAC addrs, etc)

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/core/qdev-prop-internal.h     |  2 +
 hw/core/qdev-properties-system.c | 92 +++++++++++++++++-----------------------
 hw/core/qdev-properties.c        |  2 +-
 3 files changed, 43 insertions(+), 53 deletions(-)

diff --git a/hw/core/qdev-prop-internal.h b/hw/core/qdev-prop-internal.h
index d7b77844fe0..c190b7b88cf 100644
--- a/hw/core/qdev-prop-internal.h
+++ b/hw/core/qdev-prop-internal.h
@@ -8,6 +8,8 @@
 #ifndef HW_CORE_QDEV_PROP_INTERNAL_H
 #define HW_CORE_QDEV_PROP_INTERNAL_H
 
+const QEnumLookup *qdev_propinfo_enum_lookup(const PropertyInfo *info);
+
 void qdev_propinfo_get_enum(Object *obj, Visitor *v, const char *name,
                             void *opaque, Error **errp);
 void qdev_propinfo_set_enum(Object *obj, Visitor *v, const char *name,
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 5bfdfe1ab9d..12be7b80a59 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -27,6 +27,7 @@
 #include "qemu/uuid.h"
 #include "qemu/error-report.h"
 #include "qdev-prop-internal.h"
+#include "qapi/qapi-type-infos.h"
 
 #include "qemu/audio.h"
 #include "chardev/char-fe.h"
@@ -238,7 +239,7 @@ static void release_drive(Object *obj, const char *name, void *opaque)
 }
 
 const PropertyInfo qdev_prop_drive = {
-    .type  = "str",
+    .qapi_type = &str_type_info,
     .description = "Node name or ID of a block device to use as a backend",
     .realized_set_allowed = true,
     .get   = get_drive,
@@ -247,7 +248,7 @@ const PropertyInfo qdev_prop_drive = {
 };
 
 const PropertyInfo qdev_prop_drive_iothread = {
-    .type  = "str",
+    .qapi_type = &str_type_info,
     .description = "Node name or ID of a block device to use as a backend",
     .realized_set_allowed = true,
     .get   = get_drive,
@@ -315,7 +316,7 @@ static void release_chr(Object *obj, const char *name, void *opaque)
 }
 
 const PropertyInfo qdev_prop_chr = {
-    .type  = "str",
+    .qapi_type = &str_type_info,
     .description = "ID of a chardev to use as a backend",
     .get   = get_chr,
     .set   = set_chr,
@@ -389,7 +390,7 @@ inval:
 }
 
 const PropertyInfo qdev_prop_macaddr = {
-    .type  = "str",
+    .qapi_type = &str_type_info,
     .description = "Ethernet 6-byte MAC Address, example: 52:54:00:12:34:56",
     .get   = get_mac,
     .set   = set_mac,
@@ -477,7 +478,7 @@ out:
 }
 
 const PropertyInfo qdev_prop_netdev = {
-    .type  = "str",
+    .qapi_type = &str_type_info,
     .description = "ID of a netdev to use as a backend",
     .get   = get_netdev,
     .set   = set_netdev,
@@ -514,7 +515,7 @@ static void set_audiodev(Object *obj, Visitor *v, const char* name,
 }
 
 const PropertyInfo qdev_prop_audiodev = {
-    .type = "str",
+    .qapi_type = &str_type_info,
     .description = "ID of an audiodev to use as a backend",
     /* release done on shutdown */
     .get = get_audiodev,
@@ -584,7 +585,8 @@ static void qdev_propinfo_set_losttickpolicy(Object *obj, Visitor *v,
     int *ptr = object_field_prop_ptr(obj, prop);
     int value;
 
-    if (!visit_type_enum(v, name, &value, prop->info->enum_table, errp)) {
+    if (!visit_type_enum(v, name, &value,
+                         qdev_propinfo_enum_lookup(prop->info), errp)) {
         return;
     }
 
@@ -604,9 +606,8 @@ static void qdev_propinfo_set_losttickpolicy(Object *obj, Visitor *v,
 QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
 
 const PropertyInfo qdev_prop_losttickpolicy = {
-    .type  = "LostTickPolicy",
+    .qapi_type = &LostTickPolicy_type_info,
     .description = "Policy for handling lost ticks (discard/delay/slew)",
-    .enum_table  = &LostTickPolicy_lookup,
     .get   = qdev_propinfo_get_enum,
     .set   = qdev_propinfo_set_losttickpolicy,
     .set_default_value = qdev_propinfo_set_default_value_enum,
@@ -631,7 +632,7 @@ static void set_blocksize(Object *obj, Visitor *v, const char *name,
 }
 
 const PropertyInfo qdev_prop_blocksize = {
-    .type  = "size",
+    .qapi_type = &size_type_info,
     .description = "A power of two between " MIN_BLOCK_SIZE_STR
                    " and " MAX_BLOCK_SIZE_STR,
     .get   = qdev_propinfo_get_size32,
@@ -644,9 +645,8 @@ const PropertyInfo qdev_prop_blocksize = {
 QEMU_BUILD_BUG_ON(sizeof(BlockdevOnError) != sizeof(int));
 
 const PropertyInfo qdev_prop_blockdev_on_error = {
-    .type = "BlockdevOnError",
+    .qapi_type = &BlockdevOnError_type_info,
     .description = "Error handling policy (report/ignore/enospc/stop/auto)",
-    .enum_table = &BlockdevOnError_lookup,
     .get = qdev_propinfo_get_enum,
     .set = qdev_propinfo_set_enum,
     .set_default_value = qdev_propinfo_set_default_value_enum,
@@ -657,10 +657,9 @@ const PropertyInfo qdev_prop_blockdev_on_error = {
 QEMU_BUILD_BUG_ON(sizeof(BiosAtaTranslation) != sizeof(int));
 
 const PropertyInfo qdev_prop_bios_chs_trans = {
-    .type = "BiosAtaTranslation",
+    .qapi_type = &BiosAtaTranslation_type_info,
     .description = "Logical CHS translation algorithm "
                    " (auto/none/lba/large/rechs)",
-    .enum_table = &BiosAtaTranslation_lookup,
     .get = qdev_propinfo_get_enum,
     .set = qdev_propinfo_set_enum,
     .set_default_value = qdev_propinfo_set_default_value_enum,
@@ -669,9 +668,8 @@ const PropertyInfo qdev_prop_bios_chs_trans = {
 /* --- FDC default drive types */
 
 const PropertyInfo qdev_prop_fdc_drive_type = {
-    .type = "FloppyDriveType",
+    .qapi_type = &FloppyDriveType_type_info,
     .description = "Floppy drive type (144/288/120/none/auto)",
-    .enum_table = &FloppyDriveType_lookup,
     .get = qdev_propinfo_get_enum,
     .set = qdev_propinfo_set_enum,
     .set_default_value = qdev_propinfo_set_default_value_enum,
@@ -680,10 +678,9 @@ const PropertyInfo qdev_prop_fdc_drive_type = {
 /* --- MultiFDCompression --- */
 
 const PropertyInfo qdev_prop_multifd_compression = {
-    .type = "MultiFDCompression",
+    .qapi_type = &MultiFDCompression_type_info,
     .description = "multifd compression method"
                    " (none/zlib/zstd/qpl/uadk/qatzip)",
-    .enum_table = &MultiFDCompression_lookup,
     .get = qdev_propinfo_get_enum,
     .set = qdev_propinfo_set_enum,
     .set_default_value = qdev_propinfo_set_default_value_enum,
@@ -694,9 +691,8 @@ const PropertyInfo qdev_prop_multifd_compression = {
 QEMU_BUILD_BUG_ON(sizeof(MigMode) != sizeof(int));
 
 const PropertyInfo qdev_prop_mig_mode = {
-    .type = "MigMode",
+    .qapi_type = &MigMode_type_info,
     .description = "Migration mode (normal/cpr-reboot)",
-    .enum_table = &MigMode_lookup,
     .get = qdev_propinfo_get_enum,
     .set = qdev_propinfo_set_enum,
     .set_default_value = qdev_propinfo_set_default_value_enum,
@@ -707,18 +703,16 @@ const PropertyInfo qdev_prop_mig_mode = {
 QEMU_BUILD_BUG_ON(sizeof(GranuleMode) != sizeof(int));
 
 const PropertyInfo qdev_prop_granule_mode = {
-    .type = "GranuleMode",
+    .qapi_type = &GranuleMode_type_info,
     .description = "Granule page size (4k/8k/16k/64k/host)",
-    .enum_table = &GranuleMode_lookup,
     .get = qdev_propinfo_get_enum,
     .set = qdev_propinfo_set_enum,
     .set_default_value = qdev_propinfo_set_default_value_enum,
 };
 
 const PropertyInfo qdev_prop_zero_page_detection = {
-    .type = "ZeroPageDetection",
+    .qapi_type = &ZeroPageDetection_type_info,
     .description = "Zero page detection (none/legacy/multifd)",
-    .enum_table = &ZeroPageDetection_lookup,
     .get = qdev_propinfo_get_enum,
     .set = qdev_propinfo_set_enum,
     .set_default_value = qdev_propinfo_set_default_value_enum,
@@ -729,9 +723,8 @@ const PropertyInfo qdev_prop_zero_page_detection = {
 QEMU_BUILD_BUG_ON(sizeof(SsidSizeMode) != sizeof(int));
 
 const PropertyInfo qdev_prop_ssidsize_mode = {
-    .type = "SsidSizeMode",
+    .qapi_type = &SsidSizeMode_type_info,
     .description = "ssidsize mode: auto, 0-20",
-    .enum_table = &SsidSizeMode_lookup,
     .get = qdev_propinfo_get_enum,
     .set = qdev_propinfo_set_enum,
     .set_default_value = qdev_propinfo_set_default_value_enum,
@@ -742,9 +735,8 @@ const PropertyInfo qdev_prop_ssidsize_mode = {
 QEMU_BUILD_BUG_ON(sizeof(OasMode) != sizeof(int));
 
 const PropertyInfo qdev_prop_oas_mode = {
-    .type = "OasMode",
+    .qapi_type = &OasMode_type_info,
     .description = "oas mode: auto, 32, 36, 40, 42, 44, 48, 52, 56",
-    .enum_table = &OasMode_lookup,
     .get = qdev_propinfo_get_enum,
     .set = qdev_propinfo_set_enum,
     .set_default_value = qdev_propinfo_set_default_value_enum,
@@ -824,7 +816,7 @@ out:
 }
 
 const PropertyInfo qdev_prop_reserved_region = {
-    .type  = "str",
+    .qapi_type = &str_type_info,
     .description = "Reserved Region, example: 0xFEE00000:0xFEEFFFFF:0",
     .get   = get_reserved_region,
     .set   = set_reserved_region,
@@ -904,7 +896,7 @@ static char *print_pci_devfn(Object *obj, const Property *prop)
 }
 
 const PropertyInfo qdev_prop_pci_devfn = {
-    .type  = "str",
+    .qapi_type = &str_type_info,
     .description = "Slot and optional function number, example: 06.0 or 06",
     .print = print_pci_devfn,
     .get   = qdev_propinfo_get_int32,
@@ -1010,7 +1002,7 @@ inval:
 }
 
 const PropertyInfo qdev_prop_pci_host_devaddr = {
-    .type = "str",
+    .qapi_type = &str_type_info,
     .description = "Address (bus:device.function) of "
                    "the host device, example: 04:10.0",
     .get = get_pci_host_devaddr,
@@ -1020,9 +1012,8 @@ const PropertyInfo qdev_prop_pci_host_devaddr = {
 /* --- OffAutoPCIBAR off/auto/bar0/bar1/bar2/bar3/bar4/bar5 --- */
 
 const PropertyInfo qdev_prop_off_auto_pcibar = {
-    .type = "OffAutoPCIBAR",
+    .qapi_type = &OffAutoPCIBAR_type_info,
     .description = "off/auto/bar0/bar1/bar2/bar3/bar4/bar5",
-    .enum_table = &OffAutoPCIBAR_lookup,
     .get = qdev_propinfo_get_enum,
     .set = qdev_propinfo_set_enum,
     .set_default_value = qdev_propinfo_set_default_value_enum,
@@ -1061,7 +1052,8 @@ static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
         abort();
     }
 
-    visit_type_enum(v, name, &speed, prop->info->enum_table, errp);
+    visit_type_enum(v, name, &speed,
+                    qdev_propinfo_enum_lookup(prop->info), errp);
 }
 
 static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
@@ -1071,8 +1063,8 @@ static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
     PCIExpLinkSpeed *p = object_field_prop_ptr(obj, prop);
     int speed;
 
-    if (!visit_type_enum(v, name, &speed, prop->info->enum_table,
-                         errp)) {
+    if (!visit_type_enum(v, name, &speed,
+        qdev_propinfo_enum_lookup(prop->info), errp)) {
         return;
     }
 
@@ -1102,9 +1094,8 @@ static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
 }
 
 const PropertyInfo qdev_prop_pcie_link_speed = {
-    .type = "PCIELinkSpeed",
+    .qapi_type = &PCIELinkSpeed_type_info,
     .description = "2_5/5/8/16/32/64",
-    .enum_table = &PCIELinkSpeed_lookup,
     .get = get_prop_pcielinkspeed,
     .set = set_prop_pcielinkspeed,
     .set_default_value = qdev_propinfo_set_default_value_enum,
@@ -1146,7 +1137,8 @@ static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
         abort();
     }
 
-    visit_type_enum(v, name, &width, prop->info->enum_table, errp);
+    visit_type_enum(v, name, &width,
+                    qdev_propinfo_enum_lookup(prop->info), errp);
 }
 
 static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
@@ -1156,8 +1148,8 @@ static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
     PCIExpLinkWidth *p = object_field_prop_ptr(obj, prop);
     int width;
 
-    if (!visit_type_enum(v, name, &width, prop->info->enum_table,
-                         errp)) {
+    if (!visit_type_enum(v, name, &width,
+                         qdev_propinfo_enum_lookup(prop->info), errp)) {
         return;
     }
 
@@ -1190,9 +1182,8 @@ static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
 }
 
 const PropertyInfo qdev_prop_pcie_link_width = {
-    .type = "PCIELinkWidth",
+    .qapi_type = &PCIELinkWidth_type_info,
     .description = "1/2/4/8/12/16/32",
-    .enum_table = &PCIELinkWidth_lookup,
     .get = get_prop_pcielinkwidth,
     .set = set_prop_pcielinkwidth,
     .set_default_value = qdev_propinfo_set_default_value_enum,
@@ -1240,7 +1231,7 @@ static void set_default_uuid_auto(ObjectProperty *op, const Property *prop)
 }
 
 const PropertyInfo qdev_prop_uuid = {
-    .type  = "str",
+    .qapi_type = &str_type_info,
     .description = "UUID (aka GUID) or \"" UUID_VALUE_AUTO
         "\" for random value (default)",
     .get   = get_uuid,
@@ -1253,9 +1244,8 @@ const PropertyInfo qdev_prop_uuid = {
 QEMU_BUILD_BUG_ON(sizeof(S390CpuEntitlement) != sizeof(int));
 
 const PropertyInfo qdev_prop_cpus390entitlement = {
-    .type  = "S390CpuEntitlement",
+    .qapi_type = &S390CpuEntitlement_type_info,
     .description = "auto/low/medium/high (default medium)",
-    .enum_table  = &S390CpuEntitlement_lookup,
     .get   = qdev_propinfo_get_enum,
     .set   = qdev_propinfo_set_enum,
     .set_default_value = qdev_propinfo_set_default_value_enum,
@@ -1298,7 +1288,7 @@ static void release_iothread_vq_mapping_list(Object *obj,
 }
 
 const PropertyInfo qdev_prop_iothread_vq_mapping_list = {
-    .type = "IOThreadVirtQueueMappingList",
+    .qapi_type = &IOThreadVirtQueueMappingList_type_info,
     .description = "IOThread virtqueue mapping list [{\"iothread\":\"<id>\", "
                    "\"vqs\":[1,2,3,...]},...]",
     .get = get_iothread_vq_mapping_list,
@@ -1309,18 +1299,16 @@ const PropertyInfo qdev_prop_iothread_vq_mapping_list = {
 /* --- Endian modes */
 
 const PropertyInfo qdev_prop_endian_mode = {
-    .type = "EndianMode",
+    .qapi_type = &EndianMode_type_info,
     .description = "Endian mode, big/little/unspecified",
-    .enum_table = &EndianMode_lookup,
     .get = qdev_propinfo_get_enum,
     .set = qdev_propinfo_set_enum,
     .set_default_value = qdev_propinfo_set_default_value_enum,
 };
 
 const PropertyInfo qdev_prop_vmapple_virtio_blk_variant = {
-    .type  = "VMAppleVirtioBlkVariant",
+    .qapi_type = &VMAppleVirtioBlkVariant_type_info,
     .description = "unspecified/root/aux",
-    .enum_table  = &VMAppleVirtioBlkVariant_lookup,
     .get   = qdev_propinfo_get_enum,
     .set   = qdev_propinfo_set_enum,
     .set_default_value = qdev_propinfo_set_default_value_enum,
@@ -1363,7 +1351,7 @@ static void release_virtio_gpu_output_list(Object *obj,
 }
 
 const PropertyInfo qdev_prop_virtio_gpu_output_list = {
-    .type = "VirtIOGPUOutputList",
+    .qapi_type = &VirtIOGPUOutputList_type_info,
     .description = "VirtIO GPU output list [{\"name\":\"<name>\"},...]",
     .get = get_virtio_gpu_output_list,
     .set = set_virtio_gpu_output_list,
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 7e562518184..5edcca42056 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -101,7 +101,7 @@ static ObjectPropertyAccessor *field_prop_setter(const PropertyInfo *info)
     return info->set ? field_prop_set : NULL;
 }
 
-static const QEnumLookup *qdev_propinfo_enum_lookup(const PropertyInfo *info)
+const QEnumLookup *qdev_propinfo_enum_lookup(const PropertyInfo *info)
 {
     if (info->qapi_type) {
         assert(info->qapi_type->lookup);

-- 
2.54.0



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

* [PATCH 45/54] hw: convert device-local PropertyInfo definitions to use qapi_type
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (43 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 44/54] qdev: convert system " Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 46/54] target/riscv: fix incorrect QAPI types and u8 casting Marc-André Lureau
                   ` (9 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Mechanical conversion of PropertyInfo definitions in device-specific
files, replacing .type string with .qapi_type pointer to the
corresponding QAPITypeInfo.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/block/xen-block.c       | 3 ++-
 hw/misc/xlnx-versal-trng.c | 3 ++-
 hw/nvme/nguid.c            | 3 ++-
 hw/nvram/xlnx-bbram.c      | 3 ++-
 hw/nvram/xlnx-efuse.c      | 3 ++-
 hw/pci/pci.c               | 3 ++-
 hw/s390x/ccw-device.c      | 3 ++-
 hw/s390x/css.c             | 5 +++--
 hw/s390x/s390-pci-bus.c    | 3 ++-
 hw/vfio/pci-quirks.c       | 3 ++-
 hw/display/apple-gfx.m     | 3 ++-
 11 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
index 474c12fe4ac..d9721c565c5 100644
--- a/hw/block/xen-block.c
+++ b/hw/block/xen-block.c
@@ -29,6 +29,7 @@
 #include "dataplane/xen-block.h"
 #include "hw/xen/interface/io/xs_wire.h"
 #include "trace.h"
+#include "qapi/qapi-builtin-type-infos.h"
 
 #define XVDA_MAJOR 202
 #define XVDQ_MAJOR (1 << 20)
@@ -663,7 +664,7 @@ invalid:
  * https://xenbits.xen.org/docs/unstable/man/xen-vbd-interface.7.html
  */
 static const PropertyInfo xen_block_prop_vdev = {
-    .type  = "str",
+    .qapi_type = &str_type_info,
     .description = "Virtual Disk specifier (d*p*/xvd*/hd*/sd*)",
     .get = xen_block_get_vdev,
     .set = xen_block_set_vdev,
diff --git a/hw/misc/xlnx-versal-trng.c b/hw/misc/xlnx-versal-trng.c
index aa1d65de7b7..4c358104c50 100644
--- a/hw/misc/xlnx-versal-trng.c
+++ b/hw/misc/xlnx-versal-trng.c
@@ -36,6 +36,7 @@
 #include "qapi/visitor.h"
 #include "migration/vmstate.h"
 #include "hw/core/qdev-properties.h"
+#include "qapi/qapi-builtin-type-infos.h"
 
 #ifndef XLNX_VERSAL_TRNG_ERR_DEBUG
 #define XLNX_VERSAL_TRNG_ERR_DEBUG 0
@@ -651,7 +652,7 @@ static void trng_prop_fault_event_set(Object *obj, Visitor *v,
 }
 
 static const PropertyInfo trng_prop_fault_events = {
-    .type = "uint32",
+    .qapi_type = &uint32_type_info,
     .description = "Set to trigger TRNG fault events",
     .set = trng_prop_fault_event_set,
     .realized_set_allowed = true,
diff --git a/hw/nvme/nguid.c b/hw/nvme/nguid.c
index 4cd6fad6ac9..6eaf90fca88 100644
--- a/hw/nvme/nguid.c
+++ b/hw/nvme/nguid.c
@@ -18,6 +18,7 @@
 #include "qapi/visitor.h"
 #include "qemu/ctype.h"
 #include "nvme.h"
+#include "qapi/qapi-builtin-type-infos.h"
 
 #define NGUID_SEPARATOR '-'
 
@@ -179,7 +180,7 @@ static void set_nguid(Object *obj, Visitor *v, const char *name, void *opaque,
 }
 
 const PropertyInfo qdev_prop_nguid = {
-    .type  = "str",
+    .qapi_type = &str_type_info,
     .description =
         "NGUID or \"" NGUID_VALUE_AUTO "\" for random value",
     .get   = get_nguid,
diff --git a/hw/nvram/xlnx-bbram.c b/hw/nvram/xlnx-bbram.c
index edfb592a5ec..8198790b98f 100644
--- a/hw/nvram/xlnx-bbram.c
+++ b/hw/nvram/xlnx-bbram.c
@@ -34,6 +34,7 @@
 #include "hw/core/qdev-properties.h"
 #include "hw/core/qdev-properties-system.h"
 #include "hw/nvram/xlnx-efuse.h"
+#include "qapi/qapi-builtin-type-infos.h"
 
 #ifndef XLNX_BBRAM_ERR_DEBUG
 #define XLNX_BBRAM_ERR_DEBUG 0
@@ -486,7 +487,7 @@ static void bbram_prop_release_drive(Object *obj, const char *name,
 }
 
 static const PropertyInfo bbram_prop_drive = {
-    .type  = "str",
+    .qapi_type = &str_type_info,
     .description = "Node name or ID of a block device to use as BBRAM backend",
     .realized_set_allowed = true,
     .get = bbram_prop_get_drive,
diff --git a/hw/nvram/xlnx-efuse.c b/hw/nvram/xlnx-efuse.c
index 1a9650ba128..50a7f2baba1 100644
--- a/hw/nvram/xlnx-efuse.c
+++ b/hw/nvram/xlnx-efuse.c
@@ -34,6 +34,7 @@
 #include "system/blockdev.h"
 #include "hw/core/qdev-properties.h"
 #include "hw/core/qdev-properties-system.h"
+#include "qapi/qapi-builtin-type-infos.h"
 
 #define TBIT0_OFFSET     28
 #define TBIT1_OFFSET     29
@@ -251,7 +252,7 @@ static void efuse_prop_release_drive(Object *obj, const char *name,
 }
 
 static const PropertyInfo efuse_prop_drive = {
-    .type  = "str",
+    .qapi_type = &str_type_info,
     .description = "Node name or ID of a block device to use as eFUSE backend",
     .realized_set_allowed = true,
     .get = efuse_prop_get_drive,
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index c65cf6e089b..99c583f3aeb 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -52,6 +52,7 @@
 #include "qapi/error.h"
 #include "qemu/cutils.h"
 #include "pci-internal.h"
+#include "qapi/qapi-builtin-type-infos.h"
 
 #include "hw/xen/xen.h"
 #include "hw/i386/kvm/xen_evtchn.h"
@@ -72,7 +73,7 @@ static void prop_pci_busnr_get(Object *obj, Visitor *v, const char *name,
 }
 
 static const PropertyInfo prop_pci_busnr = {
-    .type = "uint8",
+    .qapi_type = &uint8_type_info,
     .get = prop_pci_busnr_get,
 };
 
diff --git a/hw/s390x/ccw-device.c b/hw/s390x/ccw-device.c
index 25c42732795..fd21a434652 100644
--- a/hw/s390x/ccw-device.c
+++ b/hw/s390x/ccw-device.c
@@ -17,6 +17,7 @@
 #include "qapi/visitor.h"
 #include "qemu/ctype.h"
 #include "qapi/error.h"
+#include "qapi/qapi-builtin-type-infos.h"
 
 static void ccw_device_refill_ids(CcwDevice *dev)
 {
@@ -74,7 +75,7 @@ static void ccw_device_set_loadparm(Object *obj, Visitor *v,
 }
 
 const PropertyInfo ccw_loadparm = {
-    .type  = "str",
+    .qapi_type = &str_type_info,
     .description = "Up to 8 chars in set of [A-Za-z0-9. ] to select"
             " a guest kernel",
     .get = ccw_device_get_loadparm,
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index ecd28fed5c3..541a53db2c1 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -23,6 +23,7 @@
 #include "hw/s390x/s390-virtio-ccw.h"
 #include "hw/s390x/s390-ccw.h"
 #include "exec/cpu-common.h"
+#include "qapi/qapi-builtin-type-infos.h"
 
 typedef struct CrwContainer {
     CRW crw;
@@ -2494,7 +2495,7 @@ out:
 }
 
 const PropertyInfo css_devid_propinfo = {
-    .type = "str",
+    .qapi_type = &str_type_info,
     .description = "Identifier of an I/O device in the channel "
                    "subsystem, example: fe.1.23ab",
     .get = get_css_devid,
@@ -2502,7 +2503,7 @@ const PropertyInfo css_devid_propinfo = {
 };
 
 const PropertyInfo css_devid_ro_propinfo = {
-    .type = "str",
+    .qapi_type = &str_type_info,
     .description = "Read-only identifier of an I/O device in the channel "
                    "subsystem, example: fe.1.23ab",
     .get = get_css_devid,
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 4de7b587e8a..6de5caab411 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -32,6 +32,7 @@
 #include "system/runstate.h"
 
 #include "trace.h"
+#include "qapi/qapi-builtin-type-infos.h"
 
 S390pciState *s390_get_phb(void)
 {
@@ -1540,7 +1541,7 @@ static void s390_pci_set_fid(Object *obj, Visitor *v, const char *name,
 }
 
 static const PropertyInfo s390_pci_fid_propinfo = {
-    .type = "uint32",
+    .qapi_type = &uint32_type_info,
     .description = "zpci_fid",
     .get = s390_pci_get_fid,
     .set = s390_pci_set_fid,
diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
index bccf31751fd..288bcab9f21 100644
--- a/hw/vfio/pci-quirks.c
+++ b/hw/vfio/pci-quirks.c
@@ -26,6 +26,7 @@
 #include "pci.h"
 #include "pci-quirks.h"
 #include "trace.h"
+#include "qapi/qapi-builtin-type-infos.h"
 
 /*
  * List of device ids/vendor ids for which to disable
@@ -1436,7 +1437,7 @@ static void set_nv_gpudirect_clique_id(Object *obj, Visitor *v,
 }
 
 const PropertyInfo qdev_prop_nv_gpudirect_clique = {
-    .type = "uint8",
+    .qapi_type = &uint8_type_info,
     .description = "NVIDIA GPUDirect Clique ID (0 - 15)",
     .get = get_nv_gpudirect_clique_id,
     .set = set_nv_gpudirect_clique_id,
diff --git a/hw/display/apple-gfx.m b/hw/display/apple-gfx.m
index 77d80fb7cef..982b7c6597d 100644
--- a/hw/display/apple-gfx.m
+++ b/hw/display/apple-gfx.m
@@ -15,6 +15,7 @@
 #include "qemu/lockable.h"
 #include "qemu/cutils.h"
 #include "qemu/log.h"
+#include "qapi/qapi-builtin-type-infos.h"
 #include "qapi/visitor.h"
 #include "qapi/error.h"
 #include "qemu/aio-wait.h"
@@ -871,7 +872,7 @@ static void apple_gfx_set_display_mode(Object *obj, Visitor *v,
 }
 
 const PropertyInfo qdev_prop_apple_gfx_display_mode = {
-    .type  = "display_mode",
+    .qapi_type = &str_type_info,
     .description =
         "Display mode in pixels and Hertz, as <width>x<height>@<refresh-rate> "
         "Example: 3840x2160@60",

-- 
2.54.0



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

* [PATCH 46/54] target/riscv: fix incorrect QAPI types and u8 casting
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (44 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 45/54] hw: convert device-local " Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-13  2:05   ` Alistair Francis
  2026-05-10 13:43 ` [PATCH 47/54] target/riscv: convert PropertyInfo definitions to use qapi_type Marc-André Lureau
                   ` (8 subsequent siblings)
  54 siblings, 1 reply; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

"pmu_num" is u8, "pmu_mask" is u32, so is "pmp-granularity"

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 target/riscv/cpu.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7d0cf88d48d..235764462cb 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1467,7 +1467,7 @@ static void prop_pmu_num_get(Object *obj, Visitor *v, const char *name,
 }
 
 static const PropertyInfo prop_pmu_num = {
-    .type = "int8",
+    .type = "uint8",
     .description = "pmu-num",
     .get = prop_pmu_num_get,
     .set = prop_pmu_num_set,
@@ -1503,13 +1503,13 @@ static void prop_pmu_mask_set(Object *obj, Visitor *v, const char *name,
 static void prop_pmu_mask_get(Object *obj, Visitor *v, const char *name,
                              void *opaque, Error **errp)
 {
-    uint8_t pmu_mask = RISCV_CPU(obj)->cfg.pmu_mask;
+    uint32_t pmu_mask = RISCV_CPU(obj)->cfg.pmu_mask;
 
-    visit_type_uint8(v, name, &pmu_mask, errp);
+    visit_type_uint32(v, name, &pmu_mask, errp);
 }
 
 static const PropertyInfo prop_pmu_mask = {
-    .type = "int8",
+    .type = "uint32",
     .description = "pmu-mask",
     .get = prop_pmu_mask_get,
     .set = prop_pmu_mask_set,
@@ -1651,6 +1651,7 @@ static void prop_pmp_granularity_get(Object *obj, Visitor *v, const char *name,
 }
 
 static const PropertyInfo prop_pmp_granularity = {
+    .type = "uint32",
     .description = "pmp-granularity",
     .get = prop_pmp_granularity_get,
     .set = prop_pmp_granularity_set,

-- 
2.54.0



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

* [PATCH 47/54] target/riscv: convert PropertyInfo definitions to use qapi_type
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (45 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 46/54] target/riscv: fix incorrect QAPI types and u8 casting Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-13  2:07   ` Alistair Francis
  2026-05-10 13:43 ` [PATCH 48/54] qdev: " Marc-André Lureau
                   ` (7 subsequent siblings)
  54 siblings, 1 reply; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Mechanical conversion of all local PropertyInfo definitions in
target/riscv/cpu.c

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 target/riscv/cpu.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 235764462cb..bd01884fb30 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1467,7 +1467,7 @@ static void prop_pmu_num_get(Object *obj, Visitor *v, const char *name,
 }
 
 static const PropertyInfo prop_pmu_num = {
-    .type = "uint8",
+    .qapi_type = &uint8_type_info,
     .description = "pmu-num",
     .get = prop_pmu_num_get,
     .set = prop_pmu_num_set,
@@ -1509,7 +1509,7 @@ static void prop_pmu_mask_get(Object *obj, Visitor *v, const char *name,
 }
 
 static const PropertyInfo prop_pmu_mask = {
-    .type = "uint32",
+    .qapi_type = &uint32_type_info,
     .description = "pmu-mask",
     .get = prop_pmu_mask_get,
     .set = prop_pmu_mask_set,
@@ -1541,7 +1541,7 @@ static void prop_mmu_get(Object *obj, Visitor *v, const char *name,
 }
 
 static const PropertyInfo prop_mmu = {
-    .type = "bool",
+    .qapi_type = &bool_type_info,
     .description = "mmu",
     .get = prop_mmu_get,
     .set = prop_mmu_set,
@@ -1573,7 +1573,7 @@ static void prop_pmp_get(Object *obj, Visitor *v, const char *name,
 }
 
 static const PropertyInfo prop_pmp = {
-    .type = "bool",
+    .qapi_type = &bool_type_info,
     .description = "pmp",
     .get = prop_pmp_get,
     .set = prop_pmp_set,
@@ -1613,7 +1613,7 @@ static void prop_num_pmp_regions_get(Object *obj, Visitor *v, const char *name,
 }
 
 static const PropertyInfo prop_num_pmp_regions = {
-    .type = "uint8",
+    .qapi_type = &uint8_type_info,
     .description = "num-pmp-regions",
     .get = prop_num_pmp_regions_get,
     .set = prop_num_pmp_regions_set,
@@ -1651,7 +1651,7 @@ static void prop_pmp_granularity_get(Object *obj, Visitor *v, const char *name,
 }
 
 static const PropertyInfo prop_pmp_granularity = {
-    .type = "uint32",
+    .qapi_type = &uint32_type_info,
     .description = "pmp-granularity",
     .get = prop_pmp_granularity_get,
     .set = prop_pmp_granularity_set,
@@ -1726,7 +1726,7 @@ static void prop_priv_spec_get(Object *obj, Visitor *v, const char *name,
 }
 
 static const PropertyInfo prop_priv_spec = {
-    .type = "str",
+    .qapi_type = &str_type_info,
     .description = "priv_spec",
     /* FIXME enum? */
     .get = prop_priv_spec_get,
@@ -1759,7 +1759,7 @@ static void prop_vext_spec_get(Object *obj, Visitor *v, const char *name,
 }
 
 static const PropertyInfo prop_vext_spec = {
-    .type = "str",
+    .qapi_type = &str_type_info,
     .description = "vext_spec",
     /* FIXME enum? */
     .get = prop_vext_spec_get,
@@ -1802,7 +1802,7 @@ static void prop_vlen_get(Object *obj, Visitor *v, const char *name,
 }
 
 static const PropertyInfo prop_vlen = {
-    .type = "uint16",
+    .qapi_type = &uint16_type_info,
     .description = "vlen",
     .get = prop_vlen_get,
     .set = prop_vlen_set,
@@ -1843,7 +1843,7 @@ static void prop_elen_get(Object *obj, Visitor *v, const char *name,
 }
 
 static const PropertyInfo prop_elen = {
-    .type = "uint16",
+    .qapi_type = &uint16_type_info,
     .description = "elen",
     .get = prop_elen_get,
     .set = prop_elen_set,
@@ -1879,7 +1879,7 @@ static void prop_cbom_blksize_get(Object *obj, Visitor *v, const char *name,
 }
 
 static const PropertyInfo prop_cbom_blksize = {
-    .type = "uint16",
+    .qapi_type = &uint16_type_info,
     .description = "cbom_blocksize",
     .get = prop_cbom_blksize_get,
     .set = prop_cbom_blksize_set,
@@ -1915,7 +1915,7 @@ static void prop_cbop_blksize_get(Object *obj, Visitor *v, const char *name,
 }
 
 static const PropertyInfo prop_cbop_blksize = {
-    .type = "uint16",
+    .qapi_type = &uint16_type_info,
     .description = "cbop_blocksize",
     .get = prop_cbop_blksize_get,
     .set = prop_cbop_blksize_set,
@@ -1951,7 +1951,7 @@ static void prop_cboz_blksize_get(Object *obj, Visitor *v, const char *name,
 }
 
 static const PropertyInfo prop_cboz_blksize = {
-    .type = "uint16",
+    .qapi_type = &uint16_type_info,
     .description = "cboz_blocksize",
     .get = prop_cboz_blksize_get,
     .set = prop_cboz_blksize_set,
@@ -1987,7 +1987,7 @@ static void prop_mvendorid_get(Object *obj, Visitor *v, const char *name,
 }
 
 static const PropertyInfo prop_mvendorid = {
-    .type = "uint32",
+    .qapi_type = &uint32_type_info,
     .description = "mvendorid",
     .get = prop_mvendorid_get,
     .set = prop_mvendorid_set,
@@ -2023,7 +2023,7 @@ static void prop_mimpid_get(Object *obj, Visitor *v, const char *name,
 }
 
 static const PropertyInfo prop_mimpid = {
-    .type = "uint64",
+    .qapi_type = &uint64_type_info,
     .description = "mimpid",
     .get = prop_mimpid_get,
     .set = prop_mimpid_set,
@@ -2080,7 +2080,7 @@ static void prop_marchid_get(Object *obj, Visitor *v, const char *name,
 }
 
 static const PropertyInfo prop_marchid = {
-    .type = "uint64",
+    .qapi_type = &uint64_type_info,
     .description = "marchid",
     .get = prop_marchid_get,
     .set = prop_marchid_set,

-- 
2.54.0



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

* [PATCH 48/54] qdev: convert PropertyInfo definitions to use qapi_type
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (46 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 47/54] target/riscv: convert PropertyInfo definitions to use qapi_type Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 49/54] qdev: introduce typed array PropertyInfos Marc-André Lureau
                   ` (6 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Convert the remaining PropertyInfo definitions outside hw/

After this patch, all PropertyInfo definitions have .qapi_type set,
except qdev_prop_link (uses .create) and qdev_prop_array (refactored
in the next patches).

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 backends/spdm-socket.c  | 4 ++--
 backends/tpm/tpm_util.c | 3 ++-
 migration/options.c     | 4 +++-
 target/sparc/cpu.c      | 3 ++-
 4 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/backends/spdm-socket.c b/backends/spdm-socket.c
index 826efc276dc..4a430797596 100644
--- a/backends/spdm-socket.c
+++ b/backends/spdm-socket.c
@@ -17,6 +17,7 @@
 #include "hw/core/qdev-properties.h"
 #include "hw/core/qdev-properties-system.h"
 #include "hw/core/qdev-prop-internal.h"
+#include "qapi/qapi-type-infos-sockets.h"
 
 static bool read_bytes(const int socket, uint8_t *buffer,
                        size_t number_of_bytes)
@@ -253,9 +254,8 @@ void spdm_socket_close(const int socket, SpdmTransportType transport_type)
 }
 
 const PropertyInfo qdev_prop_spdm_trans = {
-    .type = "SpdmTransportType",
+    .qapi_type = &SpdmTransportType_type_info,
     .description = "Spdm Transport, doe/nvme/mctp/scsi/unspecified",
-    .enum_table = &SpdmTransportType_lookup,
     .get = qdev_propinfo_get_enum,
     .set = qdev_propinfo_set_enum,
     .set_default_value = qdev_propinfo_set_default_value_enum,
diff --git a/backends/tpm/tpm_util.c b/backends/tpm/tpm_util.c
index 264bff22a91..ecbc771baa6 100644
--- a/backends/tpm/tpm_util.c
+++ b/backends/tpm/tpm_util.c
@@ -30,6 +30,7 @@
 #include "system/tpm_backend.h"
 #include "system/tpm_util.h"
 #include "trace.h"
+#include "qapi/qapi-builtin-type-infos.h"
 
 /* tpm backend property */
 
@@ -77,7 +78,7 @@ static void release_tpm(Object *obj, const char *name, void *opaque)
 }
 
 const PropertyInfo qdev_prop_tpm = {
-    .type  = "str",
+    .qapi_type = &str_type_info,
     .description = "ID of a tpm to use as a backend",
     .get   = get_tpm,
     .set   = set_tpm,
diff --git a/migration/options.c b/migration/options.c
index 5cbfd29099b..7ef7db667a8 100644
--- a/migration/options.c
+++ b/migration/options.c
@@ -31,6 +31,8 @@
 #include "ram.h"
 #include "options.h"
 #include "system/kvm.h"
+#include "qapi/qapi-builtin-type-infos.h"
+#include "qapi/qapi-type-infos-common.h"
 
 /* Maximum migrate downtime set to 2000 seconds */
 #define MAX_MIGRATE_DOWNTIME_SECONDS 2000
@@ -285,7 +287,7 @@ static void set_default_value_tls_opt(ObjectProperty *op, const Property *prop)
  * TYPE_MIGRATION's TLS options.
  */
 const PropertyInfo qdev_prop_StrOrNull = {
-    .type  = "StrOrNull",
+    .qapi_type = &StrOrNull_type_info,
     .get = get_StrOrNull,
     .set = set_StrOrNull,
     .release = release_StrOrNull,
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index c6989229da6..463eb34f354 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -29,6 +29,7 @@
 #include "tcg/tcg.h"
 #include "fpu/softfloat.h"
 #include "target/sparc/translate.h"
+#include "qapi/qapi-builtin-type-infos.h"
 
 //#define DEBUG_FEATURES
 
@@ -947,7 +948,7 @@ static void sparc_set_nwindows(Object *obj, Visitor *v, const char *name,
 }
 
 static const PropertyInfo qdev_prop_nwindows = {
-    .type  = "int",
+    .qapi_type = &int_type_info,
     .description = "Number of register windows",
     .get   = sparc_get_nwindows,
     .set   = sparc_set_nwindows,

-- 
2.54.0



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

* [PATCH 49/54] qdev: introduce typed array PropertyInfos
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (47 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 48/54] qdev: " Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 50/54] qdev: simplify DEFINE_PROP_ARRAY and remove generic array PropertyInfo Marc-André Lureau
                   ` (5 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Add element_info and element_size fields to PropertyInfo, and extend
qdev_prop_qapi_type() to derive QAPI types for array properties via
element_info->qapi_type->list.

Add typed list PropertyInfo definitions that replace the generic
qdev_prop_array. Each typed list PropertyInfo knows its element type
at compile time through the element_info and element_size fields,
which allows the QAPI type to be derived automatically.

Infrastructure changes:
- Add prop_array_info() and prop_array_elem_size() helpers that
  prefer the new element_info/element_size fields with fallback to
  the old arrayinfo/arrayfieldsize fields for compatibility
- Make get_prop_array, set_prop_array, release_prop_array, and
  default_prop_array non-static so they can be used by
  DEFINE_PROP_ARRAY_INFO in other translation units
- Add DEFINE_PROP_ARRAY_INFO macro in qdev-prop-internal.h

New typed list PropertyInfos:
- qdev_prop_uint8_list, qdev_prop_uint16_list, qdev_prop_uint32_list,
  qdev_prop_uint64_list, qdev_prop_string_list (in qdev-properties.c)
- qdev_prop_netdev_list, qdev_prop_reserved_region_list
  (in qdev-properties-system.c)

The old qdev_prop_array and DEFINE_PROP_ARRAY macro are preserved
for compatibility; they will be replaced in the next patch.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/core/qdev-prop-internal.h             | 18 +++++++
 include/hw/core/qdev-properties-system.h |  2 +
 include/hw/core/qdev-properties.h        |  7 +++
 hw/core/qdev-properties-system.c         |  5 ++
 hw/core/qdev-properties.c                | 82 ++++++++++++++++++++++++--------
 5 files changed, 93 insertions(+), 21 deletions(-)

diff --git a/hw/core/qdev-prop-internal.h b/hw/core/qdev-prop-internal.h
index c190b7b88cf..b9d9812346d 100644
--- a/hw/core/qdev-prop-internal.h
+++ b/hw/core/qdev-prop-internal.h
@@ -27,4 +27,22 @@ void qdev_propinfo_get_int32(Object *obj, Visitor *v, const char *name,
 void qdev_propinfo_get_size32(Object *obj, Visitor *v, const char *name,
                               void *opaque, Error **errp);
 
+void get_prop_array(Object *obj, Visitor *v, const char *name,
+                    void *opaque, Error **errp);
+void set_prop_array(Object *obj, Visitor *v, const char *name,
+                    void *opaque, Error **errp);
+void release_prop_array(Object *obj, const char *name, void *opaque);
+void default_prop_array(ObjectProperty *op, const Property *prop);
+
+/* .qapi_type is derived from element_info->qapi_type->list by qdev_prop_qapi_type() */
+#define DEFINE_PROP_ARRAY_INFO(_elem_prop_info, _elem_type) \
+    {                                                       \
+        .element_info = &(_elem_prop_info),                 \
+        .element_size = sizeof(_elem_type),                 \
+        .get = get_prop_array,                              \
+        .set = set_prop_array,                              \
+        .release = release_prop_array,                      \
+        .set_default_value = default_prop_array,            \
+    }
+
 #endif
diff --git a/include/hw/core/qdev-properties-system.h b/include/hw/core/qdev-properties-system.h
index 2cbea16d615..819dce7d5e5 100644
--- a/include/hw/core/qdev-properties-system.h
+++ b/include/hw/core/qdev-properties-system.h
@@ -23,6 +23,8 @@ extern const PropertyInfo qdev_prop_fdc_drive_type;
 extern const PropertyInfo qdev_prop_drive;
 extern const PropertyInfo qdev_prop_drive_iothread;
 extern const PropertyInfo qdev_prop_netdev;
+extern const PropertyInfo qdev_prop_netdev_list;
+extern const PropertyInfo qdev_prop_reserved_region_list;
 extern const PropertyInfo qdev_prop_pci_devfn;
 extern const PropertyInfo qdev_prop_blocksize;
 extern const PropertyInfo qdev_prop_pci_host_devaddr;
diff --git a/include/hw/core/qdev-properties.h b/include/hw/core/qdev-properties.h
index 441f77a501d..14db07cf9f4 100644
--- a/include/hw/core/qdev-properties.h
+++ b/include/hw/core/qdev-properties.h
@@ -35,6 +35,8 @@ struct PropertyInfo {
     const char *description;
     const QEnumLookup *enum_table;
     const QAPITypeInfo *qapi_type;
+    const struct PropertyInfo *element_info;
+    int element_size;
     bool realized_set_allowed; /* allow setting property on realized device */
     char *(*print)(Object *obj, const Property *prop);
     void (*set_default_value)(ObjectProperty *op, const Property *prop);
@@ -75,6 +77,11 @@ extern const PropertyInfo qdev_prop_string;
 extern const PropertyInfo qdev_prop_on_off_auto;
 extern const PropertyInfo qdev_prop_size32;
 extern const PropertyInfo qdev_prop_array;
+extern const PropertyInfo qdev_prop_uint8_list;
+extern const PropertyInfo qdev_prop_uint16_list;
+extern const PropertyInfo qdev_prop_uint32_list;
+extern const PropertyInfo qdev_prop_uint64_list;
+extern const PropertyInfo qdev_prop_string_list;
 extern const PropertyInfo qdev_prop_link;
 
 #define DEFINE_PROP(_name, _state, _field, _prop, _type, ...) {  \
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 12be7b80a59..81f37ec44b2 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -484,6 +484,8 @@ const PropertyInfo qdev_prop_netdev = {
     .set   = set_netdev,
 };
 
+const PropertyInfo qdev_prop_netdev_list =
+    DEFINE_PROP_ARRAY_INFO(qdev_prop_netdev, NICPeers);
 
 /* --- audiodev --- */
 static void get_audiodev(Object *obj, Visitor *v, const char* name,
@@ -822,6 +824,9 @@ const PropertyInfo qdev_prop_reserved_region = {
     .set   = set_reserved_region,
 };
 
+const PropertyInfo qdev_prop_reserved_region_list =
+    DEFINE_PROP_ARRAY_INFO(qdev_prop_reserved_region, ReservedRegion);
+
 /* --- pci address --- */
 
 /*
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 5edcca42056..2860de1d010 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -665,6 +665,22 @@ struct ArrayElementList {
     void *value;
 };
 
+static const PropertyInfo *prop_array_info(const Property *prop)
+{
+    if (prop->info->element_info) {
+        return prop->info->element_info;
+    }
+    return prop->arrayinfo;
+}
+
+static int prop_array_elem_size(const Property *prop)
+{
+    if (prop->info->element_size) {
+        return prop->info->element_size;
+    }
+    return prop->arrayfieldsize;
+}
+
 /*
  * Given an array property @parent_prop in @obj, return a Property for a
  * specific element of the array. Arrays are backed by an uint32_t length field
@@ -674,7 +690,7 @@ static Property array_elem_prop(Object *obj, const Property *parent_prop,
                                 const char *name, char *elem)
 {
     return (Property) {
-        .info = parent_prop->arrayinfo,
+        .info = prop_array_info(parent_prop),
         .name = name,
         /*
          * This ugly piece of pointer arithmetic sets up the offset so
@@ -691,19 +707,21 @@ static Property array_elem_prop(Object *obj, const Property *parent_prop,
  * underlying element's property release hook for each element and free the
  * property array.
  */
-static void release_prop_array(Object *obj, const char *name, void *opaque)
+void release_prop_array(Object *obj, const char *name, void *opaque)
 {
     const Property *prop = opaque;
     uint32_t *alenptr = object_field_prop_ptr(obj, prop);
     void **arrayptr = (void *)obj + prop->arrayoffset;
     char *elem = *arrayptr;
     int i;
+    const PropertyInfo *elem_info = prop_array_info(prop);
+    int elem_size = prop_array_elem_size(prop);
 
-    if (prop->arrayinfo->release) {
+    if (elem_info->release) {
         for (i = 0; i < *alenptr; i++) {
             Property elem_prop = array_elem_prop(obj, prop, name, elem);
-            prop->arrayinfo->release(obj, NULL, &elem_prop);
-            elem += prop->arrayfieldsize;
+            elem_info->release(obj, NULL, &elem_prop);
+            elem += elem_size;
         }
     }
 
@@ -717,8 +735,8 @@ static void release_prop_array(Object *obj, const char *name, void *opaque)
  * (a pointer to which is stored in the additional field described by
  * prop->arrayoffset).
  */
-static void set_prop_array(Object *obj, Visitor *v, const char *name,
-                           void *opaque, Error **errp)
+void set_prop_array(Object *obj, Visitor *v, const char *name,
+                    void *opaque, Error **errp)
 {
     ERRP_GUARD();
     const Property *prop = opaque;
@@ -726,6 +744,8 @@ static void set_prop_array(Object *obj, Visitor *v, const char *name,
     void **arrayptr = (void *)obj + prop->arrayoffset;
     ArrayElementList *list, *elem, *next;
     const size_t size = sizeof(*list);
+    const PropertyInfo *elem_info = prop_array_info(prop);
+    int elem_size = prop_array_elem_size(prop);
     char *elemptr;
     bool ok = true;
 
@@ -744,9 +764,9 @@ static void set_prop_array(Object *obj, Visitor *v, const char *name,
     while (elem) {
         Property elem_prop;
 
-        elem->value = g_malloc0(prop->arrayfieldsize);
+        elem->value = g_malloc0(elem_size);
         elem_prop = array_elem_prop(obj, prop, name, elem->value);
-        prop->arrayinfo->set(obj, v, NULL, &elem_prop, errp);
+        elem_info->set(obj, v, NULL, &elem_prop, errp);
         if (*errp) {
             ok = false;
             goto out_obj;
@@ -768,8 +788,8 @@ out_obj:
         for (elem = list; elem; elem = next) {
             Property elem_prop = array_elem_prop(obj, prop, name,
                                                  elem->value);
-            if (prop->arrayinfo->release) {
-                prop->arrayinfo->release(obj, NULL, &elem_prop);
+            if (elem_info->release) {
+                elem_info->release(obj, NULL, &elem_prop);
             }
             next = elem->next;
             g_free(elem->value);
@@ -782,19 +802,19 @@ out_obj:
      * Now that we know how big the array has to be, move the data over to a
      * linear array and free the temporary list.
      */
-    *arrayptr = g_malloc_n(*alenptr, prop->arrayfieldsize);
+    *arrayptr = g_malloc_n(*alenptr, elem_size);
     elemptr = *arrayptr;
     for (elem = list; elem; elem = next) {
-        memcpy(elemptr, elem->value, prop->arrayfieldsize);
-        elemptr += prop->arrayfieldsize;
+        memcpy(elemptr, elem->value, elem_size);
+        elemptr += elem_size;
         next = elem->next;
         g_free(elem->value);
         g_free(elem);
     }
 }
 
-static void get_prop_array(Object *obj, Visitor *v, const char *name,
-                           void *opaque, Error **errp)
+void get_prop_array(Object *obj, Visitor *v, const char *name,
+                    void *opaque, Error **errp)
 {
     ERRP_GUARD();
     const Property *prop = opaque;
@@ -804,6 +824,8 @@ static void get_prop_array(Object *obj, Visitor *v, const char *name,
     ArrayElementList *list = NULL, *elem;
     ArrayElementList **tail = &list;
     const size_t size = sizeof(*list);
+    const PropertyInfo *elem_info = prop_array_info(prop);
+    int elem_size = prop_array_elem_size(prop);
     int i;
     bool ok;
 
@@ -811,7 +833,7 @@ static void get_prop_array(Object *obj, Visitor *v, const char *name,
     for (i = 0; i < *alenptr; i++) {
         elem = g_new0(ArrayElementList, 1);
         elem->value = elemptr;
-        elemptr += prop->arrayfieldsize;
+        elemptr += elem_size;
 
         *tail = elem;
         tail = &elem->next;
@@ -824,7 +846,7 @@ static void get_prop_array(Object *obj, Visitor *v, const char *name,
     elem = list;
     while (elem) {
         Property elem_prop = array_elem_prop(obj, prop, name, elem->value);
-        prop->arrayinfo->get(obj, v, NULL, &elem_prop, errp);
+        elem_info->get(obj, v, NULL, &elem_prop, errp);
         if (*errp) {
             goto out_obj;
         }
@@ -846,7 +868,7 @@ out_obj:
     }
 }
 
-static void default_prop_array(ObjectProperty *op, const Property *prop)
+void default_prop_array(ObjectProperty *op, const Property *prop)
 {
     object_property_set_default_list(op);
 }
@@ -859,6 +881,17 @@ const PropertyInfo qdev_prop_array = {
     .set_default_value = default_prop_array,
 };
 
+const PropertyInfo qdev_prop_uint8_list =
+    DEFINE_PROP_ARRAY_INFO(qdev_prop_uint8, uint8_t);
+const PropertyInfo qdev_prop_uint16_list =
+    DEFINE_PROP_ARRAY_INFO(qdev_prop_uint16, uint16_t);
+const PropertyInfo qdev_prop_uint32_list =
+    DEFINE_PROP_ARRAY_INFO(qdev_prop_uint32, uint32_t);
+const PropertyInfo qdev_prop_uint64_list =
+    DEFINE_PROP_ARRAY_INFO(qdev_prop_uint64, uint64_t);
+const PropertyInfo qdev_prop_string_list =
+    DEFINE_PROP_ARRAY_INFO(qdev_prop_string, char *);
+
 /* --- public helpers --- */
 
 static const Property *qdev_prop_walk(DeviceClass *cls, const char *name)
@@ -1080,8 +1113,15 @@ const PropertyInfo qdev_prop_link = {
 
 static const QAPITypeInfo *qdev_prop_qapi_type(const Property *prop)
 {
-    /* this will be later extended to cope with QAPI array properties */
-    return prop->info->qapi_type;
+    if (prop->info->qapi_type) {
+        return prop->info->qapi_type;
+    }
+    if (prop->info->element_info) {
+        assert(prop->info->element_info->qapi_type);
+        assert(prop->info->element_info->qapi_type->list);
+        return prop->info->element_info->qapi_type->list;
+    }
+    return NULL;
 }
 
 void qdev_property_add_static(DeviceState *dev, const Property *prop)

-- 
2.54.0



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

* [PATCH 50/54] qdev: simplify DEFINE_PROP_ARRAY and remove generic array PropertyInfo
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (48 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 49/54] qdev: introduce typed array PropertyInfos Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 51/54] qdev: remove deprecated PropertyInfo.type and .enum_table fields Marc-André Lureau
                   ` (4 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Change DEFINE_PROP_ARRAY, the macro now uses _arrayprop##_list to
resolve the typed list PropertyInfo (introduced in the previous patch)
instead of the generic qdev_prop_array.

This means the element type and size information is carried by the
PropertyInfo itself rather than duplicated at each callsite. Since
the typed list PropertyInfos encode element_info and element_size,
the .arrayinfo and .arrayfieldsize fields are no longer set by the
macro (they will be removed from the Property struct in the next patch).

Remove qdev_prop_array, which is now unused.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/display/apple-gfx.h            |  1 +
 include/hw/block/block.h          |  2 +-
 include/hw/core/qdev-properties.h | 17 +++++++----------
 hw/core/qdev-properties.c         |  8 --------
 hw/input/stellaris_gamepad.c      |  2 +-
 hw/intc/arm_gicv3_common.c        |  2 +-
 hw/intc/rx_icu.c                  |  4 ++--
 hw/misc/arm_sysctl.c              |  4 ++--
 hw/misc/mps2-scc.c                |  2 +-
 hw/net/rocker/rocker.c            |  2 +-
 hw/net/virtio-net.c               |  2 +-
 hw/nvram/xlnx-efuse.c             |  2 +-
 hw/nvram/xlnx-versal-efuse-ctrl.c |  2 +-
 hw/riscv/riscv_hart.c             |  6 ++----
 hw/virtio/virtio-iommu-pci.c      |  2 +-
 tests/unit/test-qdev.c            |  2 +-
 hw/display/apple-gfx-mmio.m       |  2 +-
 hw/display/apple-gfx-pci.m        |  2 +-
 hw/display/apple-gfx.m            |  4 ++++
 19 files changed, 30 insertions(+), 38 deletions(-)

diff --git a/hw/display/apple-gfx.h b/hw/display/apple-gfx.h
index 3197bd853da..b7eef7b9b14 100644
--- a/hw/display/apple-gfx.h
+++ b/hw/display/apple-gfx.h
@@ -69,6 +69,7 @@ void *apple_gfx_host_ptr_for_gpa_range(uint64_t guest_physical,
                                        MemoryRegion **mapping_in_region);
 
 extern const PropertyInfo qdev_prop_apple_gfx_display_mode;
+extern const PropertyInfo qdev_prop_apple_gfx_display_mode_list;
 
 #endif
 
diff --git a/include/hw/block/block.h b/include/hw/block/block.h
index 7dc19d8a453..d6b4492a27a 100644
--- a/include/hw/block/block.h
+++ b/include/hw/block/block.h
@@ -71,7 +71,7 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
                             _conf.account_failed, ON_OFF_AUTO_AUTO),    \
     DEFINE_PROP_ARRAY("stats-intervals", _state,                        \
                      _conf.num_stats_intervals, _conf.stats_intervals,  \
-                     qdev_prop_uint32, uint32_t)
+                     qdev_prop_uint32)
 
 #define DEFINE_BLOCK_PROPERTIES(_state, _conf)                          \
     DEFINE_PROP_DRIVE("drive", _state, _conf.blk),                      \
diff --git a/include/hw/core/qdev-properties.h b/include/hw/core/qdev-properties.h
index 14db07cf9f4..8dd80501fb8 100644
--- a/include/hw/core/qdev-properties.h
+++ b/include/hw/core/qdev-properties.h
@@ -76,7 +76,6 @@ extern const PropertyInfo qdev_prop_size;
 extern const PropertyInfo qdev_prop_string;
 extern const PropertyInfo qdev_prop_on_off_auto;
 extern const PropertyInfo qdev_prop_size32;
-extern const PropertyInfo qdev_prop_array;
 extern const PropertyInfo qdev_prop_uint8_list;
 extern const PropertyInfo qdev_prop_uint16_list;
 extern const PropertyInfo qdev_prop_uint32_list;
@@ -147,15 +146,15 @@ extern const PropertyInfo qdev_prop_link;
  * @_name: name of the array
  * @_state: name of the device state structure type
  * @_field: uint32_t field in @_state to hold the array length
- * @_arrayfield: field in @_state (of type '@_arraytype *') which
- *               will point to the array
- * @_arrayprop: PropertyInfo defining what property the array elements have
- * @_arraytype: C type of the array elements
+ * @_arrayfield: field in @_state which will point to the array
+ * @_arrayprop: PropertyInfo for the array elements (e.g. qdev_prop_uint32);
+ *              a corresponding list PropertyInfo named @_arrayprop##_list
+ *              must exist
  *
  * Define device properties for a variable-length array _name.  The array is
  * represented as a list in the visitor interface.
  *
- * @_arraytype is required to be movable with memcpy().
+ * The element type must be movable with memcpy().
  *
  * When the array property is set, the @_field member of the device
  * struct is set to the array length, and @_arrayfield is set to point
@@ -165,12 +164,10 @@ extern const PropertyInfo qdev_prop_link;
  * @_arrayfield memory.
  */
 #define DEFINE_PROP_ARRAY(_name, _state, _field,                        \
-                          _arrayfield, _arrayprop, _arraytype)          \
-    DEFINE_PROP(_name, _state, _field, qdev_prop_array, uint32_t,       \
+                          _arrayfield, _arrayprop)                      \
+    DEFINE_PROP(_name, _state, _field, _arrayprop##_list, uint32_t,     \
                 .set_default = true,                                    \
                 .defval.u = 0,                                          \
-                .arrayinfo = &(_arrayprop),                             \
-                .arrayfieldsize = sizeof(_arraytype),                   \
                 .arrayoffset = offsetof(_state, _arrayfield))
 
 #define DEFINE_PROP_LINK(_name, _state, _field, _type, _ptr_type)     \
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 2860de1d010..c9c29578d99 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -873,14 +873,6 @@ void default_prop_array(ObjectProperty *op, const Property *prop)
     object_property_set_default_list(op);
 }
 
-const PropertyInfo qdev_prop_array = {
-    .type = "list",
-    .get = get_prop_array,
-    .set = set_prop_array,
-    .release = release_prop_array,
-    .set_default_value = default_prop_array,
-};
-
 const PropertyInfo qdev_prop_uint8_list =
     DEFINE_PROP_ARRAY_INFO(qdev_prop_uint8, uint8_t);
 const PropertyInfo qdev_prop_uint16_list =
diff --git a/hw/input/stellaris_gamepad.c b/hw/input/stellaris_gamepad.c
index 42d43f9af51..0714aaff188 100644
--- a/hw/input/stellaris_gamepad.c
+++ b/hw/input/stellaris_gamepad.c
@@ -72,7 +72,7 @@ static void stellaris_gamepad_reset_enter(Object *obj, ResetType type)
 
 static const Property stellaris_gamepad_properties[] = {
     DEFINE_PROP_ARRAY("keycodes", StellarisGamepad, num_buttons,
-                      keycodes, qdev_prop_uint32, uint32_t),
+                      keycodes, qdev_prop_uint32),
 };
 
 static void stellaris_gamepad_class_init(ObjectClass *klass, const void *data)
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
index f7ba74e6d52..1298b6b735e 100644
--- a/hw/intc/arm_gicv3_common.c
+++ b/hw/intc/arm_gicv3_common.c
@@ -615,7 +615,7 @@ static const Property arm_gicv3_common_properties[] = {
      */
     DEFINE_PROP_BOOL("force-8-bit-prio", GICv3State, force_8bit_prio, 0),
     DEFINE_PROP_ARRAY("redist-region-count", GICv3State, nb_redist_regions,
-                      redist_region_count, qdev_prop_uint32, uint32_t),
+                      redist_region_count, qdev_prop_uint32),
     DEFINE_PROP_LINK("sysmem", GICv3State, dma, TYPE_MEMORY_REGION,
                      MemoryRegion *),
     DEFINE_PROP_UINT32("first-cpu-index", GICv3State, first_cpu_idx, 0),
diff --git a/hw/intc/rx_icu.c b/hw/intc/rx_icu.c
index 992b069ae24..125a6dcb680 100644
--- a/hw/intc/rx_icu.c
+++ b/hw/intc/rx_icu.c
@@ -356,9 +356,9 @@ static const VMStateDescription vmstate_rxicu = {
 
 static const Property rxicu_properties[] = {
     DEFINE_PROP_ARRAY("ipr-map", RXICUState, nr_irqs, map,
-                      qdev_prop_uint8, uint8_t),
+                      qdev_prop_uint8),
     DEFINE_PROP_ARRAY("trigger-level", RXICUState, nr_sense, init_sense,
-                      qdev_prop_uint8, uint8_t),
+                      qdev_prop_uint8),
 };
 
 static void rxicu_class_init(ObjectClass *klass, const void *data)
diff --git a/hw/misc/arm_sysctl.c b/hw/misc/arm_sysctl.c
index ebc95b9bb54..1df85593a5c 100644
--- a/hw/misc/arm_sysctl.c
+++ b/hw/misc/arm_sysctl.c
@@ -626,10 +626,10 @@ static const Property arm_sysctl_properties[] = {
     DEFINE_PROP_UINT32("proc_id", arm_sysctl_state, proc_id, 0),
     /* Daughterboard power supply voltages (as reported via SYS_CFG) */
     DEFINE_PROP_ARRAY("db-voltage", arm_sysctl_state, db_num_vsensors,
-                      db_voltage, qdev_prop_uint32, uint32_t),
+                      db_voltage, qdev_prop_uint32),
     /* Daughterboard clock reset values (as reported via SYS_CFG) */
     DEFINE_PROP_ARRAY("db-clock", arm_sysctl_state, db_num_clocks,
-                      db_clock_reset, qdev_prop_uint32, uint32_t),
+                      db_clock_reset, qdev_prop_uint32),
 };
 
 static void arm_sysctl_class_init(ObjectClass *klass, const void *data)
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
index 7877b31479c..5c77239d2cf 100644
--- a/hw/misc/mps2-scc.c
+++ b/hw/misc/mps2-scc.c
@@ -464,7 +464,7 @@ static const Property mps2_scc_properties[] = {
      * motherboard configuration controller to suit the FPGA image.
      */
     DEFINE_PROP_ARRAY("oscclk", MPS2SCC, num_oscclk, oscclk_reset,
-                      qdev_prop_uint32, uint32_t),
+                      qdev_prop_uint32),
 };
 
 static void mps2_scc_class_init(ObjectClass *klass, const void *data)
diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c
index 910dce901b6..afbc32e99d9 100644
--- a/hw/net/rocker/rocker.c
+++ b/hw/net/rocker/rocker.c
@@ -1466,7 +1466,7 @@ static const Property rocker_properties[] = {
     DEFINE_PROP_UINT64("switch_id", Rocker,
                        switch_id, 0),
     DEFINE_PROP_ARRAY("ports", Rocker, fp_ports,
-                      fp_ports_peers, qdev_prop_netdev, NICPeers),
+                      fp_ports_peers, qdev_prop_netdev),
 };
 
 static const VMStateDescription rocker_vmsd = {
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 2a5d642a647..092a262269a 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -4234,7 +4234,7 @@ static const Property virtio_net_properties[] = {
     DEFINE_PROP_BIT64("hash", VirtIONet, host_features,
                     VIRTIO_NET_F_HASH_REPORT, false),
     DEFINE_PROP_ARRAY("ebpf-rss-fds", VirtIONet, nr_ebpf_rss_fds,
-                      ebpf_rss_fds, qdev_prop_string, char*),
+                      ebpf_rss_fds, qdev_prop_string),
     DEFINE_PROP_BIT64("guest_rsc_ext", VirtIONet, host_features,
                     VIRTIO_NET_F_RSC_EXT, false),
     DEFINE_PROP_UINT32("rsc_interval", VirtIONet, rsc_timeout,
diff --git a/hw/nvram/xlnx-efuse.c b/hw/nvram/xlnx-efuse.c
index 50a7f2baba1..6514ee84caf 100644
--- a/hw/nvram/xlnx-efuse.c
+++ b/hw/nvram/xlnx-efuse.c
@@ -266,7 +266,7 @@ static const Property efuse_properties[] = {
     DEFINE_PROP_UINT32("efuse-size", XlnxEFuse, efuse_size, 64 * 32),
     DEFINE_PROP_BOOL("init-factory-tbits", XlnxEFuse, init_tbits, true),
     DEFINE_PROP_ARRAY("read-only", XlnxEFuse, ro_bits_cnt, ro_bits,
-                      qdev_prop_uint32, uint32_t),
+                      qdev_prop_uint32),
 };
 
 static void efuse_class_init(ObjectClass *klass, const void *data)
diff --git a/hw/nvram/xlnx-versal-efuse-ctrl.c b/hw/nvram/xlnx-versal-efuse-ctrl.c
index f5d5587cb65..101320b82fd 100644
--- a/hw/nvram/xlnx-versal-efuse-ctrl.c
+++ b/hw/nvram/xlnx-versal-efuse-ctrl.c
@@ -740,7 +740,7 @@ static const Property efuse_ctrl_props[] = {
                      TYPE_XLNX_EFUSE, XlnxEFuse *),
     DEFINE_PROP_ARRAY("pg0-lock",
                       XlnxVersalEFuseCtrl, extra_pg0_lock_n16,
-                      extra_pg0_lock_spec, qdev_prop_uint16, uint16_t),
+                      extra_pg0_lock_spec, qdev_prop_uint16),
 };
 
 static void efuse_ctrl_class_init(ObjectClass *klass, const void *data)
diff --git a/hw/riscv/riscv_hart.c b/hw/riscv/riscv_hart.c
index e675358e1a1..69d605c71e6 100644
--- a/hw/riscv/riscv_hart.c
+++ b/hw/riscv/riscv_hart.c
@@ -48,11 +48,9 @@ static const Property riscv_harts_props[] = {
      * defined by "rnmi-exception-vector".
      */
     DEFINE_PROP_ARRAY("rnmi-interrupt-vector", RISCVHartArrayState,
-                      num_rnmi_irqvec, rnmi_irqvec, qdev_prop_uint64,
-                      uint64_t),
+                      num_rnmi_irqvec, rnmi_irqvec, qdev_prop_uint64),
     DEFINE_PROP_ARRAY("rnmi-exception-vector", RISCVHartArrayState,
-                      num_rnmi_excpvec, rnmi_excpvec, qdev_prop_uint64,
-                      uint64_t),
+                      num_rnmi_excpvec, rnmi_excpvec, qdev_prop_uint64),
 };
 
 static void riscv_harts_cpu_reset(void *opaque)
diff --git a/hw/virtio/virtio-iommu-pci.c b/hw/virtio/virtio-iommu-pci.c
index 7b5ffddc1e9..1f3a07c5d11 100644
--- a/hw/virtio/virtio-iommu-pci.c
+++ b/hw/virtio/virtio-iommu-pci.c
@@ -38,7 +38,7 @@ static const Property virtio_iommu_pci_properties[] = {
     DEFINE_PROP_UINT32("class", VirtIOPCIProxy, class_code, 0),
     DEFINE_PROP_ARRAY("reserved-regions", VirtIOIOMMUPCI,
                       vdev.nr_prop_resv_regions, vdev.prop_resv_regions,
-                      qdev_prop_reserved_region, ReservedRegion),
+                      qdev_prop_reserved_region),
 };
 
 static void virtio_iommu_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
diff --git a/tests/unit/test-qdev.c b/tests/unit/test-qdev.c
index 20eae38e03f..1199b761a32 100644
--- a/tests/unit/test-qdev.c
+++ b/tests/unit/test-qdev.c
@@ -23,7 +23,7 @@ static const Property my_dev_props[] = {
     DEFINE_PROP_UINT32("u32", MyDev, prop_u32, 100),
     DEFINE_PROP_STRING("string", MyDev, prop_string),
     DEFINE_PROP_ARRAY("array-u32", MyDev, prop_array_u32_nb, prop_array_u32,
-                     qdev_prop_uint32, uint32_t),
+                     qdev_prop_uint32),
 };
 
 static void my_dev_class_init(ObjectClass *oc, const void *data)
diff --git a/hw/display/apple-gfx-mmio.m b/hw/display/apple-gfx-mmio.m
index 58beaadd1f1..dcd04617eb8 100644
--- a/hw/display/apple-gfx-mmio.m
+++ b/hw/display/apple-gfx-mmio.m
@@ -258,7 +258,7 @@ static void apple_gfx_mmio_reset(Object *obj, ResetType type)
 static const Property apple_gfx_mmio_properties[] = {
     DEFINE_PROP_ARRAY("display-modes", AppleGFXMMIOState,
                       common.num_display_modes, common.display_modes,
-                      qdev_prop_apple_gfx_display_mode, AppleGFXDisplayMode),
+                      qdev_prop_apple_gfx_display_mode),
 };
 
 static void apple_gfx_mmio_class_init(ObjectClass *klass, const void *data)
diff --git a/hw/display/apple-gfx-pci.m b/hw/display/apple-gfx-pci.m
index b0694f4cb85..74f79c8b157 100644
--- a/hw/display/apple-gfx-pci.m
+++ b/hw/display/apple-gfx-pci.m
@@ -118,7 +118,7 @@ static void apple_gfx_pci_reset(Object *obj, ResetType type)
 static const Property apple_gfx_pci_properties[] = {
     DEFINE_PROP_ARRAY("display-modes", AppleGFXPCIState,
                       common.num_display_modes, common.display_modes,
-                      qdev_prop_apple_gfx_display_mode, AppleGFXDisplayMode),
+                      qdev_prop_apple_gfx_display_mode),
 };
 
 static void apple_gfx_pci_class_init(ObjectClass *klass, const void *data)
diff --git a/hw/display/apple-gfx.m b/hw/display/apple-gfx.m
index 982b7c6597d..f9314eff748 100644
--- a/hw/display/apple-gfx.m
+++ b/hw/display/apple-gfx.m
@@ -16,6 +16,7 @@
 #include "qemu/cutils.h"
 #include "qemu/log.h"
 #include "qapi/qapi-builtin-type-infos.h"
+#include "hw/core/qdev-prop-internal.h"
 #include "qapi/visitor.h"
 #include "qapi/error.h"
 #include "qemu/aio-wait.h"
@@ -879,3 +880,6 @@ static void apple_gfx_set_display_mode(Object *obj, Visitor *v,
     .get   = apple_gfx_get_display_mode,
     .set   = apple_gfx_set_display_mode,
 };
+
+const PropertyInfo qdev_prop_apple_gfx_display_mode_list =
+    DEFINE_PROP_ARRAY_INFO(qdev_prop_apple_gfx_display_mode, AppleGFXDisplayMode);

-- 
2.54.0



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

* [PATCH 51/54] qdev: remove deprecated PropertyInfo.type and .enum_table fields
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (49 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 50/54] qdev: simplify DEFINE_PROP_ARRAY and remove generic array PropertyInfo Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 52/54] memory: use object_property_add_link for container property Marc-André Lureau
                   ` (3 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Now that all PropertyInfo definitions use .qapi_type, remove the
legacy .type (string) and .enum_table fields from PropertyInfo, and
the .arrayinfo/.arrayfieldsize fields from Property.

Remove fallback branches in qdev_property_add_static() and
qdev_class_add_property() that used object_property_add() with
prop->info->type — these always use the QAPI-aware registration
path now. Simplify qdev_propinfo_enum_lookup(), prop_array_info()
and prop_array_elem_size() to use the new fields directly.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/hw/core/qdev-properties.h |  4 ---
 hw/core/qdev-properties.c         | 59 +++++++++++----------------------------
 2 files changed, 17 insertions(+), 46 deletions(-)

diff --git a/include/hw/core/qdev-properties.h b/include/hw/core/qdev-properties.h
index 8dd80501fb8..937b11dad09 100644
--- a/include/hw/core/qdev-properties.h
+++ b/include/hw/core/qdev-properties.h
@@ -23,17 +23,13 @@ struct Property {
         int64_t i;
         uint64_t u;
     } defval;
-    const PropertyInfo *arrayinfo;
     int          arrayoffset;
-    int          arrayfieldsize;
     uint8_t      bitnr;
     bool         set_default;
 };
 
 struct PropertyInfo {
-    const char *type;
     const char *description;
-    const QEnumLookup *enum_table;
     const QAPITypeInfo *qapi_type;
     const struct PropertyInfo *element_info;
     int element_size;
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index c9c29578d99..bcf72222d8d 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -103,11 +103,8 @@ static ObjectPropertyAccessor *field_prop_setter(const PropertyInfo *info)
 
 const QEnumLookup *qdev_propinfo_enum_lookup(const PropertyInfo *info)
 {
-    if (info->qapi_type) {
-        assert(info->qapi_type->lookup);
-        return info->qapi_type->lookup;
-    }
-    return info->enum_table;
+    assert(info->qapi_type->lookup);
+    return info->qapi_type->lookup;
 }
 
 void qdev_propinfo_get_enum(Object *obj, Visitor *v, const char *name,
@@ -667,18 +664,12 @@ struct ArrayElementList {
 
 static const PropertyInfo *prop_array_info(const Property *prop)
 {
-    if (prop->info->element_info) {
-        return prop->info->element_info;
-    }
-    return prop->arrayinfo;
+    return prop->info->element_info;
 }
 
 static int prop_array_elem_size(const Property *prop)
 {
-    if (prop->info->element_size) {
-        return prop->info->element_size;
-    }
-    return prop->arrayfieldsize;
+    return prop->info->element_size;
 }
 
 /*
@@ -1099,7 +1090,6 @@ static ObjectProperty *create_link_property(ObjectClass *oc, const char *name,
 }
 
 const PropertyInfo qdev_prop_link = {
-    .type = "link",
     .create = create_link_property,
 };
 
@@ -1123,20 +1113,13 @@ void qdev_property_add_static(DeviceState *dev, const Property *prop)
     const QAPITypeInfo *qapi_type = qdev_prop_qapi_type(prop);
 
     assert(!prop->info->create);
+    assert(qapi_type);
 
-    if (qapi_type) {
-        op = object_property_add_qapi(obj, prop->name, qapi_type,
-                                      field_prop_getter(prop->info),
-                                      field_prop_setter(prop->info),
-                                      prop->info->release,
-                                      (Property *)prop);
-    } else {
-        op = object_property_add(obj, prop->name, prop->info->type,
-                                 field_prop_getter(prop->info),
-                                 field_prop_setter(prop->info),
-                                 prop->info->release,
-                                 (Property *)prop);
-    }
+    op = object_property_add_qapi(obj, prop->name, qapi_type,
+                                  field_prop_getter(prop->info),
+                                  field_prop_setter(prop->info),
+                                  prop->info->release,
+                                  (Property *)prop);
 
     object_property_set_description(obj, prop->name,
                                     prop->info->description);
@@ -1160,21 +1143,13 @@ static void qdev_class_add_property(DeviceClass *klass, const char *name,
     } else {
         const QAPITypeInfo *qapi_type = qdev_prop_qapi_type(prop);
 
-        if (qapi_type) {
-            op = object_class_property_add_qapi(oc,
-                                               name, qapi_type,
-                                               field_prop_getter(prop->info),
-                                               field_prop_setter(prop->info),
-                                               prop->info->release,
-                                               (Property *)prop);
-        } else {
-            op = object_class_property_add(oc,
-                                           name, prop->info->type,
-                                           field_prop_getter(prop->info),
-                                           field_prop_setter(prop->info),
-                                           prop->info->release,
-                                           (Property *)prop);
-        }
+        assert(qapi_type);
+        op = object_class_property_add_qapi(oc,
+                                            name, qapi_type,
+                                            field_prop_getter(prop->info),
+                                            field_prop_setter(prop->info),
+                                            prop->info->release,
+                                            (Property *)prop);
     }
     if (prop->set_default) {
         prop->info->set_default_value(op, prop);

-- 
2.54.0



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

* [PATCH 52/54] memory: use object_property_add_link for container property
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (50 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 51/54] qdev: remove deprecated PropertyInfo.type and .enum_table fields Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 53/54] qom: drop free-form property typename registration Marc-André Lureau
                   ` (2 subsequent siblings)
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

Replace the hand-rolled container property with
object_property_add_link().

With check=NULL the link has no setter (read-only), matching the
existing behaviour. The built-in link getter and resolver are
functionally identical to the removed memory_region_get_container()
and memory_region_resolve_container(). The non-STRONG flag avoids
refcount interference — mr->container is managed externally by
memory_region_add/del_subregion().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 system/memory.c | 35 +++++------------------------------
 1 file changed, 5 insertions(+), 30 deletions(-)

diff --git a/system/memory.c b/system/memory.c
index 1f2d44ce8b4..d06b14d8338 100644
--- a/system/memory.c
+++ b/system/memory.c
@@ -1253,29 +1253,6 @@ void memory_region_init(MemoryRegion *mr,
     memory_region_do_init(mr, owner, name, size);
 }
 
-static void memory_region_get_container(Object *obj, Visitor *v,
-                                        const char *name, void *opaque,
-                                        Error **errp)
-{
-    MemoryRegion *mr = MEMORY_REGION(obj);
-    char *path = (char *)"";
-
-    if (mr->container) {
-        path = object_get_canonical_path(OBJECT(mr->container));
-    }
-    visit_type_str(v, name, &path, errp);
-    if (mr->container) {
-        g_free(path);
-    }
-}
-
-static Object *memory_region_resolve_container(Object *obj, void *opaque,
-                                               const char *part)
-{
-    MemoryRegion *mr = MEMORY_REGION(obj);
-
-    return OBJECT(mr->container);
-}
 
 static void memory_region_get_priority(Object *obj, Visitor *v,
                                        const char *name, void *opaque,
@@ -1299,7 +1276,6 @@ static void memory_region_get_size(Object *obj, Visitor *v, const char *name,
 static void memory_region_initfn(Object *obj)
 {
     MemoryRegion *mr = MEMORY_REGION(obj);
-    ObjectProperty *op;
 
     mr->ops = &unassigned_mem_ops;
     mr->enabled = true;
@@ -1308,12 +1284,11 @@ static void memory_region_initfn(Object *obj)
     QTAILQ_INIT(&mr->subregions);
     QTAILQ_INIT(&mr->coalesced);
 
-    op = object_property_add(OBJECT(mr), "container",
-                             "link<" TYPE_MEMORY_REGION ">",
-                             memory_region_get_container,
-                             NULL, /* memory_region_set_container */
-                             NULL, NULL);
-    op->resolve = memory_region_resolve_container;
+    object_property_add_link(obj, "container",
+                             TYPE_MEMORY_REGION,
+                             (Object **)&mr->container,
+                             NULL, /* read-only: no check means no setter */
+                             0);
 
     object_property_add_uint64_ptr(OBJECT(mr), "addr",
                                    &mr->addr, OBJ_PROP_FLAG_READ);

-- 
2.54.0



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

* [PATCH 53/54] qom: drop free-form property typename registration
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (51 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 52/54] memory: use object_property_add_link for container property Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-05-10 13:43 ` [PATCH 54/54] qom: use QAPITypeInfo in object_property_get_enum Marc-André Lureau
  2026-07-29  7:28 ` [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Markus Armbruster via qemu development
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

All properties must now use builtin registration helpers
or QAPI-based properties.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/qom/object.h | 36 ------------------------------------
 qom/object.c         |  4 ++--
 2 files changed, 2 insertions(+), 38 deletions(-)

diff --git a/include/qom/object.h b/include/qom/object.h
index d0134a94281..ba2df54258b 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1084,44 +1084,8 @@ ObjectProperty *object_property_try_add(Object *obj, const char *name,
                                         ObjectPropertyRelease *release,
                                         void *opaque, Error **errp);
 
-/**
- * object_property_add:
- * Same as object_property_try_add() with @errp hardcoded to
- * &error_abort.
- *
- * @obj: the object to add a property to
- * @name: the name of the property.  This can contain any character except for
- *  a forward slash.  In general, you should use hyphens '-' instead of
- *  underscores '_' when naming properties.
- * @type: the type name of the property.  This namespace is pretty loosely
- *   defined.  Sub namespaces are constructed by using a prefix and then
- *   to angle brackets.  For instance, the type 'virtio-net-pci' in the
- *   'link' namespace would be 'link<virtio-net-pci>'.
- * @get: The getter to be called to read a property.  If this is NULL, then
- *   the property cannot be read.
- * @set: the setter to be called to write a property.  If this is NULL,
- *   then the property cannot be written.
- * @release: called when the property is removed from the object.  This is
- *   meant to allow a property to free its opaque upon object
- *   destruction.  This may be NULL.
- * @opaque: an opaque pointer to pass to the callbacks for the property
- */
-ObjectProperty *object_property_add(Object *obj, const char *name,
-                                    const char *type,
-                                    ObjectPropertyAccessor *get,
-                                    ObjectPropertyAccessor *set,
-                                    ObjectPropertyRelease *release,
-                                    void *opaque);
-
 void object_property_del(Object *obj, const char *name);
 
-ObjectProperty *object_class_property_add(ObjectClass *klass, const char *name,
-                                          const char *type,
-                                          ObjectPropertyAccessor *get,
-                                          ObjectPropertyAccessor *set,
-                                          ObjectPropertyRelease *release,
-                                          void *opaque);
-
 /**
  * object_property_set_default_bool:
  * @prop: the property to set
diff --git a/qom/object.c b/qom/object.c
index 1e6c3a9f91d..c378d20c4db 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1225,7 +1225,7 @@ object_property_try_add(Object *obj, const char *name, const char *type,
     return prop;
 }
 
-ObjectProperty *
+static ObjectProperty *
 object_property_add(Object *obj, const char *name, const char *type,
                     ObjectPropertyAccessor *get,
                     ObjectPropertyAccessor *set,
@@ -1236,7 +1236,7 @@ object_property_add(Object *obj, const char *name, const char *type,
                                    opaque, &error_abort);
 }
 
-ObjectProperty *
+static ObjectProperty *
 object_class_property_add(ObjectClass *klass,
                           const char *name,
                           const char *type,

-- 
2.54.0



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

* [PATCH 54/54] qom: use QAPITypeInfo in object_property_get_enum
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (52 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 53/54] qom: drop free-form property typename registration Marc-André Lureau
@ 2026-05-10 13:43 ` Marc-André Lureau
  2026-07-29  7:28 ` [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Markus Armbruster via qemu development
  54 siblings, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-05-10 13:43 UTC (permalink / raw)
  To: qemu-devel
  Cc: Markus Armbruster, Paolo Bonzini, Daniel P. Berrangé,
	Marc-André Lureau

The typename parameter becomes a QAPITypeInfo pointer, and the
validation compares prop->qapi_type against it instead of matching
prop->type strings.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/qom/object.h            | 4 ++--
 hw/core/machine-qmp-cmds.c      | 3 ++-
 qom/object.c                    | 8 ++++----
 tests/unit/check-qom-proplist.c | 6 +++---
 4 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/include/qom/object.h b/include/qom/object.h
index ba2df54258b..573414c7270 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1410,7 +1410,7 @@ uint64_t object_property_get_uint(Object *obj, const char *name,
  * object_property_get_enum:
  * @obj: the object
  * @name: the name of the property
- * @typename: the name of the enum data type
+ * @type_info: the QAPITypeInfo of the enum
  * @errp: returns an error if this function fails
  *
  * Returns: the value of the property, converted to an integer (which
@@ -1418,7 +1418,7 @@ uint64_t object_property_get_uint(Object *obj, const char *name,
  * value is not an enum).
  */
 int object_property_get_enum(Object *obj, const char *name,
-                             const char *typename, Error **errp);
+                             const QAPITypeInfo *type_info, Error **errp);
 
 /**
  * object_property_set:
diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
index e62cb4ec888..9b449080dd5 100644
--- a/hw/core/machine-qmp-cmds.c
+++ b/hw/core/machine-qmp-cmds.c
@@ -17,6 +17,7 @@
 #include "qapi/qapi-commands-accelerator.h"
 #include "qapi/qapi-commands-machine.h"
 #include "qobject/qobject.h"
+#include "qapi/qapi-type-infos-common.h"
 #include "qapi/qobject-input-visitor.h"
 #include "qapi/type-helpers.h"
 #include "qemu/uuid.h"
@@ -218,7 +219,7 @@ static int query_memdev(Object *obj, void *opaque)
         } else {
             m->has_reserve = true;
         }
-        m->policy = object_property_get_enum(obj, "policy", "HostMemPolicy",
+        m->policy = object_property_get_enum(obj, "policy", &HostMemPolicy_type_info,
                                              &error_abort);
         host_nodes = object_property_get_qobject(obj,
                                                  "host-nodes",
diff --git a/qom/object.c b/qom/object.c
index c378d20c4db..08f2e93d0a1 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1604,7 +1604,7 @@ uint64_t object_property_get_uint(Object *obj, const char *name,
 }
 
 int object_property_get_enum(Object *obj, const char *name,
-                             const char *typename, Error **errp)
+                             const QAPITypeInfo *type_info, Error **errp)
 {
     char *str;
     int ret;
@@ -1614,10 +1614,10 @@ int object_property_get_enum(Object *obj, const char *name,
         return -1;
     }
 
-    if (!g_str_equal(prop->type, typename)) {
+    if (prop->qapi_type != type_info) {
         error_setg(errp, "Property %s on %s is not '%s' enum type",
-                   name, object_class_get_name(
-                       object_get_class(obj)), typename);
+                   name, object_class_get_name(object_get_class(obj)),
+                   type_info->name);
         return -1;
     }
 
diff --git a/tests/unit/check-qom-proplist.c b/tests/unit/check-qom-proplist.c
index 7f10befe687..d6703e64827 100644
--- a/tests/unit/check-qom-proplist.c
+++ b/tests/unit/check-qom-proplist.c
@@ -528,14 +528,14 @@ static void test_dummy_getenum(void)
 
     val = object_property_get_enum(OBJECT(dobj),
                                    "av",
-                                   "DummyAnimal",
+                                   &dummy_animal_qapi_type_info,
                                    &error_abort);
     g_assert(val == DUMMY_PLATYPUS);
 
     /* A bad enum type name */
     val = object_property_get_enum(OBJECT(dobj),
                                    "av",
-                                   "BadAnimal",
+                                   &dummy_str_qapi_type_info,
                                    &err);
     g_assert(val == -1);
     error_free_or_abort(&err);
@@ -543,7 +543,7 @@ static void test_dummy_getenum(void)
     /* A non-enum property name */
     val = object_property_get_enum(OBJECT(dobj),
                                    "iv",
-                                   "DummyAnimal",
+                                   &dummy_animal_qapi_type_info,
                                    &err);
     g_assert(val == -1);
     error_free_or_abort(&err);

-- 
2.54.0



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

* Re: [PATCH 20/54] riscv/virt: convert OnOffAuto properties to QAPI-aware registration
  2026-05-10 13:43 ` [PATCH 20/54] riscv/virt: convert OnOffAuto properties " Marc-André Lureau
@ 2026-05-13  2:04   ` Alistair Francis
  0 siblings, 0 replies; 62+ messages in thread
From: Alistair Francis @ 2026-05-13  2:04 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Markus Armbruster, Paolo Bonzini,
	Daniel P. Berrangé

On Sun, May 10, 2026 at 11:49 PM Marc-André Lureau
<marcandre.lureau@redhat.com> wrote:
>
> Convert the acpi and iommu-sys OnOffAuto properties from manual
> visitor-based callbacks to property_add_qapi_enum().
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  hw/riscv/virt.c | 54 ++++++++++++++++++++++++------------------------------
>  1 file changed, 24 insertions(+), 30 deletions(-)
>
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index a1c323e66df..5148044df95 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -55,7 +55,7 @@
>  #include "hw/pci-host/gpex.h"
>  #include "hw/display/ramfb.h"
>  #include "hw/acpi/aml-build.h"
> -#include "qapi/qapi-visit-common.h"
> +#include "qapi/qapi-type-infos-common.h"
>  #include "hw/virtio/virtio-iommu.h"
>  #include "hw/uefi/var-service-api.h"
>
> @@ -1832,21 +1832,16 @@ bool virt_is_iommu_sys_enabled(RISCVVirtState *s)
>      return s->iommu_sys == ON_OFF_AUTO_ON;
>  }
>
> -static void virt_get_iommu_sys(Object *obj, Visitor *v, const char *name,
> -                               void *opaque, Error **errp)
> +static int virt_get_iommu_sys(Object *obj, Error **errp)
>  {
>      RISCVVirtState *s = RISCV_VIRT_MACHINE(obj);
> -    OnOffAuto iommu_sys = s->iommu_sys;
> -
> -    visit_type_OnOffAuto(v, name, &iommu_sys, errp);
> +    return s->iommu_sys;
>  }
>
> -static void virt_set_iommu_sys(Object *obj, Visitor *v, const char *name,
> -                               void *opaque, Error **errp)
> +static void virt_set_iommu_sys(Object *obj, int value, Error **errp)
>  {
>      RISCVVirtState *s = RISCV_VIRT_MACHINE(obj);
> -
> -    visit_type_OnOffAuto(v, name, &s->iommu_sys, errp);
> +    s->iommu_sys = value;
>  }
>
>  bool virt_is_acpi_enabled(RISCVVirtState *s)
> @@ -1854,21 +1849,16 @@ bool virt_is_acpi_enabled(RISCVVirtState *s)
>      return s->acpi != ON_OFF_AUTO_OFF;
>  }
>
> -static void virt_get_acpi(Object *obj, Visitor *v, const char *name,
> -                          void *opaque, Error **errp)
> +static int virt_get_acpi(Object *obj, Error **errp)
>  {
>      RISCVVirtState *s = RISCV_VIRT_MACHINE(obj);
> -    OnOffAuto acpi = s->acpi;
> -
> -    visit_type_OnOffAuto(v, name, &acpi, errp);
> +    return s->acpi;
>  }
>
> -static void virt_set_acpi(Object *obj, Visitor *v, const char *name,
> -                          void *opaque, Error **errp)
> +static void virt_set_acpi(Object *obj, int value, Error **errp)
>  {
>      RISCVVirtState *s = RISCV_VIRT_MACHINE(obj);
> -
> -    visit_type_OnOffAuto(v, name, &s->acpi, errp);
> +    s->acpi = value;
>  }
>
>  static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
> @@ -1966,17 +1956,21 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data)
>          object_class_property_set_description(oc, "aia-guests", str);
>      }
>
> -    object_class_property_add(oc, "acpi", "OnOffAuto",
> -                              virt_get_acpi, virt_set_acpi,
> -                              NULL, NULL);
> -    object_class_property_set_description(oc, "acpi",
> -                                          "Enable ACPI");
> -
> -    object_class_property_add(oc, "iommu-sys", "OnOffAuto",
> -                              virt_get_iommu_sys, virt_set_iommu_sys,
> -                              NULL, NULL);
> -    object_class_property_set_description(oc, "iommu-sys",
> -                                          "Enable IOMMU platform device");
> +    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
> +        .name = "acpi",
> +        .description = "Enable ACPI",
> +        .qapi_type = &OnOffAuto_type_info,
> +        .get = virt_get_acpi,
> +        .set = virt_set_acpi,
> +    ));
> +
> +    object_class_property_add_qapi_enum(oc, QAPI_ENUM_PROP(
> +        .name = "iommu-sys",
> +        .description = "Enable IOMMU platform device",
> +        .qapi_type = &OnOffAuto_type_info,
> +        .get = virt_get_iommu_sys,
> +        .set = virt_set_iommu_sys,
> +    ));
>  }
>
>  static const TypeInfo virt_machine_typeinfo = {
>
> --
> 2.54.0
>
>


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

* Re: [PATCH 46/54] target/riscv: fix incorrect QAPI types and u8 casting
  2026-05-10 13:43 ` [PATCH 46/54] target/riscv: fix incorrect QAPI types and u8 casting Marc-André Lureau
@ 2026-05-13  2:05   ` Alistair Francis
  0 siblings, 0 replies; 62+ messages in thread
From: Alistair Francis @ 2026-05-13  2:05 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Markus Armbruster, Paolo Bonzini,
	Daniel P. Berrangé

On Sun, May 10, 2026 at 11:53 PM Marc-André Lureau
<marcandre.lureau@redhat.com> wrote:
>
> "pmu_num" is u8, "pmu_mask" is u32, so is "pmp-granularity"
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/cpu.c | 9 +++++----
>  1 file changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 7d0cf88d48d..235764462cb 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -1467,7 +1467,7 @@ static void prop_pmu_num_get(Object *obj, Visitor *v, const char *name,
>  }
>
>  static const PropertyInfo prop_pmu_num = {
> -    .type = "int8",
> +    .type = "uint8",
>      .description = "pmu-num",
>      .get = prop_pmu_num_get,
>      .set = prop_pmu_num_set,
> @@ -1503,13 +1503,13 @@ static void prop_pmu_mask_set(Object *obj, Visitor *v, const char *name,
>  static void prop_pmu_mask_get(Object *obj, Visitor *v, const char *name,
>                               void *opaque, Error **errp)
>  {
> -    uint8_t pmu_mask = RISCV_CPU(obj)->cfg.pmu_mask;
> +    uint32_t pmu_mask = RISCV_CPU(obj)->cfg.pmu_mask;
>
> -    visit_type_uint8(v, name, &pmu_mask, errp);
> +    visit_type_uint32(v, name, &pmu_mask, errp);
>  }
>
>  static const PropertyInfo prop_pmu_mask = {
> -    .type = "int8",
> +    .type = "uint32",
>      .description = "pmu-mask",
>      .get = prop_pmu_mask_get,
>      .set = prop_pmu_mask_set,
> @@ -1651,6 +1651,7 @@ static void prop_pmp_granularity_get(Object *obj, Visitor *v, const char *name,
>  }
>
>  static const PropertyInfo prop_pmp_granularity = {
> +    .type = "uint32",
>      .description = "pmp-granularity",
>      .get = prop_pmp_granularity_get,
>      .set = prop_pmp_granularity_set,
>
> --
> 2.54.0
>
>


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

* Re: [PATCH 47/54] target/riscv: convert PropertyInfo definitions to use qapi_type
  2026-05-10 13:43 ` [PATCH 47/54] target/riscv: convert PropertyInfo definitions to use qapi_type Marc-André Lureau
@ 2026-05-13  2:07   ` Alistair Francis
  0 siblings, 0 replies; 62+ messages in thread
From: Alistair Francis @ 2026-05-13  2:07 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Markus Armbruster, Paolo Bonzini,
	Daniel P. Berrangé

On Sun, May 10, 2026 at 11:53 PM Marc-André Lureau
<marcandre.lureau@redhat.com> wrote:
>
> Mechanical conversion of all local PropertyInfo definitions in
> target/riscv/cpu.c
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/cpu.c | 32 ++++++++++++++++----------------
>  1 file changed, 16 insertions(+), 16 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 235764462cb..bd01884fb30 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -1467,7 +1467,7 @@ static void prop_pmu_num_get(Object *obj, Visitor *v, const char *name,
>  }
>
>  static const PropertyInfo prop_pmu_num = {
> -    .type = "uint8",
> +    .qapi_type = &uint8_type_info,
>      .description = "pmu-num",
>      .get = prop_pmu_num_get,
>      .set = prop_pmu_num_set,
> @@ -1509,7 +1509,7 @@ static void prop_pmu_mask_get(Object *obj, Visitor *v, const char *name,
>  }
>
>  static const PropertyInfo prop_pmu_mask = {
> -    .type = "uint32",
> +    .qapi_type = &uint32_type_info,
>      .description = "pmu-mask",
>      .get = prop_pmu_mask_get,
>      .set = prop_pmu_mask_set,
> @@ -1541,7 +1541,7 @@ static void prop_mmu_get(Object *obj, Visitor *v, const char *name,
>  }
>
>  static const PropertyInfo prop_mmu = {
> -    .type = "bool",
> +    .qapi_type = &bool_type_info,
>      .description = "mmu",
>      .get = prop_mmu_get,
>      .set = prop_mmu_set,
> @@ -1573,7 +1573,7 @@ static void prop_pmp_get(Object *obj, Visitor *v, const char *name,
>  }
>
>  static const PropertyInfo prop_pmp = {
> -    .type = "bool",
> +    .qapi_type = &bool_type_info,
>      .description = "pmp",
>      .get = prop_pmp_get,
>      .set = prop_pmp_set,
> @@ -1613,7 +1613,7 @@ static void prop_num_pmp_regions_get(Object *obj, Visitor *v, const char *name,
>  }
>
>  static const PropertyInfo prop_num_pmp_regions = {
> -    .type = "uint8",
> +    .qapi_type = &uint8_type_info,
>      .description = "num-pmp-regions",
>      .get = prop_num_pmp_regions_get,
>      .set = prop_num_pmp_regions_set,
> @@ -1651,7 +1651,7 @@ static void prop_pmp_granularity_get(Object *obj, Visitor *v, const char *name,
>  }
>
>  static const PropertyInfo prop_pmp_granularity = {
> -    .type = "uint32",
> +    .qapi_type = &uint32_type_info,
>      .description = "pmp-granularity",
>      .get = prop_pmp_granularity_get,
>      .set = prop_pmp_granularity_set,
> @@ -1726,7 +1726,7 @@ static void prop_priv_spec_get(Object *obj, Visitor *v, const char *name,
>  }
>
>  static const PropertyInfo prop_priv_spec = {
> -    .type = "str",
> +    .qapi_type = &str_type_info,
>      .description = "priv_spec",
>      /* FIXME enum? */
>      .get = prop_priv_spec_get,
> @@ -1759,7 +1759,7 @@ static void prop_vext_spec_get(Object *obj, Visitor *v, const char *name,
>  }
>
>  static const PropertyInfo prop_vext_spec = {
> -    .type = "str",
> +    .qapi_type = &str_type_info,
>      .description = "vext_spec",
>      /* FIXME enum? */
>      .get = prop_vext_spec_get,
> @@ -1802,7 +1802,7 @@ static void prop_vlen_get(Object *obj, Visitor *v, const char *name,
>  }
>
>  static const PropertyInfo prop_vlen = {
> -    .type = "uint16",
> +    .qapi_type = &uint16_type_info,
>      .description = "vlen",
>      .get = prop_vlen_get,
>      .set = prop_vlen_set,
> @@ -1843,7 +1843,7 @@ static void prop_elen_get(Object *obj, Visitor *v, const char *name,
>  }
>
>  static const PropertyInfo prop_elen = {
> -    .type = "uint16",
> +    .qapi_type = &uint16_type_info,
>      .description = "elen",
>      .get = prop_elen_get,
>      .set = prop_elen_set,
> @@ -1879,7 +1879,7 @@ static void prop_cbom_blksize_get(Object *obj, Visitor *v, const char *name,
>  }
>
>  static const PropertyInfo prop_cbom_blksize = {
> -    .type = "uint16",
> +    .qapi_type = &uint16_type_info,
>      .description = "cbom_blocksize",
>      .get = prop_cbom_blksize_get,
>      .set = prop_cbom_blksize_set,
> @@ -1915,7 +1915,7 @@ static void prop_cbop_blksize_get(Object *obj, Visitor *v, const char *name,
>  }
>
>  static const PropertyInfo prop_cbop_blksize = {
> -    .type = "uint16",
> +    .qapi_type = &uint16_type_info,
>      .description = "cbop_blocksize",
>      .get = prop_cbop_blksize_get,
>      .set = prop_cbop_blksize_set,
> @@ -1951,7 +1951,7 @@ static void prop_cboz_blksize_get(Object *obj, Visitor *v, const char *name,
>  }
>
>  static const PropertyInfo prop_cboz_blksize = {
> -    .type = "uint16",
> +    .qapi_type = &uint16_type_info,
>      .description = "cboz_blocksize",
>      .get = prop_cboz_blksize_get,
>      .set = prop_cboz_blksize_set,
> @@ -1987,7 +1987,7 @@ static void prop_mvendorid_get(Object *obj, Visitor *v, const char *name,
>  }
>
>  static const PropertyInfo prop_mvendorid = {
> -    .type = "uint32",
> +    .qapi_type = &uint32_type_info,
>      .description = "mvendorid",
>      .get = prop_mvendorid_get,
>      .set = prop_mvendorid_set,
> @@ -2023,7 +2023,7 @@ static void prop_mimpid_get(Object *obj, Visitor *v, const char *name,
>  }
>
>  static const PropertyInfo prop_mimpid = {
> -    .type = "uint64",
> +    .qapi_type = &uint64_type_info,
>      .description = "mimpid",
>      .get = prop_mimpid_get,
>      .set = prop_mimpid_set,
> @@ -2080,7 +2080,7 @@ static void prop_marchid_get(Object *obj, Visitor *v, const char *name,
>  }
>
>  static const PropertyInfo prop_marchid = {
> -    .type = "uint64",
> +    .qapi_type = &uint64_type_info,
>      .description = "marchid",
>      .get = prop_marchid_get,
>      .set = prop_marchid_set,
>
> --
> 2.54.0
>
>


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

* Re: [PATCH 00/54] qom/qdev: associate properties with QAPI schema types
  2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
                   ` (53 preceding siblings ...)
  2026-05-10 13:43 ` [PATCH 54/54] qom: use QAPITypeInfo in object_property_get_enum Marc-André Lureau
@ 2026-07-29  7:28 ` Markus Armbruster via qemu development
  2026-07-29 10:04   ` Marc-André Lureau
  54 siblings, 1 reply; 62+ messages in thread
From: Markus Armbruster via qemu development @ 2026-07-29  7:28 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel, Paolo Bonzini, Daniel P. Berrangé

I started writing this reply right when I saw the series, i.e. an
embarrassingly long time ago.  Then stuff happened, some of it good,
some bad, this review got crowded out, and my memory purged.

I sincerely apologize for the massive delay.

Naturally, this needs a rebase now.  But let me try to review it as is.

Marc-André Lureau <marcandre.lureau@redhat.com> writes:

> Hi,
>
> This series connects QOM and qdev properties to the QAPI type system, so
> that management tools can discover the QAPI schema type of each object
> property.

Sounds lovely!

> Today, QOM properties carry a free-form "type" string ("bool", "uint32",
> "OnOffAuto", ..) that has no formal link to the QAPI schema exposed by
> query-qmp-schema. Management tools must maintain ad-hoc mappings or rely
> on naming conventions to figure out how to interpret property values.

Correct.

Before I dive into individual patches, let me try to work out what the
series does as a whole.

> This series adds:
>   - A new QAPITypeInfo struct that pairs a property with its QAPI schema
>     type name, enum lookup table, and list-element type.

Peeking at the code, I see that ObjectProperty gains a member @qapi_type
pointing to its QAPITypeInfo.

It is null when the ObjectProperty doesn't have a QAPI type.

If it's non-null, then ObjectProperty members @name and @type are
redundant with qapi_type.name and .type.

Correct?

Would "every ObjectProperty has a QAPI type" be a reasonable goal for
the future?

>
>   - A QAPI code generator (qapi-type-infos) that emits a QAPITypeInfo
>     instance for every schema-defined type, including the mapping
>     between internal C names and the schema name visible to clients.

Peeking at the code, I find:

* The type

    typedef struct QAPITypeInfo {
        const char *name;
        const char *schema_name;
        const QEnumLookup *lookup;
        const struct QAPITypeInfo *list;
    } QAPITypeInfo;

* A T_type_info for each QAPI type T, including built-in types.

* T_type_info member @name is T's QAPI name, i.e. "T".

* T_type_info member @schema_name is T's masked name used in
  query-qmp-schema output, null when T is elided there.

* T_type_info member @list points to TList_type_info when that exists,
  else it's null.

* T_type_info member @lookup points to T_lookup when T is an enum, else
  it's null.

Correct?

>   - A "qapi-type" field in the ObjectPropertyInfo and
>     ObjectPropertyValue QMP structs, populated from the QAPITypeInfo
>     when present giving clients a cross-reference into query-qmp-schema
>     output.

To be precise: when ObjectPropertyInfo member @type is "T", then member
@qapi-type is T_type_info.qapi-type.  Correct?

If .qapi-type is non-null, you can use it to look up precise type
information via QAPI introspection, i.e. query-qmp-schema.

Correct?

Possible problem: query-qmp-schema covers only types that are actually
used in QMP.  But the above technique additionally wants QOM property
types.  I haven't checked what your series does about this, if anything.

ObjectPropertyInfo is only used with QMP command handlers.  It is
computed from ObjectProperty.

>   - Conversion of all PropertyInfo definitions from the old
>     .type/.enum_table strings to the new .qapi_type pointer.

The above is QOM, this is qdev.

Like ObjectProperty, PropertyInfo gains a member @qapi_type pointing to
its QAPITypeInfo.  Howver, this one cannot be null.

PropertyInfo members @type and @enum_table are dropped, because they are
redundant with qapi_type.type and .lookup.

Correct?

>   - Replacement of the generic qdev_prop_array with typed per-element
>     array PropertyInfos, removing the arrayinfo/arrayfieldsize
>     indirection from struct Property.

Before the series, an array-valued Property's @info member is
@qdev_prop_array.  @qdev_prop_array provides no information on the array
elements.  Instead, Property member @arrayinfo points to the
PropertyInfo for the elements, and @arrayfieldsize is the size of an
element.

Your series makes PropertyInfo array-capable: new members @element_info
and @element_size are the elements' PropertyInfo and size.  It then adds
a proper PropertyInfo for each such property, and drops
@qdev_prop_array.

Correct?

This could perhaps be spun out and merged separately to reduce the size
of future respins.

Not mentioned:

    - New QOM property creation functions for creating properties of
      QAPI type.  These take a QAPITypeInfo.

    - Convert some properties to use them.

>   - Removal of the deprecated PropertyInfo.type and .enum_table fields,
>     and of the old object_property_add_enum/add_tm APIs.
>
> Along the way, a few pre-existing type mismatches in property
> definitions are fixed, the "struct tm" RTC property is replaced with a
> proper QAPI StructTm type etc. Introducing more specific types or a
> "typedef" to QAPI could help provide better associated type informations
> than plain "str" in many cases, for example.

Examples?

> Comments welcome!
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>


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

* Re: [PATCH 00/54] qom/qdev: associate properties with QAPI schema types
  2026-07-29  7:28 ` [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Markus Armbruster via qemu development
@ 2026-07-29 10:04   ` Marc-André Lureau
  2026-07-29 12:20     ` Marc-André Lureau
  2026-07-29 12:42     ` Markus Armbruster
  0 siblings, 2 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-07-29 10:04 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel, Paolo Bonzini, Daniel P. Berrangé

Hi

On Wed, Jul 29, 2026 at 11:29 AM Markus Armbruster via qemu
development <qemu-devel@nongnu.org> wrote:
> Before I dive into individual patches, let me try to work out what the
> series does as a whole.
>
> > This series adds:
> >   - A new QAPITypeInfo struct that pairs a property with its QAPI schema
> >     type name, enum lookup table, and list-element type.
>
> Peeking at the code, I see that ObjectProperty gains a member @qapi_type
> pointing to its QAPITypeInfo.
>
> It is null when the ObjectProperty doesn't have a QAPI type.
>
> If it's non-null, then ObjectProperty members @name and @type are
> redundant with qapi_type.name and .type.
>
> Correct?

Almost. @name is the property name (e.g. "policy"), not the type name.
But @type becomes redundant with qapi_type->name when qapi_type is set
(object_property_add_qapi derive prop->type from qapi_type->name).

Also @type carries additional information for some property kinds that
@qapi_type doesn't cover: child<T> and link<T> embed the linked
object's QOM type name in the type string. qapi_type can't represent
that atm.

> Would "every ObjectProperty has a QAPI type" be a reasonable goal for
> the future?

Maybe? we would need to address the child<>/link<> gap. At least we
can make raw object_property_add() deprecated/static in object.c after
this series

>
> >
> >   - A QAPI code generator (qapi-type-infos) that emits a QAPITypeInfo
> >     instance for every schema-defined type, including the mapping
> >     between internal C names and the schema name visible to clients.
>
> Peeking at the code, I find:
>
> * The type
>
>     typedef struct QAPITypeInfo {
>         const char *name;
>         const char *schema_name;
>         const QEnumLookup *lookup;
>         const struct QAPITypeInfo *list;
>     } QAPITypeInfo;
>
> * A T_type_info for each QAPI type T, including built-in types.
>
> * T_type_info member @name is T's QAPI name, i.e. "T".
>
> * T_type_info member @schema_name is T's masked name used in
>   query-qmp-schema output, null when T is elided there.
>
> * T_type_info member @list points to TList_type_info when that exists,
>   else it's null.
>
> * T_type_info member @lookup points to T_lookup when T is an enum, else
>   it's null.
>
> Correct?

Yes

> >   - A "qapi-type" field in the ObjectPropertyInfo and
> >     ObjectPropertyValue QMP structs, populated from the QAPITypeInfo
> >     when present giving clients a cross-reference into query-qmp-schema
> >     output.
>
> To be precise: when ObjectPropertyInfo member @type is "T", then member
> @qapi-type is T_type_info.qapi-type.  Correct?

@qapi-type is T_type_info.schema_name, the masked name

> If .qapi-type is non-null, you can use it to look up precise type
> information via QAPI introspection, i.e. query-qmp-schema.
>
> Correct?

Yes

>
> Possible problem: query-qmp-schema covers only types that are actually
> used in QMP.  But the above technique additionally wants QOM property
> types.  I haven't checked what your series does about this, if anything.

Most types used as QOM properties are also used by QMP commands. But
it's true that types not used by QMP get schame_name = NULL atm.

Should we have a new pragma? Even if we have conditions, we may end up
with unused types in the build, but that shouldn't be a big issue. Or
we would need a more complicated several step build.

> ObjectPropertyInfo is only used with QMP command handlers.  It is
> computed from ObjectProperty.
>
> >   - Conversion of all PropertyInfo definitions from the old
> >     .type/.enum_table strings to the new .qapi_type pointer.
>
> The above is QOM, this is qdev.
>
> Like ObjectProperty, PropertyInfo gains a member @qapi_type pointing to
> its QAPITypeInfo.  Howver, this one cannot be null.
>
> PropertyInfo members @type and @enum_table are dropped, because they are
> redundant with qapi_type.type and .lookup.
>
> Correct?

Almost. Every PropertyInfo has a non-NULL qapi_type, except the array
ones (created with DEFINE_PROP_ARRAY_INFO) which leave .qapi_type NULL
and derive it at registration time from
.element_info->qapi_type->list. Either way, the resulting
ObjectProperty always ends up with a non-NULL qapi_type.

PropertyInfo members @type and @enum_table are dropped, because they
are redundant with qapi_type->name and ->lookup.

> >   - Replacement of the generic qdev_prop_array with typed per-element
> >     array PropertyInfos, removing the arrayinfo/arrayfieldsize
> >     indirection from struct Property.
>
> Before the series, an array-valued Property's @info member is
> @qdev_prop_array.  @qdev_prop_array provides no information on the array
> elements.  Instead, Property member @arrayinfo points to the
> PropertyInfo for the elements, and @arrayfieldsize is the size of an
> element.
>
> Your series makes PropertyInfo array-capable: new members @element_info
> and @element_size are the elements' PropertyInfo and size.  It then adds
> a proper PropertyInfo for each such property, and drops
> @qdev_prop_array.
>
> Correct?

Yes

>
> This could perhaps be spun out and merged separately to reduce the size
> of future respins.

I can split it out if it helps

>
> Not mentioned:
>
>     - New QOM property creation functions for creating properties of
>       QAPI type.  These take a QAPITypeInfo.
>
>     - Convert some properties to use them.
>
> >   - Removal of the deprecated PropertyInfo.type and .enum_table fields,
> >     and of the old object_property_add_enum/add_tm APIs.
> >
> > Along the way, a few pre-existing type mismatches in property
> > definitions are fixed, the "struct tm" RTC property is replaced with a
> > proper QAPI StructTm type etc. Introducing more specific types or a
> > "typedef" to QAPI could help provide better associated type informations
> > than plain "str" in many cases, for example.
>
> Examples?
>

Properties using str_type_info that carry structured values with their
own validation: macaddr ("52:54:00:12:34:56"), PCI addresses
("04:00.0"), netdev names, chardev names, drive names, UUID strings. A
QAPI "typedef" (or newtype) for e.g. MacAddr, PciDevAddr, UUID could
let tools know these aren't arbitrary strings (see "hw/nvdimm: convert
UUID property to QAPI-aware registration" patch).


> > Comments welcome!
> >
> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>


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

* Re: [PATCH 00/54] qom/qdev: associate properties with QAPI schema types
  2026-07-29 10:04   ` Marc-André Lureau
@ 2026-07-29 12:20     ` Marc-André Lureau
  2026-07-29 12:42     ` Markus Armbruster
  1 sibling, 0 replies; 62+ messages in thread
From: Marc-André Lureau @ 2026-07-29 12:20 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel, Paolo Bonzini, Daniel P. Berrangé

Hi

On Wed, Jul 29, 2026 at 2:04 PM Marc-André Lureau
<marcandre.lureau@redhat.com> wrote:
>
> Hi
>
> On Wed, Jul 29, 2026 at 11:29 AM Markus Armbruster via qemu
> development <qemu-devel@nongnu.org> wrote:
> > > Along the way, a few pre-existing type mismatches in property
> > > definitions are fixed, the "struct tm" RTC property is replaced with a
> > > proper QAPI StructTm type etc. Introducing more specific types or a
> > > "typedef" to QAPI could help provide better associated type informations
> > > than plain "str" in many cases, for example.
> >
> > Examples?
> >
>
> Properties using str_type_info that carry structured values with their
> own validation: macaddr ("52:54:00:12:34:56"), PCI addresses
> ("04:00.0"), netdev names, chardev names, drive names, UUID strings. A
> QAPI "typedef" (or newtype) for e.g. MacAddr, PciDevAddr, UUID could
> let tools know these aren't arbitrary strings (see "hw/nvdimm: convert
> UUID property to QAPI-aware registration" patch).

On a related note, qapi-type for integers are all collapsed to "int"
(and list of). Even though json wire accepts "int", it would be nice
to retain the original type information.


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

* Re: [PATCH 00/54] qom/qdev: associate properties with QAPI schema types
  2026-07-29 10:04   ` Marc-André Lureau
  2026-07-29 12:20     ` Marc-André Lureau
@ 2026-07-29 12:42     ` Markus Armbruster
  1 sibling, 0 replies; 62+ messages in thread
From: Markus Armbruster @ 2026-07-29 12:42 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel, Paolo Bonzini, Daniel P. Berrangé

Marc-André Lureau <marcandre.lureau@redhat.com> writes:

> Hi
>
> On Wed, Jul 29, 2026 at 11:29 AM Markus Armbruster via qemu
> development <qemu-devel@nongnu.org> wrote:
>> Before I dive into individual patches, let me try to work out what the
>> series does as a whole.
>>
>> > This series adds:
>> >   - A new QAPITypeInfo struct that pairs a property with its QAPI schema
>> >     type name, enum lookup table, and list-element type.
>>
>> Peeking at the code, I see that ObjectProperty gains a member @qapi_type
>> pointing to its QAPITypeInfo.
>>
>> It is null when the ObjectProperty doesn't have a QAPI type.
>>
>> If it's non-null, then ObjectProperty members @name and @type are
>> redundant with qapi_type.name and .type.
>>
>> Correct?
>
> Almost. @name is the property name (e.g. "policy"), not the type name.
> But @type becomes redundant with qapi_type->name when qapi_type is set
> (object_property_add_qapi derive prop->type from qapi_type->name).
>
> Also @type carries additional information for some property kinds that
> @qapi_type doesn't cover: child<T> and link<T> embed the linked
> object's QOM type name in the type string. qapi_type can't represent
> that atm.

Can child and link properties have non-null @qapi_type?

>> Would "every ObjectProperty has a QAPI type" be a reasonable goal for
>> the future?
>
> Maybe? we would need to address the child<>/link<> gap. At least we
> can make raw object_property_add() deprecated/static in object.c after
> this series

Interesting!

>> >   - A QAPI code generator (qapi-type-infos) that emits a QAPITypeInfo
>> >     instance for every schema-defined type, including the mapping
>> >     between internal C names and the schema name visible to clients.
>>
>> Peeking at the code, I find:
>>
>> * The type
>>
>>     typedef struct QAPITypeInfo {
>>         const char *name;
>>         const char *schema_name;
>>         const QEnumLookup *lookup;
>>         const struct QAPITypeInfo *list;
>>     } QAPITypeInfo;
>>
>> * A T_type_info for each QAPI type T, including built-in types.
>>
>> * T_type_info member @name is T's QAPI name, i.e. "T".
>>
>> * T_type_info member @schema_name is T's masked name used in
>>   query-qmp-schema output, null when T is elided there.
>>
>> * T_type_info member @list points to TList_type_info when that exists,
>>   else it's null.
>>
>> * T_type_info member @lookup points to T_lookup when T is an enum, else
>>   it's null.
>>
>> Correct?
>
> Yes
>
>> >   - A "qapi-type" field in the ObjectPropertyInfo and
>> >     ObjectPropertyValue QMP structs, populated from the QAPITypeInfo
>> >     when present giving clients a cross-reference into query-qmp-schema
>> >     output.
>>
>> To be precise: when ObjectPropertyInfo member @type is "T", then member
>> @qapi-type is T_type_info.qapi-type.  Correct?
>
> @qapi-type is T_type_info.schema_name, the masked name

Right.

>> If .qapi-type is non-null, you can use it to look up precise type
>> information via QAPI introspection, i.e. query-qmp-schema.
>>
>> Correct?
>
> Yes
>
>>
>> Possible problem: query-qmp-schema covers only types that are actually
>> used in QMP.  But the above technique additionally wants QOM property
>> types.  I haven't checked what your series does about this, if anything.
>
> Most types used as QOM properties are also used by QMP commands. But
> it's true that types not used by QMP get schame_name = NULL atm.

So the problem is real, and to reap the full benefit of your work, we
need to solve it.  Not necessarily right away.

> Should we have a new pragma? Even if we have conditions, we may end up
> with unused types in the build, but that shouldn't be a big issue. Or
> we would need a more complicated several step build.

No need not worry about the how right now.

>> ObjectPropertyInfo is only used with QMP command handlers.  It is
>> computed from ObjectProperty.
>>
>> >   - Conversion of all PropertyInfo definitions from the old
>> >     .type/.enum_table strings to the new .qapi_type pointer.
>>
>> The above is QOM, this is qdev.
>>
>> Like ObjectProperty, PropertyInfo gains a member @qapi_type pointing to
>> its QAPITypeInfo.  Howver, this one cannot be null.
>>
>> PropertyInfo members @type and @enum_table are dropped, because they are
>> redundant with qapi_type.type and .lookup.
>>
>> Correct?
>
> Almost. Every PropertyInfo has a non-NULL qapi_type, except the array
> ones (created with DEFINE_PROP_ARRAY_INFO) which leave .qapi_type NULL
> and derive it at registration time from
> .element_info->qapi_type->list.

Can you point me to the code setting it?  Would save me the digging.

>                                 Either way, the resulting
> ObjectProperty always ends up with a non-NULL qapi_type.
>
> PropertyInfo members @type and @enum_table are dropped, because they
> are redundant with qapi_type->name and ->lookup.

Yes.

>> >   - Replacement of the generic qdev_prop_array with typed per-element
>> >     array PropertyInfos, removing the arrayinfo/arrayfieldsize
>> >     indirection from struct Property.
>>
>> Before the series, an array-valued Property's @info member is
>> @qdev_prop_array.  @qdev_prop_array provides no information on the array
>> elements.  Instead, Property member @arrayinfo points to the
>> PropertyInfo for the elements, and @arrayfieldsize is the size of an
>> element.
>>
>> Your series makes PropertyInfo array-capable: new members @element_info
>> and @element_size are the elements' PropertyInfo and size.  It then adds
>> a proper PropertyInfo for each such property, and drops
>> @qdev_prop_array.
>>
>> Correct?
>
> Yes
>
>>
>> This could perhaps be spun out and merged separately to reduce the size
>> of future respins.
>
> I can split it out if it helps

Splitting off self-contained parts of a big series can help if they can
be merged quicker than the entire series.  We'll see.

>> Not mentioned:
>>
>>     - New QOM property creation functions for creating properties of
>>       QAPI type.  These take a QAPITypeInfo.
>>
>>     - Convert some properties to use them.
>>
>> >   - Removal of the deprecated PropertyInfo.type and .enum_table fields,
>> >     and of the old object_property_add_enum/add_tm APIs.
>> >
>> > Along the way, a few pre-existing type mismatches in property
>> > definitions are fixed, the "struct tm" RTC property is replaced with a
>> > proper QAPI StructTm type etc. Introducing more specific types or a
>> > "typedef" to QAPI could help provide better associated type informations
>> > than plain "str" in many cases, for example.
>>
>> Examples?
>>
>
> Properties using str_type_info that carry structured values with their
> own validation: macaddr ("52:54:00:12:34:56"), PCI addresses
> ("04:00.0"), netdev names, chardev names, drive names, UUID strings. A
> QAPI "typedef" (or newtype) for e.g. MacAddr, PciDevAddr, UUID could
> let tools know these aren't arbitrary strings (see "hw/nvdimm: convert
> UUID property to QAPI-aware registration" patch).

Two separate kinds:

1. Strings we need to parse: PCI addresses, MAC addresses, UUIDs, ...

   Parsing maps the string to something else, usually some object that
   isn't a string.

   We avoid string parsing in QAPI/QMP whenever practical.  You quoted
   several examples where we don't.

2. IDs of things we need to resolve

   Resolving maps the string to the object it names.

In both cases, we map strings to objects.

QAPI is unaware of this.  It simply uses strings in generated C.

What if QAPI was aware?  If the schema specified the object type, and
how to map from string to it?  This is a step beyond a mere typedef.
The mapping would move from handwritten code to generated code.
Generated interfaces would use the object types instead of strings.

Not now, of course.

>> > Comments welcome!
>> >
>> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>>



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

end of thread, other threads:[~2026-07-29 12:43 UTC | newest]

Thread overview: 62+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-10 13:42 [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Marc-André Lureau
2026-05-10 13:42 ` [PATCH 01/54] qapi: add QAPITypeInfo struct definition Marc-André Lureau
2026-05-10 13:42 ` [PATCH 02/54] qapi/introspect: expose the type name map Marc-André Lureau
2026-05-10 13:43 ` [PATCH 03/54] qapi: add type-infos generator Marc-André Lureau
2026-05-10 13:43 ` [PATCH 04/54] qapi/backend: wire up type-infos generation Marc-André Lureau
2026-05-10 13:43 ` [PATCH 05/54] qapi/gen: fix _module_basename for multi-dash 'what' parameters Marc-André Lureau
2026-05-10 13:43 ` [PATCH 06/54] meson: add qapi-type-infos-*.c/h to build Marc-André Lureau
2026-05-10 13:43 ` [PATCH 07/54] qom: add qapi_type field to ObjectProperty Marc-André Lureau
2026-05-10 13:43 ` [PATCH 08/54] qapi/qom: add qapi-type field to ObjectPropertyInfo Marc-André Lureau
2026-05-10 13:43 ` [PATCH 09/54] qom/qmp: populate qapi-type in QMP handlers Marc-André Lureau
2026-05-10 13:43 ` [PATCH 10/54] qom: add QAPI-aware property registration Marc-André Lureau
2026-05-10 13:43 ` [PATCH 11/54] tests: update check-qom-proplist for " Marc-André Lureau
2026-05-10 13:43 ` [PATCH 12/54] qom: convert enum properties to QAPI-aware registration Marc-André Lureau
2026-05-10 13:43 ` [PATCH 13/54] qom: remove old enum property registration API Marc-André Lureau
2026-05-10 13:43 ` [PATCH 14/54] qom: convert struct properties to QAPI-aware registration Marc-André Lureau
2026-05-10 13:43 ` [PATCH 15/54] " Marc-André Lureau
2026-05-10 13:43 ` [PATCH 16/54] x86: convert OnOffAuto " Marc-André Lureau
2026-05-10 13:43 ` [PATCH 17/54] microvm: " Marc-André Lureau
2026-05-10 13:43 ` [PATCH 18/54] pc: convert OnOffAuto vmport property " Marc-André Lureau
2026-05-10 13:43 ` [PATCH 19/54] arm/virt: convert OnOffAuto acpi " Marc-André Lureau
2026-05-10 13:43 ` [PATCH 20/54] riscv/virt: convert OnOffAuto properties " Marc-André Lureau
2026-05-13  2:04   ` Alistair Francis
2026-05-10 13:43 ` [PATCH 21/54] loongarch/virt: " Marc-André Lureau
2026-05-10 13:43 ` [PATCH 22/54] hostmem-file: convert OnOffAuto rom property " Marc-André Lureau
2026-05-10 13:43 ` [PATCH 23/54] sev: convert OnOffAuto legacy-vm-type " Marc-André Lureau
2026-05-10 13:43 ` [PATCH 24/54] whpx: convert OnOffAuto hyperv " Marc-André Lureau
2026-05-10 13:43 ` [PATCH 25/54] whpx: convert OnOffAuto arch properties " Marc-André Lureau
2026-05-10 13:43 ` [PATCH 26/54] accel/kvm: convert OnOffSplit property " Marc-André Lureau
2026-05-10 13:43 ` [PATCH 27/54] whpx: " Marc-André Lureau
2026-05-10 13:43 ` [PATCH 28/54] ppc/spapr-caps: convert to QAPI-aware property registration Marc-André Lureau
2026-05-10 13:43 ` [PATCH 29/54] system/memory: fix "priority" property typename Marc-André Lureau
2026-05-10 13:43 ` [PATCH 30/54] hw/mem/nvdimm: fix "size" " Marc-André Lureau
2026-05-10 13:43 ` [PATCH 31/54] qom: convert scalar properties to QAPI-aware registration Marc-André Lureau
2026-05-10 13:43 ` [PATCH 32/54] i386/cpu: convert strList property " Marc-André Lureau
2026-05-10 13:43 ` [PATCH 33/54] accel/hvf: convert OnOffSplit " Marc-André Lureau
2026-05-10 13:43 ` [PATCH 34/54] i386/x86: convert SgxEPCList " Marc-André Lureau
2026-05-10 13:43 ` [PATCH 35/54] virtio-balloon: convert guest-stats property to QAPI type Marc-André Lureau
2026-05-10 13:43 ` [PATCH 36/54] qom: replace object_property_add_tm with StructTm " Marc-André Lureau
2026-05-10 13:43 ` [PATCH 37/54] hw/nvdimm: convert UUID property to QAPI-aware registration Marc-André Lureau
2026-05-10 13:43 ` [PATCH 38/54] hw/s390-virtio-ccw: convert loadparm " Marc-André Lureau
2026-05-10 13:43 ` [PATCH 39/54] hw/ppc/spapr_drc: convert fdt " Marc-André Lureau
2026-05-10 13:43 ` [PATCH 40/54] spdm-socket: convert SpdmTransportType to QAPI enum Marc-André Lureau
2026-05-10 13:43 ` [PATCH 41/54] hw/pci: change the busnr type to uint8 Marc-André Lureau
2026-05-10 13:43 ` [PATCH 42/54] qdev: add qapi_type field to PropertyInfo with fallback registration Marc-André Lureau
2026-05-10 13:43 ` [PATCH 43/54] qdev: convert core PropertyInfo definitions to use qapi_type Marc-André Lureau
2026-05-10 13:43 ` [PATCH 44/54] qdev: convert system " Marc-André Lureau
2026-05-10 13:43 ` [PATCH 45/54] hw: convert device-local " Marc-André Lureau
2026-05-10 13:43 ` [PATCH 46/54] target/riscv: fix incorrect QAPI types and u8 casting Marc-André Lureau
2026-05-13  2:05   ` Alistair Francis
2026-05-10 13:43 ` [PATCH 47/54] target/riscv: convert PropertyInfo definitions to use qapi_type Marc-André Lureau
2026-05-13  2:07   ` Alistair Francis
2026-05-10 13:43 ` [PATCH 48/54] qdev: " Marc-André Lureau
2026-05-10 13:43 ` [PATCH 49/54] qdev: introduce typed array PropertyInfos Marc-André Lureau
2026-05-10 13:43 ` [PATCH 50/54] qdev: simplify DEFINE_PROP_ARRAY and remove generic array PropertyInfo Marc-André Lureau
2026-05-10 13:43 ` [PATCH 51/54] qdev: remove deprecated PropertyInfo.type and .enum_table fields Marc-André Lureau
2026-05-10 13:43 ` [PATCH 52/54] memory: use object_property_add_link for container property Marc-André Lureau
2026-05-10 13:43 ` [PATCH 53/54] qom: drop free-form property typename registration Marc-André Lureau
2026-05-10 13:43 ` [PATCH 54/54] qom: use QAPITypeInfo in object_property_get_enum Marc-André Lureau
2026-07-29  7:28 ` [PATCH 00/54] qom/qdev: associate properties with QAPI schema types Markus Armbruster via qemu development
2026-07-29 10:04   ` Marc-André Lureau
2026-07-29 12:20     ` Marc-André Lureau
2026-07-29 12:42     ` Markus Armbruster

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.