* [RFC 1/7] meson: add --enable-deprecations configure flag
2026-06-16 15:55 [RFC 0/7] qom: deprecate embedded objects and instance properties Daniel P. Berrangé
@ 2026-06-16 15:55 ` Daniel P. Berrangé
2026-06-16 15:55 ` [RFC 2/7] qom: deprecated embedding object structs within other objects Daniel P. Berrangé
` (8 subsequent siblings)
9 siblings, 0 replies; 27+ messages in thread
From: Daniel P. Berrangé @ 2026-06-16 15:55 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Peter Xu,
Hervé Poussineau, Alex Bennée, Michael S. Tsirkin,
Akihiko Odaki, Daniel P. Berrangé, Aurelien Jarno,
Fabiano Rosas, Paolo Bonzini, BALATON Zoltan, Mark Cave-Ayland,
Marc-André Lureau
A challenge with QEMU is that internal APIs get obsoleted but chasing
down use of old APIs is not as simple as it should be. Introduce a
--enable-deprecations configure flag which expands the macro
"QEMU_DEPRECATIONS" into "G_GNUC_DEPRECATED". This will trigger a
compiler warning for any use of the deprecated APIs.
It would generally be a good idea to disable -Werror when turning on
deprecations otherwise the build will quickly abort.
XXX: possibly add -Wno-error=deprecated-declarations, so we have
show deprecations by default despite -Werror being on by default.
This would trigger very many warnings but might be worth it if we
want to strongly nudge maintainers to convert existing code. Our
historical approach of "hope" has never worked to eliminate old
code patterns.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
include/qemu/osdep.h | 19 +++++++++++++++++++
meson.build | 1 +
meson_options.txt | 2 ++
scripts/meson-buildoptions.sh | 3 +++
4 files changed, 25 insertions(+)
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 2f0e61ad6b..99b8f9cbb7 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -447,6 +447,25 @@ void QEMU_ERROR("code path is reachable")
((void)0))
#endif
+/*
+ * Tag an internal APIs which should no longer be used
+ * to emit a warning during build if --enable-deprecations
+ * is used with configure. Use of -Werror will trigger
+ * immediate build failure if this is used.
+ */
+#ifdef CONFIG_DEPRECATIONS
+# define QEMU_DEPRECATED G_GNUC_DEPRECATED
+# define QEMU_DEPRECATIONS_OFF \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
+# define QEMU_DEPRECATIONS_ON \
+ _Pragma("GCC diagnostic pop")
+#else
+# define QEMU_DEPRECATED
+# define QEMU_DEPRECATIONS_OFF
+# define QEMU_DEPRECATIONS_ON
+#endif
+
/*
* Minimum function that returns zero only if both values are zero.
* Intended for use with unsigned values only.
diff --git a/meson.build b/meson.build
index 19e123423b..9e863aa897 100644
--- a/meson.build
+++ b/meson.build
@@ -2567,6 +2567,7 @@ config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage')
config_host_data.set('CONFIG_DEBUG_TCG', get_option('debug_tcg'))
config_host_data.set('CONFIG_DEBUG_REMAP', get_option('debug_remap'))
config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug'))
+config_host_data.set('CONFIG_DEPRECATIONS', get_option('deprecations'))
config_host_data.set('CONFIG_REPLICATION', get_option('replication').allowed())
config_host_data.set('CONFIG_FSFREEZE', qga_fsfreeze)
config_host_data.set('CONFIG_FSTRIM', qga_fstrim)
diff --git a/meson_options.txt b/meson_options.txt
index a07cb47d35..8f5924422d 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -367,6 +367,8 @@ option('qom_cast_debug', type: 'boolean', value: true,
description: 'cast debugging support')
option('slirp_smbd', type : 'feature', value : 'auto',
description: 'use smbd (at path --smbd=*) in slirp networking')
+option('deprecations', type: 'boolean', value: true,
+ description: 'enable internal API deprecation warnings')
option('qemu_ga_manufacturer', type: 'string', value: 'QEMU',
description: '"manufacturer" name for qemu-ga registry entries')
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
index c003985047..fb57f0610d 100644
--- a/scripts/meson-buildoptions.sh
+++ b/scripts/meson-buildoptions.sh
@@ -13,6 +13,7 @@ meson_options_help() {
printf "%s\n" ' --datadir=VALUE Data file directory [share]'
printf "%s\n" ' --disable-coroutine-pool coroutine freelist (better performance)'
printf "%s\n" ' --disable-debug-info Enable debug symbols and other information'
+ printf "%s\n" ' --disable-deprecations enable internal API deprecation warnings'
printf "%s\n" ' --disable-hexagon-idef-parser'
printf "%s\n" ' use idef-parser to automatically generate TCG'
printf "%s\n" ' code for the Hexagon frontend'
@@ -306,6 +307,8 @@ _meson_option_parse() {
--disable-debug-stack-usage) printf "%s" -Ddebug_stack_usage=false ;;
--enable-debug-tcg) printf "%s" -Ddebug_tcg=true ;;
--disable-debug-tcg) printf "%s" -Ddebug_tcg=false ;;
+ --enable-deprecations) printf "%s" -Ddeprecations=true ;;
+ --disable-deprecations) printf "%s" -Ddeprecations=false ;;
--enable-dmg) printf "%s" -Ddmg=enabled ;;
--disable-dmg) printf "%s" -Ddmg=disabled ;;
--docdir=*) quote_sh "-Ddocdir=$2" ;;
--
2.54.0
^ permalink raw reply related [flat|nested] 27+ messages in thread* [RFC 2/7] qom: deprecated embedding object structs within other objects
2026-06-16 15:55 [RFC 0/7] qom: deprecate embedded objects and instance properties Daniel P. Berrangé
2026-06-16 15:55 ` [RFC 1/7] meson: add --enable-deprecations configure flag Daniel P. Berrangé
@ 2026-06-16 15:55 ` Daniel P. Berrangé
2026-06-16 16:15 ` Peter Maydell
2026-06-16 15:55 ` [RFC 3/7] qom: deprecate use of instance properties Daniel P. Berrangé
` (7 subsequent siblings)
9 siblings, 1 reply; 27+ messages in thread
From: Daniel P. Berrangé @ 2026-06-16 15:55 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Peter Xu,
Hervé Poussineau, Alex Bennée, Michael S. Tsirkin,
Akihiko Odaki, Daniel P. Berrangé, Aurelien Jarno,
Fabiano Rosas, Paolo Bonzini, BALATON Zoltan, Mark Cave-Ayland,
Marc-André Lureau
The QOM APIs currently allow objects to be either allocated directly
on the heap, or statically embedded inside the struct of another object.
For the latter QOM has logic to avoid calling 'free' on the object when
finalizers complete, however, this is not sufficient to make the
practice safe.
Users of QOM expect that if they call "object_ref" to acquire their own
reference, then object will never be freed as long as they hold it.
This expectation is broken when an instance is embedded, as the "owner"
object's may be finalized, which frees the memory that is storing the
embedded QOM instance, even if its ref-count is still live.
Worse still is that a user of a QOM object cannot easily tell if the
instance they're using is embedded or directly heap allocated.
Mark the APIs for embedding objects as deprecated as the first step
towards removal of this flawed design concept. All objects must now
be directly heap allocated going forward, and existing usage must be
incrementally converted.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
include/qom/object.h | 28 ++++++++++++++++++++++++----
qom/object.c | 6 ++++++
2 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/include/qom/object.h b/include/qom/object.h
index 11f55613fc..dd708b1136 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -854,8 +854,13 @@ bool object_set_props_from_keyval(Object *obj, const QDict *qdict,
* This function will initialize an object. The memory for the object should
* have already been allocated. The returned object has a reference count of 1,
* and will be finalized when the last reference is dropped.
+ *
+ * Use of this function is now deprecated. All objects must be
+ * allocated using the object_new() family of functions and not
+ * statically embedded in a larger struct.
*/
-void object_initialize(void *obj, size_t size, const char *typename);
+void object_initialize(void *obj, size_t size, const char *typename)
+ QEMU_DEPRECATED;
/**
* object_initialize_child_with_props:
@@ -873,6 +878,10 @@ void object_initialize(void *obj, size_t size, const char *typename);
* has a reference count of 1 (for the "child<...>" property from the parent),
* so the object will be finalized automatically when the parent gets removed.
*
+ * Use of this function is now deprecated. All objects must be
+ * allocated using the object_new() family of functions and not
+ * statically embedded in a larger struct.
+ *
* The variadic parameters are a list of pairs of (propname, propvalue)
* strings. The propname of %NULL indicates the end of the property list.
* If the object implements the user creatable interface, the object will
@@ -883,7 +892,8 @@ void object_initialize(void *obj, size_t size, const char *typename);
bool object_initialize_child_with_props(Object *parentobj,
const char *propname,
void *childobj, size_t size, const char *type,
- Error **errp, ...) G_GNUC_NULL_TERMINATED;
+ Error **errp, ...) G_GNUC_NULL_TERMINATED
+ QEMU_DEPRECATED;
/**
* object_initialize_child_with_propsv:
@@ -897,12 +907,17 @@ bool object_initialize_child_with_props(Object *parentobj,
*
* See object_initialize_child() for documentation.
*
+ * Use of this function is now deprecated. All objects must be
+ * allocated using the object_new() family of functions and not
+ * statically embedded in a larger struct.
+ *
* Returns: %true on success, %false on failure.
*/
bool object_initialize_child_with_propsv(Object *parentobj,
const char *propname,
void *childobj, size_t size, const char *type,
- Error **errp, va_list vargs);
+ Error **errp, va_list vargs)
+ QEMU_DEPRECATED;
/**
* object_initialize_child:
@@ -917,13 +932,18 @@ bool object_initialize_child_with_propsv(Object *parentobj,
* object_initialize_child_with_props(parent, propname,
* child, sizeof(*child), type,
* &error_abort, NULL)
+ *
+ * Use of this function is now deprecated. All objects must be
+ * allocated using the object_new() family of functions and not
+ * statically embedded in a larger struct.
*/
#define object_initialize_child(parent, propname, child, type) \
object_initialize_child_internal((parent), (propname), \
(child), sizeof(*(child)), (type))
void object_initialize_child_internal(Object *parent, const char *propname,
void *child, size_t size,
- const char *type);
+ const char *type)
+ QEMU_DEPRECATED;
/**
* object_dynamic_cast:
diff --git a/qom/object.c b/qom/object.c
index 0ac201de4c..33b2801ee4 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -522,9 +522,11 @@ bool object_initialize_child_with_props(Object *parentobj,
bool ok;
va_start(vargs, errp);
+QEMU_DEPRECATIONS_OFF;
ok = object_initialize_child_with_propsv(parentobj, propname,
childobj, size, type, errp,
vargs);
+QEMU_DEPRECATIONS_ON;
va_end(vargs);
return ok;
}
@@ -539,7 +541,9 @@ bool object_initialize_child_with_propsv(Object *parentobj,
Object *obj;
UserCreatable *uc;
+QEMU_DEPRECATIONS_OFF;
object_initialize(childobj, size, type);
+QEMU_DEPRECATIONS_ON;
obj = OBJECT(childobj);
if (!object_set_propv(obj, vargs, errp)) {
@@ -576,8 +580,10 @@ void object_initialize_child_internal(Object *parent,
void *child, size_t size,
const char *type)
{
+QEMU_DEPRECATIONS_OFF;
object_initialize_child_with_props(parent, propname, child, size, type,
&error_abort, NULL);
+QEMU_DEPRECATIONS_ON;
}
static inline bool object_property_is_child(ObjectProperty *prop)
--
2.54.0
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [RFC 2/7] qom: deprecated embedding object structs within other objects
2026-06-16 15:55 ` [RFC 2/7] qom: deprecated embedding object structs within other objects Daniel P. Berrangé
@ 2026-06-16 16:15 ` Peter Maydell
2026-06-16 16:43 ` Daniel P. Berrangé
0 siblings, 1 reply; 27+ messages in thread
From: Peter Maydell @ 2026-06-16 16:15 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: qemu-devel, Philippe Mathieu-Daudé, Pierrick Bouvier,
Peter Xu, Hervé Poussineau, Alex Bennée,
Michael S. Tsirkin, Akihiko Odaki, Aurelien Jarno, Fabiano Rosas,
Paolo Bonzini, BALATON Zoltan, Mark Cave-Ayland,
Marc-André Lureau
On Tue, 16 Jun 2026 at 16:56, Daniel P. Berrangé <berrange@redhat.com> wrote:
>
> The QOM APIs currently allow objects to be either allocated directly
> on the heap, or statically embedded inside the struct of another object.
>
> For the latter QOM has logic to avoid calling 'free' on the object when
> finalizers complete, however, this is not sufficient to make the
> practice safe.
>
> Users of QOM expect that if they call "object_ref" to acquire their own
> reference, then object will never be freed as long as they hold it.
>
> This expectation is broken when an instance is embedded, as the "owner"
> object's may be finalized, which frees the memory that is storing the
> embedded QOM instance, even if its ref-count is still live.
>
> Worse still is that a user of a QOM object cannot easily tell if the
> instance they're using is embedded or directly heap allocated.
>
> Mark the APIs for embedding objects as deprecated as the first step
> towards removal of this flawed design concept. All objects must now
> be directly heap allocated going forward, and existing usage must be
> incrementally converted.
I think if you mark an API that we call in 800+ places and 150+ files
as deprecated, mostly what will happen is nobody ever turns on the
--enable-deprecated option because the output will be full of noise...
-- PMM
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC 2/7] qom: deprecated embedding object structs within other objects
2026-06-16 16:15 ` Peter Maydell
@ 2026-06-16 16:43 ` Daniel P. Berrangé
0 siblings, 0 replies; 27+ messages in thread
From: Daniel P. Berrangé @ 2026-06-16 16:43 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, Philippe Mathieu-Daudé, Pierrick Bouvier,
Peter Xu, Hervé Poussineau, Alex Bennée,
Michael S. Tsirkin, Akihiko Odaki, Aurelien Jarno, Fabiano Rosas,
Paolo Bonzini, BALATON Zoltan, Mark Cave-Ayland,
Marc-André Lureau
On Tue, Jun 16, 2026 at 05:15:22PM +0100, Peter Maydell wrote:
> On Tue, 16 Jun 2026 at 16:56, Daniel P. Berrangé <berrange@redhat.com> wrote:
> >
> > The QOM APIs currently allow objects to be either allocated directly
> > on the heap, or statically embedded inside the struct of another object.
> >
> > For the latter QOM has logic to avoid calling 'free' on the object when
> > finalizers complete, however, this is not sufficient to make the
> > practice safe.
> >
> > Users of QOM expect that if they call "object_ref" to acquire their own
> > reference, then object will never be freed as long as they hold it.
> >
> > This expectation is broken when an instance is embedded, as the "owner"
> > object's may be finalized, which frees the memory that is storing the
> > embedded QOM instance, even if its ref-count is still live.
> >
> > Worse still is that a user of a QOM object cannot easily tell if the
> > instance they're using is embedded or directly heap allocated.
> >
> > Mark the APIs for embedding objects as deprecated as the first step
> > towards removal of this flawed design concept. All objects must now
> > be directly heap allocated going forward, and existing usage must be
> > incrementally converted.
>
> I think if you mark an API that we call in 800+ places and 150+ files
> as deprecated, mostly what will happen is nobody ever turns on the
> --enable-deprecated option because the output will be full of noise...
That is a challenge. The baseline is that developers have no visibility
of use of deprecated APIs at all, and we barely even document them.
My thought is that even if --enable-deprecated is rarely enabled, at
least having QEMU_DEPRECATED visible in the header files is a red flag
for developers to look elsewhere for their solution.
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 27+ messages in thread
* [RFC 3/7] qom: deprecate use of instance properties
2026-06-16 15:55 [RFC 0/7] qom: deprecate embedded objects and instance properties Daniel P. Berrangé
2026-06-16 15:55 ` [RFC 1/7] meson: add --enable-deprecations configure flag Daniel P. Berrangé
2026-06-16 15:55 ` [RFC 2/7] qom: deprecated embedding object structs within other objects Daniel P. Berrangé
@ 2026-06-16 15:55 ` Daniel P. Berrangé
2026-06-16 15:55 ` [RFC 4/7] system: add memory_region_new / memory_region_new_io Daniel P. Berrangé
` (6 subsequent siblings)
9 siblings, 0 replies; 27+ messages in thread
From: Daniel P. Berrangé @ 2026-06-16 15:55 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Peter Xu,
Hervé Poussineau, Alex Bennée, Michael S. Tsirkin,
Akihiko Odaki, Daniel P. Berrangé, Aurelien Jarno,
Fabiano Rosas, Paolo Bonzini, BALATON Zoltan, Mark Cave-Ayland,
Marc-André Lureau
The concept of class properties was introduced over 10 years ago.
While there is significant use of class properties, there is a
long way to go before any conversion is complete and new uses are
often introduced as it is not obvious that class properties are
preferred.
The downsides of instances properties are:
* Increased memory usage as the property info is duplicated
across every instance.
* Introspection side effects, since instances need to be created
to be introspected and this can have unexpected side effects
if code is not expecting these throwaway instances to be
around.
* Non-introspectable designs, if properties are conditionally
registered against instances, those props may not be visible
when a dummy instances is created for introspection.
This deprecates the use of instance properties for all regular
scalar properties. ie strings, integers, enums, etc.
It does not deprecate instance properties used for setting up
the QOM composition tree child relationships, nor the link or
alias properties.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
include/qom/object.h | 70 +++++++++++++++++++++++++++++++++++++-------
qom/object.c | 28 ++++++++++++++++++
2 files changed, 88 insertions(+), 10 deletions(-)
diff --git a/include/qom/object.h b/include/qom/object.h
index dd708b1136..e9ce15d595 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1175,6 +1175,10 @@ void object_unref(void *obj);
* @opaque: an opaque pointer to pass to the callbacks for the property
* @errp: pointer to error object
*
+ * Use of this function is now deprecated. All properties must be
+ * registered against the class, using the object_class_property_add()
+ * function and not registered against instances.
+ *
* Returns: The #ObjectProperty; this can be used to set the @resolve
* callback for child and link properties.
*/
@@ -1183,7 +1187,8 @@ ObjectProperty *object_property_try_add(Object *obj, const char *name,
ObjectPropertyAccessor *get,
ObjectPropertyAccessor *set,
ObjectPropertyRelease *release,
- void *opaque, Error **errp);
+ void *opaque, Error **errp)
+ QEMU_DEPRECATED;
/**
* object_property_add:
@@ -1206,13 +1211,18 @@ ObjectProperty *object_property_try_add(Object *obj, const char *name,
* 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
+ *
+ * Use of this function is now deprecated. All properties must be
+ * registered against the class, using the object_class_property_add()
+ * function and not registered against instances.
*/
ObjectProperty *object_property_add(Object *obj, const char *name,
const char *type,
ObjectPropertyAccessor *get,
ObjectPropertyAccessor *set,
ObjectPropertyRelease *release,
- void *opaque);
+ void *opaque)
+ QEMU_DEPRECATED;
void object_property_del(Object *obj, const char *name);
@@ -1873,11 +1883,16 @@ Object *object_resolve_and_typecheck(const char *path, const char *name,
* Add a string property using getters/setters. This function will add a
* property of type 'string'.
*
+ * Use of this function is now deprecated. All properties must be
+ * registered against the class, using the object_class_property_add_str()
+ * function and not registered against instances.
+ *
* Returns: The newly added property on success, or %NULL on failure.
*/
ObjectProperty *object_property_add_str(Object *obj, const char *name,
char *(*get)(Object *, Error **),
- void (*set)(Object *, const char *, Error **));
+ void (*set)(Object *, const char *, Error **))
+ QEMU_DEPRECATED;
ObjectProperty *object_class_property_add_str(ObjectClass *klass,
const char *name,
@@ -1895,11 +1910,16 @@ ObjectProperty *object_class_property_add_str(ObjectClass *klass,
* Add a bool property using getters/setters. This function will add a
* property of type 'bool'.
*
+ * Use of this function is now deprecated. All properties must be
+ * registered against the class, using the object_class_property_add_bool()
+ * function and not registered against instances.
+ *
* Returns: The newly added property on success, or %NULL on failure.
*/
ObjectProperty *object_property_add_bool(Object *obj, const char *name,
bool (*get)(Object *, Error **),
- void (*set)(Object *, bool, Error **));
+ void (*set)(Object *, bool, Error **))
+ QEMU_DEPRECATED;
ObjectProperty *object_class_property_add_bool(ObjectClass *klass,
const char *name,
@@ -1918,13 +1938,18 @@ ObjectProperty *object_class_property_add_bool(ObjectClass *klass,
* Add an enum property using getters/setters. This function will add a
* property of type '@typename'.
*
+ * Use of this function is now deprecated. All properties must be
+ * registered against the class, using the object_class_property_add_enum()
+ * function and not registered against instances.
+ *
* 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 **));
+ void (*set)(Object *, int, Error **))
+ QEMU_DEPRECATED;
ObjectProperty *object_class_property_add_enum(ObjectClass *klass,
const char *name,
@@ -1942,10 +1967,15 @@ ObjectProperty *object_class_property_add_enum(ObjectClass *klass,
* Add a read-only struct tm valued property using a getter function.
* This function will add a property of type 'struct tm'.
*
+ * Use of this function is now deprecated. All properties must be
+ * registered against the class, using the object_class_property_add_tm()
+ * function and not registered against instances.
+ *
* 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 **));
+ void (*get)(Object *, struct tm *, Error **))
+ QEMU_DEPRECATED;
ObjectProperty *object_class_property_add_tm(ObjectClass *klass,
const char *name,
@@ -1970,11 +2000,16 @@ typedef enum {
* Add an integer property in memory. This function will add a
* property of type 'uint8'.
*
+ * Use of this function is now deprecated. All properties must be
+ * registered against the class, using the object_class_property_add_uint8_ptr()
+ * function and not registered against instances.
+ *
* Returns: The newly added property on success, or %NULL on failure.
*/
ObjectProperty *object_property_add_uint8_ptr(Object *obj, const char *name,
const uint8_t *v,
- ObjectPropertyFlags flags);
+ ObjectPropertyFlags flags)
+ QEMU_DEPRECATED;
ObjectProperty *object_class_property_add_uint8_ptr(ObjectClass *klass,
const char *name,
@@ -1991,11 +2026,16 @@ ObjectProperty *object_class_property_add_uint8_ptr(ObjectClass *klass,
* Add an integer property in memory. This function will add a
* property of type 'uint16'.
*
+ * Use of this function is now deprecated. All properties must be
+ * registered against the class, using the object_class_property_add_uint16_ptr()
+ * function and not registered against instances.
+ *
* Returns: The newly added property on success, or %NULL on failure.
*/
ObjectProperty *object_property_add_uint16_ptr(Object *obj, const char *name,
const uint16_t *v,
- ObjectPropertyFlags flags);
+ ObjectPropertyFlags flags)
+ QEMU_DEPRECATED;
ObjectProperty *object_class_property_add_uint16_ptr(ObjectClass *klass,
const char *name,
@@ -2012,11 +2052,16 @@ ObjectProperty *object_class_property_add_uint16_ptr(ObjectClass *klass,
* Add an integer property in memory. This function will add a
* property of type 'uint32'.
*
+ * Use of this function is now deprecated. All properties must be
+ * registered against the class, using the object_class_property_add_uint32_ptr()
+ * function and not registered against instances.
+ *
* Returns: The newly added property on success, or %NULL on failure.
*/
ObjectProperty *object_property_add_uint32_ptr(Object *obj, const char *name,
const uint32_t *v,
- ObjectPropertyFlags flags);
+ ObjectPropertyFlags flags)
+ QEMU_DEPRECATED;
ObjectProperty *object_class_property_add_uint32_ptr(ObjectClass *klass,
const char *name,
@@ -2033,11 +2078,16 @@ ObjectProperty *object_class_property_add_uint32_ptr(ObjectClass *klass,
* Add an integer property in memory. This function will add a
* property of type 'uint64'.
*
+ * Use of this function is now deprecated. All properties must be
+ * registered against the class, using the object_class_property_add_uint64_ptr()
+ * function and not registered against instances.
+ *
* Returns: The newly added property on success, or %NULL on failure.
*/
ObjectProperty *object_property_add_uint64_ptr(Object *obj, const char *name,
const uint64_t *v,
- ObjectPropertyFlags flags);
+ ObjectPropertyFlags flags)
+ QEMU_DEPRECATED;
ObjectProperty *object_class_property_add_uint64_ptr(ObjectClass *klass,
const char *name,
diff --git a/qom/object.c b/qom/object.c
index 33b2801ee4..415d5c5291 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1362,8 +1362,10 @@ object_property_try_add(Object *obj, const char *name, const char *type,
for (i = 0; i < INT16_MAX; ++i) {
char *full_name = g_strdup_printf("%s[%d]", name_no_array, i);
+ QEMU_DEPRECATIONS_OFF;
ret = object_property_try_add(obj, full_name, type, get, set,
release, opaque, NULL);
+ QEMU_DEPRECATIONS_ON;
g_free(full_name);
if (ret) {
break;
@@ -1403,8 +1405,10 @@ object_property_add(Object *obj, const char *name, const char *type,
ObjectPropertyRelease *release,
void *opaque)
{
+ QEMU_DEPRECATIONS_OFF;
return object_property_try_add(obj, name, type, get, set, release,
opaque, &error_abort);
+ QEMU_DEPRECATIONS_ON;
}
ObjectProperty *
@@ -1951,9 +1955,11 @@ object_property_try_add_child(Object *obj, const char *name,
type = g_strdup_printf("child<%s>", object_get_typename(child));
+ QEMU_DEPRECATIONS_OFF;
op = object_property_try_add(obj, name, type, object_get_child_property,
NULL, object_finalize_child_property,
child, errp);
+ QEMU_DEPRECATIONS_ON;
if (!op) {
return NULL;
}
@@ -1967,7 +1973,9 @@ ObjectProperty *
object_property_add_child(Object *obj, const char *name,
Object *child)
{
+ QEMU_DEPRECATIONS_OFF;
return object_property_try_add_child(obj, name, child, &error_abort);
+ QEMU_DEPRECATIONS_ON;
}
void object_property_allow_set_link(const Object *obj, const char *name,
@@ -2145,11 +2153,13 @@ object_add_link_prop(Object *obj, const char *name,
full_type = g_strdup_printf("link<%s>", type);
+ QEMU_DEPRECATIONS_OFF;
op = object_property_add(obj, name, full_type,
object_get_link_property,
check ? object_set_link_property : NULL,
object_release_link_property,
prop);
+ QEMU_DEPRECATIONS_ON;
op->resolve = object_resolve_link_property;
return op;
}
@@ -2442,11 +2452,13 @@ object_property_add_str(Object *obj, const char *name,
prop->get = get;
prop->set = set;
+ QEMU_DEPRECATIONS_OFF;
return object_property_add(obj, name, "string",
get ? property_get_str : NULL,
set ? property_set_str : NULL,
property_release_data,
prop);
+ QEMU_DEPRECATIONS_ON;
}
ObjectProperty *
@@ -2512,11 +2524,13 @@ object_property_add_bool(Object *obj, const char *name,
prop->get = get;
prop->set = set;
+ QEMU_DEPRECATIONS_OFF;
return object_property_add(obj, name, "bool",
get ? property_get_bool : NULL,
set ? property_set_bool : NULL,
property_release_data,
prop);
+ QEMU_DEPRECATIONS_ON;
}
ObjectProperty *
@@ -2577,11 +2591,13 @@ object_property_add_enum(Object *obj, const char *name,
prop->get = get;
prop->set = set;
+ QEMU_DEPRECATIONS_OFF;
return object_property_add(obj, name, typename,
get ? property_get_enum : NULL,
set ? property_set_enum : NULL,
property_release_data,
prop);
+ QEMU_DEPRECATIONS_ON;
}
ObjectProperty *
@@ -2655,10 +2671,12 @@ object_property_add_tm(Object *obj, const char *name,
prop->get = get;
+ QEMU_DEPRECATIONS_OFF;
return object_property_add(obj, name, "struct tm",
get ? property_get_tm : NULL, NULL,
property_release_data,
prop);
+ QEMU_DEPRECATIONS_ON;
}
ObjectProperty *
@@ -2775,8 +2793,10 @@ object_property_add_uint8_ptr(Object *obj, const char *name,
setter = property_set_uint8_ptr;
}
+ QEMU_DEPRECATIONS_OFF;
return object_property_add(obj, name, "uint8",
getter, setter, NULL, (void *)v);
+ QEMU_DEPRECATIONS_ON;
}
ObjectProperty *
@@ -2815,8 +2835,10 @@ object_property_add_uint16_ptr(Object *obj, const char *name,
setter = property_set_uint16_ptr;
}
+ QEMU_DEPRECATIONS_OFF;
return object_property_add(obj, name, "uint16",
getter, setter, NULL, (void *)v);
+ QEMU_DEPRECATIONS_ON;
}
ObjectProperty *
@@ -2855,8 +2877,10 @@ object_property_add_uint32_ptr(Object *obj, const char *name,
setter = property_set_uint32_ptr;
}
+ QEMU_DEPRECATIONS_OFF;
return object_property_add(obj, name, "uint32",
getter, setter, NULL, (void *)v);
+ QEMU_DEPRECATIONS_ON;
}
ObjectProperty *
@@ -2895,8 +2919,10 @@ object_property_add_uint64_ptr(Object *obj, const char *name,
setter = property_set_uint64_ptr;
}
+ QEMU_DEPRECATIONS_OFF;
return object_property_add(obj, name, "uint64",
getter, setter, NULL, (void *)v);
+ QEMU_DEPRECATIONS_ON;
}
ObjectProperty *
@@ -2983,11 +3009,13 @@ object_property_add_alias(Object *obj, const char *name,
prop->target_obj = target_obj;
prop->target_name = g_strdup(target_name);
+ QEMU_DEPRECATIONS_OFF;
op = object_property_add(obj, name, prop_type,
property_get_alias,
property_set_alias,
property_release_alias,
prop);
+ QEMU_DEPRECATIONS_ON;
op->resolve = property_resolve_alias;
if (target_prop->defval) {
op->defval = qobject_ref(target_prop->defval);
--
2.54.0
^ permalink raw reply related [flat|nested] 27+ messages in thread* [RFC 4/7] system: add memory_region_new / memory_region_new_io
2026-06-16 15:55 [RFC 0/7] qom: deprecate embedded objects and instance properties Daniel P. Berrangé
` (2 preceding siblings ...)
2026-06-16 15:55 ` [RFC 3/7] qom: deprecate use of instance properties Daniel P. Berrangé
@ 2026-06-16 15:55 ` Daniel P. Berrangé
2026-06-17 12:49 ` Paolo Bonzini
2026-06-16 15:55 ` [RFC 5/7] system: add qemu_irq_new / qemu_irq_new_child / qemu_irq_new_array Daniel P. Berrangé
` (5 subsequent siblings)
9 siblings, 1 reply; 27+ messages in thread
From: Daniel P. Berrangé @ 2026-06-16 15:55 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Peter Xu,
Hervé Poussineau, Alex Bennée, Michael S. Tsirkin,
Akihiko Odaki, Daniel P. Berrangé, Aurelien Jarno,
Fabiano Rosas, Paolo Bonzini, BALATON Zoltan, Mark Cave-Ayland,
Marc-André Lureau
Prepare for the move to dynamically allocated memory regions by
introducing memory_region_new and memory_region_new_io functions
which call through to object_new instead of object_initialize.
TBD: add "new" variants for all the other memory_region_init
variants.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
include/system/memory.h | 76 ++++++++++++++++++++++++++++++------
system/memory.c | 85 ++++++++++++++++++++++++++++++++++-------
2 files changed, 136 insertions(+), 25 deletions(-)
diff --git a/include/system/memory.h b/include/system/memory.h
index 1417132f6d..b4c5a185c0 100644
--- a/include/system/memory.h
+++ b/include/system/memory.h
@@ -1300,19 +1300,44 @@ static inline bool memory_region_section_intersect_range(MemoryRegionSection *s,
/**
* memory_region_init: Initialize a memory region
- *
- * The region typically acts as a container for other memory regions. Use
- * memory_region_add_subregion() to add subregions.
- *
* @mr: the #MemoryRegion to be initialized
* @owner: the object that tracks the region's reference count
* @name: used for debugging; not visible to the user or ABI
* @size: size of the region; any subregions beyond this size will be clipped
+ *
+ * The region typically acts as a container for other memory regions. Use
+ * memory_region_add_subregion() to add subregions.
+ *
+ * Use of this function is now deprecated. All memory regions must be
+ * allocated using the memory_region_new() family of functions and not
+ * statically embedded in a larger struct.
*/
void memory_region_init(MemoryRegion *mr,
Object *owner,
const char *name,
- uint64_t size);
+ uint64_t size)
+ QEMU_DEPRECATED;
+
+
+/**
+ * memory_region_new: Allocate a memory region.
+ * @owner: the object that owns the memory region in the composition tree
+ * @name: used for debugging; not visible to the user or ABI
+ * @size: size of the region; any subregions beyond this size will be clipped
+ *
+ * The region typically acts as a container for other memory regions. Use
+ * memory_region_add_subregion() to add subregions.
+ *
+ * The returned memory region will have a single reference, which is
+ * held by the @owner object in the QOM composition tree. Thus in the
+ * absence of any further references being acquired, the memory region
+ * will be freed when @owner is freed
+ *
+ * Returns: the newly allocated memory region
+ */
+MemoryRegion *memory_region_new(Object *owner,
+ const char *name,
+ uint64_t size);
/**
* memory_region_ref: Add 1 to a memory region's reference count
@@ -1344,11 +1369,7 @@ void memory_region_ref(MemoryRegion *mr);
void memory_region_unref(MemoryRegion *mr);
/**
- * memory_region_init_io: Initialize an I/O memory region.
- *
- * Accesses into the region will cause the callbacks in @ops to be called.
- * if @size is nonzero, subregions will be clipped to @size.
- *
+ * memory_region_init_io: Initialize an I/O memory region
* @mr: the #MemoryRegion to be initialized.
* @owner: the object that tracks the region's reference count
* @ops: a structure containing read and write callbacks to be used when
@@ -1356,13 +1377,46 @@ void memory_region_unref(MemoryRegion *mr);
* @opaque: passed to the read and write callbacks of the @ops structure.
* @name: used for debugging; not visible to the user or ABI
* @size: size of the region.
+ *
+ * Accesses into the region will cause the callbacks in @ops to be called.
+ * if @size is nonzero, subregions will be clipped to @size.
+ *
+ * Use of this function is now deprecated. All memory regions must be
+ * allocated using the memory_region_new() family of functions and not
+ * statically embedded in a larger struct.
*/
void memory_region_init_io(MemoryRegion *mr,
Object *owner,
const MemoryRegionOps *ops,
void *opaque,
const char *name,
- uint64_t size);
+ uint64_t size)
+ QEMU_DEPRECATED;
+
+/**
+ * memory_region_new_io: Allocates an I/O memory region
+ * @owner: the object that tracks the region's reference count
+ * @ops: a structure containing read and write callbacks to be used when
+ * I/O is performed on the region.
+ * @opaque: passed to the read and write callbacks of the @ops structure.
+ * @name: used for debugging; not visible to the user or ABI
+ * @size: size of the region.
+ *
+ * Accesses into the region will cause the callbacks in @ops to be called.
+ * if @size is nonzero, subregions will be clipped to @size.
+ *
+ * The returned memory region will have a single reference, which is
+ * held by the @owner object in the QOM composition tree. Thus in the
+ * absence of any further references being acquired, the memory region
+ * will be freed when @owner is freed
+ *
+ * Returns: the newly allocated memory region
+ */
+MemoryRegion *memory_region_new_io(Object *owner,
+ const MemoryRegionOps *ops,
+ void *opaque,
+ const char *name,
+ uint64_t size);
/**
* memory_region_init_ram_flags_nomigrate: Initialize RAM memory region.
diff --git a/system/memory.c b/system/memory.c
index 739ba11da6..e8a539e37e 100644
--- a/system/memory.c
+++ b/system/memory.c
@@ -1214,6 +1214,18 @@ static char *memory_region_escape_name(const char *name)
return escaped;
}
+static char *memory_region_make_child(Object **owner,
+ const char *name)
+{
+ g_autofree char *escaped_name = memory_region_escape_name(name);
+
+ if (!*owner) {
+ *owner = machine_get_container("unattached");
+ }
+
+ return g_strdup_printf("%s[*]", escaped_name);
+}
+
static void memory_region_do_init(MemoryRegion *mr,
Object *owner,
const char *name,
@@ -1227,20 +1239,6 @@ static void memory_region_do_init(MemoryRegion *mr,
mr->owner = owner;
mr->dev = (DeviceState *) object_dynamic_cast(mr->owner, TYPE_DEVICE);
mr->ram_block = NULL;
-
- if (name) {
- char *escaped_name = memory_region_escape_name(name);
- char *name_array = g_strdup_printf("%s[*]", escaped_name);
-
- if (!owner) {
- owner = machine_get_container("unattached");
- }
-
- object_property_add_child(owner, name_array, OBJECT(mr));
- object_unref(OBJECT(mr));
- g_free(name_array);
- g_free(escaped_name);
- }
}
void memory_region_init(MemoryRegion *mr,
@@ -1250,6 +1248,31 @@ void memory_region_init(MemoryRegion *mr,
{
object_initialize(mr, sizeof(*mr), TYPE_MEMORY_REGION);
memory_region_do_init(mr, owner, name, size);
+ if (name) {
+ g_autofree char *childname = memory_region_make_child(&owner, name);
+ object_property_add_child(owner, childname, OBJECT(mr));
+ object_unref(OBJECT(mr));
+ }
+}
+
+MemoryRegion *memory_region_new(Object *owner,
+ const char *name,
+ uint64_t size)
+{
+ /*
+ * error_abort is safe, because 'childname' includes a wildcard
+ * for dynamically assigning a unique name. Thus adding the child
+ * property cannot fail
+ */
+ MemoryRegion *mr = MEMORY_REGION(object_new(TYPE_MEMORY_REGION));
+ memory_region_do_init(mr, owner, name, size);
+ if (name) {
+ g_autofree char *childname = memory_region_make_child(&owner, name);
+ object_property_add_child(owner, childname, OBJECT(mr));
+ object_unref(OBJECT(mr));
+
+ }
+ return mr;
}
static void memory_region_get_container(Object *obj, Visitor *v,
@@ -1574,10 +1597,22 @@ void memory_region_init_io(MemoryRegion *mr, Object *owner,
const char *name, uint64_t size)
{
g_assert(!ops || !(ops->impl.unaligned && !ops->valid.unaligned));
+ QEMU_DEPRECATIONS_OFF;
memory_region_init(mr, owner, name, size);
+ QEMU_DEPRECATIONS_ON;
memory_region_set_ops(mr, ops, opaque);
}
+MemoryRegion *memory_region_new_io(Object *owner,
+ const MemoryRegionOps *ops, void *opaque,
+ const char *name, uint64_t size)
+{
+ g_assert(!ops || !(ops->impl.unaligned && !ops->valid.unaligned));
+ MemoryRegion *mr = memory_region_new(owner, name, size);
+ memory_region_set_ops(mr, ops, opaque);
+ return mr;
+}
+
static bool memory_region_set_ram_block(MemoryRegion *mr, RAMBlock *rb)
{
mr->terminates = true;
@@ -1597,7 +1632,9 @@ bool memory_region_init_ram_flags_nomigrate(MemoryRegion *mr, Object *owner,
{
RAMBlock *rb;
+ QEMU_DEPRECATIONS_OFF;
memory_region_init(mr, owner, name, size);
+ QEMU_DEPRECATIONS_ON;
mr->ram = true;
rb = qemu_ram_alloc(size, ram_flags, mr, errp);
return memory_region_set_ram_block(mr, rb);
@@ -1615,7 +1652,9 @@ bool memory_region_init_resizeable_ram(MemoryRegion *mr,
{
RAMBlock *rb;
+ QEMU_DEPRECATIONS_OFF;
memory_region_init(mr, owner, name, size);
+ QEMU_DEPRECATIONS_ON;
mr->ram = true;
rb = qemu_ram_alloc_resizeable(size, max_size, resized, mr, errp);
return memory_region_set_ram_block(mr, rb);
@@ -1630,7 +1669,9 @@ bool memory_region_init_ram_from_file(MemoryRegion *mr, Object *owner,
{
RAMBlock *rb;
+ QEMU_DEPRECATIONS_OFF;
memory_region_init(mr, owner, name, size);
+ QEMU_DEPRECATIONS_ON;
mr->ram = true;
mr->readonly = !!(ram_flags & RAM_READONLY);
mr->align = align;
@@ -1645,7 +1686,9 @@ bool memory_region_init_ram_from_fd(MemoryRegion *mr, Object *owner,
{
RAMBlock *rb;
+ QEMU_DEPRECATIONS_OFF;
memory_region_init(mr, owner, name, size);
+ QEMU_DEPRECATIONS_ON;
mr->ram = true;
mr->readonly = !!(ram_flags & RAM_READONLY);
rb = qemu_ram_alloc_from_fd(size, size, NULL, mr, ram_flags, fd, offset,
@@ -1667,7 +1710,9 @@ void memory_region_init_ram_ptr(MemoryRegion *mr, Object *owner,
const char *name, uint64_t size,
void *ptr)
{
+ QEMU_DEPRECATIONS_OFF;
memory_region_init(mr, owner, name, size);
+ QEMU_DEPRECATIONS_ON;
mr->ram = true;
memory_region_set_ram_ptr(mr, size, ptr);
}
@@ -1676,7 +1721,9 @@ void memory_region_init_ram_device_ptr(MemoryRegion *mr, Object *owner,
const char *name, uint64_t size,
void *ptr)
{
+ QEMU_DEPRECATIONS_OFF;
memory_region_init_io(mr, owner, &ram_device_mem_ops, mr, name, size);
+ QEMU_DEPRECATIONS_ON;
mr->ram = true;
mr->ram_device = true;
memory_region_set_ram_ptr(mr, size, ptr);
@@ -1686,7 +1733,9 @@ void memory_region_init_alias(MemoryRegion *mr, Object *owner,
const char *name, MemoryRegion *orig,
hwaddr offset, uint64_t size)
{
+ QEMU_DEPRECATIONS_OFF;
memory_region_init(mr, owner, name, size);
+ QEMU_DEPRECATIONS_ON;
mr->alias = orig;
mr->alias_offset = offset;
}
@@ -1704,6 +1753,12 @@ void memory_region_init_iommu(void *_iommu_mr,
object_initialize(_iommu_mr, instance_size, mrtypename);
mr = MEMORY_REGION(_iommu_mr);
memory_region_do_init(mr, owner, name, size);
+ if (name) {
+ g_autofree char *childname = memory_region_make_child(&owner, name);
+ object_property_add_child(owner, childname, OBJECT(mr));
+ object_unref(OBJECT(mr));
+ }
+
iommu_mr = IOMMU_MEMORY_REGION(mr);
mr->terminates = true; /* then re-forwards */
QLIST_INIT(&iommu_mr->iommu_notify);
@@ -3703,7 +3758,9 @@ bool memory_region_init_rom_device(MemoryRegion *mr, Object *owner,
RAMBlock *rb;
assert(ops);
+ QEMU_DEPRECATIONS_OFF;
memory_region_init_io(mr, owner, ops, opaque, name, size);
+ QEMU_DEPRECATIONS_ON;
rb = qemu_ram_alloc(size, 0, mr, errp);
if (memory_region_set_ram_block(mr, rb)) {
mr->rom_device = true;
--
2.54.0
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [RFC 4/7] system: add memory_region_new / memory_region_new_io
2026-06-16 15:55 ` [RFC 4/7] system: add memory_region_new / memory_region_new_io Daniel P. Berrangé
@ 2026-06-17 12:49 ` Paolo Bonzini
2026-06-17 14:10 ` BALATON Zoltan
0 siblings, 1 reply; 27+ messages in thread
From: Paolo Bonzini @ 2026-06-17 12:49 UTC (permalink / raw)
To: Daniel P. Berrangé, qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Peter Xu,
Hervé Poussineau, Alex Bennée, Michael S. Tsirkin,
Akihiko Odaki, Aurelien Jarno, Fabiano Rosas, BALATON Zoltan,
Mark Cave-Ayland, Marc-André Lureau
On 6/16/26 17:55, Daniel P. Berrangé wrote:
> Prepare for the move to dynamically allocated memory regions by
> introducing memory_region_new and memory_region_new_io functions
> which call through to object_new instead of object_initialize.
>
> TBD: add "new" variants for all the other memory_region_init
> variants.
>
> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Zoltan already proposed this, but I really think it's a bad idea.
MemoryRegionOps callback will certainly access fields in the parent.
Having a separate object gives you no benefit because you still have the
same use-after-free if the MemoryRegion outlives the device. Likewise
for buses.
For buses, the fact that the parent and child live at the same time is
explicitly tracked with mutual refcount and unparent. If it's not, we
have the hack that Akihiko mentioned
(https://lists.gnu.org/archive/html/qemu-devel/2026-06/msg03459.html):
> However, this is insufficient to avoid calling object_ref() for all
> embedded objects. For example, consider an embedded Device that has a
> MemoryRegion. When referencing a MemoryRegion for guest memory access,
> QEMU automatically references the owning Device to keep the MemoryRegion
> alive. However, that reference is ineffective if the Device itself is
> embedded, because object_ref() does not keep the containing storage
> alive.
If the device itself is embedded, then all the invariants must hold
recursively:
- the device must be kept alive by mutual references between the device
itself and its parent;
- unparent for the device should wait for all guest memory accesses to
be either completed or cancelled.
So, the problem is that "QEMU automatically references the owning Device
to keep the MemoryRegion alive" is a hack that should die. I added it,
mea culpa.
The model is that if it makes sense to have B outlive A, you use new. If
it doesn't, you use init. For MemoryRegions or anything that has
callbacks, it makes no sense to outlive the implementor of the
callbacks. There are exceptions if the number of objects is dynamic but
they're very rare.
I agree that there's extra complexity added by embedding; but I disagree
that removing embedding will fix any bugs, and because it will hide a
relationship between objects, I believe the complexity is not accidental.
Paolo
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC 4/7] system: add memory_region_new / memory_region_new_io
2026-06-17 12:49 ` Paolo Bonzini
@ 2026-06-17 14:10 ` BALATON Zoltan
0 siblings, 0 replies; 27+ messages in thread
From: BALATON Zoltan @ 2026-06-17 14:10 UTC (permalink / raw)
To: Paolo Bonzini
Cc: Daniel P. Berrangé, qemu-devel, Philippe Mathieu-Daudé,
Pierrick Bouvier, Peter Xu, Hervé Poussineau,
Alex Bennée, Michael S. Tsirkin, Akihiko Odaki,
Aurelien Jarno, Fabiano Rosas, Mark Cave-Ayland,
Marc-André Lureau
[-- Attachment #1: Type: text/plain, Size: 3671 bytes --]
On Wed, 17 Jun 2026, Paolo Bonzini wrote:
> On 6/16/26 17:55, Daniel P. Berrangé wrote:
>> Prepare for the move to dynamically allocated memory regions by
>> introducing memory_region_new and memory_region_new_io functions
>> which call through to object_new instead of object_initialize.
>>
>> TBD: add "new" variants for all the other memory_region_init
>> variants.
>>
>> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
>
> Zoltan already proposed this, but I really think it's a bad idea.
>
> MemoryRegionOps callback will certainly access fields in the parent. Having a
> separate object gives you no benefit because you still have the same
> use-after-free if the MemoryRegion outlives the device. Likewise for buses.
>
> For buses, the fact that the parent and child live at the same time is
> explicitly tracked with mutual refcount and unparent. If it's not, we have
> the hack that Akihiko mentioned
> (https://lists.gnu.org/archive/html/qemu-devel/2026-06/msg03459.html):
>
>> However, this is insufficient to avoid calling object_ref() for all
>> embedded objects. For example, consider an embedded Device that has a
>> MemoryRegion. When referencing a MemoryRegion for guest memory access,
>> QEMU automatically references the owning Device to keep the MemoryRegion
>> alive. However, that reference is ineffective if the Device itself is
>> embedded, because object_ref() does not keep the containing storage
>> alive.
>
> If the device itself is embedded, then all the invariants must hold
> recursively:
>
> - the device must be kept alive by mutual references between the device
> itself and its parent;
>
> - unparent for the device should wait for all guest memory accesses to be
> either completed or cancelled.
>
> So, the problem is that "QEMU automatically references the owning Device to
> keep the MemoryRegion alive" is a hack that should die. I added it, mea
> culpa.
>
> The model is that if it makes sense to have B outlive A, you use new. If it
> doesn't, you use init. For MemoryRegions or anything that has callbacks, it
> makes no sense to outlive the implementor of the callbacks. There are
> exceptions if the number of objects is dynamic but they're very rare.
>
> I agree that there's extra complexity added by embedding; but I disagree that
> removing embedding will fix any bugs, and because it will hide a relationship
> between objects, I believe the complexity is not accidental.
The problem is that memory regions cannot be ref counted because they are
piggybacking on their owner's ref count instead of using their own. So
while memory regions are QOM objects and the code is there to ref count
and free them with their owners this can't be used and we hack around that
by referencing the owner instead. If there's a dependency on the parent
then maybe the memory region should take a ref of the parent so it does
not go away until the memory region is freed or the owner relation needs
to be taken into account instead of using the parent ref count and
forbidding to make memory regions proper QOM objects which is very
confusing and leads to all sorts of other hacks.
And it also forces me to embed a bunch of memory regions in device states
that are otherwise not needed and already stored as PCI BARs or sysbus
regions so I should not need them in my device state. This added
complexity was my motivation but it turned out to be a larger issue and I
think restoring the ability to ref count memory regions and clean up the
hacks of keeping the parent alive with every object using its own ref
counts would be cleaner than keeping to the current way.
Regards,
BALATON Zoltan
^ permalink raw reply [flat|nested] 27+ messages in thread
* [RFC 5/7] system: add qemu_irq_new / qemu_irq_new_child / qemu_irq_new_array
2026-06-16 15:55 [RFC 0/7] qom: deprecate embedded objects and instance properties Daniel P. Berrangé
` (3 preceding siblings ...)
2026-06-16 15:55 ` [RFC 4/7] system: add memory_region_new / memory_region_new_io Daniel P. Berrangé
@ 2026-06-16 15:55 ` Daniel P. Berrangé
2026-06-16 16:22 ` Peter Maydell
2026-06-16 15:55 ` [RFC 6/7] hw/isa: convert PIIX embedded QOM objects to heap allocated Daniel P. Berrangé
` (4 subsequent siblings)
9 siblings, 1 reply; 27+ messages in thread
From: Daniel P. Berrangé @ 2026-06-16 15:55 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Peter Xu,
Hervé Poussineau, Alex Bennée, Michael S. Tsirkin,
Akihiko Odaki, Daniel P. Berrangé, Aurelien Jarno,
Fabiano Rosas, Paolo Bonzini, BALATON Zoltan, Mark Cave-Ayland,
Marc-André Lureau
Prepare for the move to dynamically allocated IRQ objects by
introducing qemu_irq_new / qemu_irq_new_child / qemu_irq_new_array
functions which call through to object_new instead of object_initialize.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/core/irq.c | 35 ++++++++++++++++++++
include/hw/core/irq.h | 75 ++++++++++++++++++++++++++++++++++++++++---
2 files changed, 106 insertions(+), 4 deletions(-)
diff --git a/hw/core/irq.c b/hw/core/irq.c
index 106805e241..e943c87b81 100644
--- a/hw/core/irq.c
+++ b/hw/core/irq.c
@@ -49,6 +49,13 @@ void qemu_init_irq(IRQState *irq, qemu_irq_handler handler, void *opaque,
init_irq_fields(irq, handler, opaque, n);
}
+IRQState *qemu_irq_new(qemu_irq_handler handler, void *opaque, int n)
+{
+ IRQState *irq = IRQ(object_new(TYPE_IRQ));
+ init_irq_fields(irq, handler, opaque, n);
+ return irq;
+}
+
void qemu_init_irq_child(Object *parent, const char *propname,
IRQState *irq, qemu_irq_handler handler,
void *opaque, int n)
@@ -57,14 +64,42 @@ void qemu_init_irq_child(Object *parent, const char *propname,
init_irq_fields(irq, handler, opaque, n);
}
+IRQState *qemu_irq_new_child(Object *parent, const char *propname,
+ qemu_irq_handler handler,
+ void *opaque, int n,
+ Error **errp)
+{
+ IRQState *irq = IRQ(object_new_with_props(TYPE_IRQ, parent, propname,
+ errp, NULL));
+ if (!irq) {
+ return NULL;
+ }
+ init_irq_fields(irq, handler, opaque, n);
+ return irq;
+}
+
+
void qemu_init_irqs(IRQState irq[], size_t count,
qemu_irq_handler handler, void *opaque)
{
for (size_t i = 0; i < count; i++) {
+ QEMU_DEPRECATIONS_OFF;
qemu_init_irq(&irq[i], handler, opaque, i);
+ QEMU_DEPRECATIONS_ON;
}
}
+IRQState **qemu_irq_new_array(size_t count,
+ qemu_irq_handler handler, void *opaque)
+{
+ IRQState **irqs = g_new0(IRQState *, count);
+ for (size_t i = 0; i < count; i++) {
+ irqs[i] = qemu_irq_new(handler, opaque, i);
+ }
+ return irqs;
+}
+
+
qemu_irq *qemu_extend_irqs(qemu_irq *old, int n_old, qemu_irq_handler handler,
void *opaque, int n)
{
diff --git a/include/hw/core/irq.h b/include/hw/core/irq.h
index 291fdd67df..af9bf6fb12 100644
--- a/include/hw/core/irq.h
+++ b/include/hw/core/irq.h
@@ -34,7 +34,12 @@ static inline void qemu_irq_pulse(qemu_irq irq)
qemu_set_irq(irq, 0);
}
-/*
+/**
+ * qemu_init_irq: Initialize IRQ
+ * @handler: handler function for incoming interrupts
+ * @opaque: opaque data to pass to @handler
+ * @n: interrupt number to pass to @handler
+ *
* Init a single IRQ. The irq is assigned with a handler, an opaque data
* and the interrupt number. The caller must free this with qemu_free_irq().
* If you are using this inside a device's init or realize method, then
@@ -42,7 +47,21 @@ static inline void qemu_irq_pulse(qemu_irq irq)
* to manually clean up the IRQ.
*/
void qemu_init_irq(IRQState *irq, qemu_irq_handler handler, void *opaque,
- int n);
+ int n)
+ QEMU_DEPRECATED;
+/**
+ * qemu_new_irq: Allocate IRQ
+ * @handler: handler function for incoming interrupts
+ * @opaque: opaque data to pass to @handler
+ * @n: interrupt number to pass to @handler
+ *
+ * The returned IRQ will have a single reference, which is held by the
+ * caller and must be released to free the returned IRQ object when
+ * no longer required.
+ *
+ * Returns: the newly allocated IRQ
+ */
+IRQState *qemu_irq_new(qemu_irq_handler handler, void *opaque, int n);
/**
* qemu_init_irq_child: Initialize IRQ and make it a QOM child
@@ -56,10 +75,38 @@ void qemu_init_irq(IRQState *irq, qemu_irq_handler handler, void *opaque,
* Init a single IRQ and make the IRQ object a child of @parent with
* the child-property name @propname. The IRQ object will thus be
* automatically freed when @parent is destroyed.
+ *
+ * Use of this function is now deprecated. All IRQs must be
+ * allocated using the qemu_irq_new() family of functions and not
+ * statically embedded in a larger struct.
*/
void qemu_init_irq_child(Object *parent, const char *propname,
IRQState *irq, qemu_irq_handler handler,
- void *opaque, int n);
+ void *opaque, int n)
+ QEMU_DEPRECATED;
+
+/**
+ * qemu_init_irq_child: Allocate IRQ and make it a QOM child
+ * @parent: QOM object which owns this IRQ
+ * @propname: child property name
+ * @handler: handler function for incoming interrupts
+ * @opaque: opaque data to pass to @handler
+ * @n: interrupt number to pass to @handler
+ *
+ * Allocate a single IRQ and make the IRQ object a child of @parent with
+ * the child-property name @propname.
+ *
+ * The returned IRQ will have a single reference, which is held by the
+ * @owner object in the QOM composition tree. Thus in the absence of
+ * any further references being acquired, the IRQ will be freed when
+ * @owner is freed
+ *
+ * Returns: the newly allocated IRQ
+ */
+IRQState *qemu_irq_new_child(Object *parent, const char *propname,
+ qemu_irq_handler handler,
+ void *opaque, int n,
+ Error **errp);
/**
@@ -69,9 +116,29 @@ void qemu_init_irq_child(Object *parent, const char *propname,
* @count: number of IRQs to initialize
* @handler: handler to assign to each IRQ
* @opaque: opaque data to pass to @handler
+ *
+ * Use of this function is now deprecated. All IRQs must be
+ * allocated using the qemu_irq_new() family of functions and not
+ * statically embedded in a larger struct.
*/
void qemu_init_irqs(IRQState irq[], size_t count,
- qemu_irq_handler handler, void *opaque);
+ qemu_irq_handler handler, void *opaque)
+ QEMU_DEPRECATED;
+/**
+ * qemu_irq_new_array: Allocate an array of IRQs.
+ * @count: number of IRQs to initialize
+ * @handler: handler to assign to each IRQ
+ * @opaque: opaque data to pass to @handler
+ *
+ * The returned IRQs will have a single reference, which is held by the
+ * caller and must be released to free the returned IRQs object when
+ * no longer required. The return array memory must also be freed by
+ * the caller.
+ *
+ * Returns: an array of IRQ objects
+ */
+IRQState **qemu_irq_new_array(size_t count,
+ qemu_irq_handler handler, void *opaque);
/* Returns an array of N IRQs. Each IRQ is assigned the argument handler and
* opaque data.
--
2.54.0
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [RFC 5/7] system: add qemu_irq_new / qemu_irq_new_child / qemu_irq_new_array
2026-06-16 15:55 ` [RFC 5/7] system: add qemu_irq_new / qemu_irq_new_child / qemu_irq_new_array Daniel P. Berrangé
@ 2026-06-16 16:22 ` Peter Maydell
2026-06-16 16:36 ` Daniel P. Berrangé
2026-06-17 10:45 ` Mark Cave-Ayland
0 siblings, 2 replies; 27+ messages in thread
From: Peter Maydell @ 2026-06-16 16:22 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: qemu-devel, Philippe Mathieu-Daudé, Pierrick Bouvier,
Peter Xu, Hervé Poussineau, Alex Bennée,
Michael S. Tsirkin, Akihiko Odaki, Aurelien Jarno, Fabiano Rosas,
Paolo Bonzini, BALATON Zoltan, Mark Cave-Ayland,
Marc-André Lureau
On Tue, 16 Jun 2026 at 16:57, Daniel P. Berrangé <berrange@redhat.com> wrote:
>
> Prepare for the move to dynamically allocated IRQ objects by
> introducing qemu_irq_new / qemu_irq_new_child / qemu_irq_new_array
> functions which call through to object_new instead of object_initialize.
>
> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
> ---
> hw/core/irq.c | 35 ++++++++++++++++++++
> include/hw/core/irq.h | 75 ++++++++++++++++++++++++++++++++++++++++---
> 2 files changed, 106 insertions(+), 4 deletions(-)
>
> diff --git a/hw/core/irq.c b/hw/core/irq.c
> index 106805e241..e943c87b81 100644
> --- a/hw/core/irq.c
> +++ b/hw/core/irq.c
> @@ -49,6 +49,13 @@ void qemu_init_irq(IRQState *irq, qemu_irq_handler handler, void *opaque,
> init_irq_fields(irq, handler, opaque, n);
> }
>
> +IRQState *qemu_irq_new(qemu_irq_handler handler, void *opaque, int n)
> +{
> + IRQState *irq = IRQ(object_new(TYPE_IRQ));
> + init_irq_fields(irq, handler, opaque, n);
> + return irq;
> +}
Isn't this the same as the existing qemu_allocate_irq() ?
(I have over the past few years occasionally been trying to get rid
of existing uses of qemu_allocate_irq() and its cousin
qemu_allocate_irqs(), because they are persistent sources of memory
leaks. The function returns a pointer that the caller has to deal
with and remember to free, whereas using e.g. qdev_init_gpio_*()
makes the new irq objects children of the device they belong to,
so they're automatically freed when the device is destroyed.
qemu_init_irq_child() similarly.)
-- PMM
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [RFC 5/7] system: add qemu_irq_new / qemu_irq_new_child / qemu_irq_new_array
2026-06-16 16:22 ` Peter Maydell
@ 2026-06-16 16:36 ` Daniel P. Berrangé
2026-06-17 10:46 ` Mark Cave-Ayland
2026-06-17 10:45 ` Mark Cave-Ayland
1 sibling, 1 reply; 27+ messages in thread
From: Daniel P. Berrangé @ 2026-06-16 16:36 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, Philippe Mathieu-Daudé, Pierrick Bouvier,
Peter Xu, Hervé Poussineau, Alex Bennée,
Michael S. Tsirkin, Akihiko Odaki, Aurelien Jarno, Fabiano Rosas,
Paolo Bonzini, BALATON Zoltan, Mark Cave-Ayland,
Marc-André Lureau
On Tue, Jun 16, 2026 at 05:22:05PM +0100, Peter Maydell wrote:
> On Tue, 16 Jun 2026 at 16:57, Daniel P. Berrangé <berrange@redhat.com> wrote:
> >
> > Prepare for the move to dynamically allocated IRQ objects by
> > introducing qemu_irq_new / qemu_irq_new_child / qemu_irq_new_array
> > functions which call through to object_new instead of object_initialize.
> >
> > Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
> > ---
> > hw/core/irq.c | 35 ++++++++++++++++++++
> > include/hw/core/irq.h | 75 ++++++++++++++++++++++++++++++++++++++++---
> > 2 files changed, 106 insertions(+), 4 deletions(-)
> >
> > diff --git a/hw/core/irq.c b/hw/core/irq.c
> > index 106805e241..e943c87b81 100644
> > --- a/hw/core/irq.c
> > +++ b/hw/core/irq.c
> > @@ -49,6 +49,13 @@ void qemu_init_irq(IRQState *irq, qemu_irq_handler handler, void *opaque,
> > init_irq_fields(irq, handler, opaque, n);
> > }
> >
> > +IRQState *qemu_irq_new(qemu_irq_handler handler, void *opaque, int n)
> > +{
> > + IRQState *irq = IRQ(object_new(TYPE_IRQ));
> > + init_irq_fields(irq, handler, opaque, n);
> > + return irq;
> > +}
>
> Isn't this the same as the existing qemu_allocate_irq() ?
Doh, I missed the very surprising naming pattern where "qemu_irq" is a
typedef of 'struct IRQState *'.
> (I have over the past few years occasionally been trying to get rid
> of existing uses of qemu_allocate_irq() and its cousin
> qemu_allocate_irqs(), because they are persistent sources of memory
> leaks. The function returns a pointer that the caller has to deal
> with and remember to free, whereas using e.g. qdev_init_gpio_*()
> makes the new irq objects children of the device they belong to,
> so they're automatically freed when the device is destroyed.
> qemu_init_irq_child() similarly.)
If we think it is best practice to mandate passing in a parent
object so that every IRQ is gauranteed to be owned by the QOM
tree, that's fine with me.
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [RFC 5/7] system: add qemu_irq_new / qemu_irq_new_child / qemu_irq_new_array
2026-06-16 16:36 ` Daniel P. Berrangé
@ 2026-06-17 10:46 ` Mark Cave-Ayland
0 siblings, 0 replies; 27+ messages in thread
From: Mark Cave-Ayland @ 2026-06-17 10:46 UTC (permalink / raw)
To: Daniel P. Berrangé, Peter Maydell
Cc: qemu-devel, Philippe Mathieu-Daudé, Pierrick Bouvier,
Peter Xu, Hervé Poussineau, Alex Bennée,
Michael S. Tsirkin, Akihiko Odaki, Aurelien Jarno, Fabiano Rosas,
Paolo Bonzini, BALATON Zoltan, Mark Cave-Ayland,
Marc-André Lureau
On 16/06/2026 17:36, Daniel P. Berrangé wrote:
>> Isn't this the same as the existing qemu_allocate_irq() ?
>
> Doh, I missed the very surprising naming pattern where "qemu_irq" is a
> typedef of 'struct IRQState *'.
>
>> (I have over the past few years occasionally been trying to get rid
>> of existing uses of qemu_allocate_irq() and its cousin
>> qemu_allocate_irqs(), because they are persistent sources of memory
>> leaks. The function returns a pointer that the caller has to deal
>> with and remember to free, whereas using e.g. qdev_init_gpio_*()
>> makes the new irq objects children of the device they belong to,
>> so they're automatically freed when the device is destroyed.
>> qemu_init_irq_child() similarly.)
>
> If we think it is best practice to mandate passing in a parent
> object so that every IRQ is gauranteed to be owned by the QOM
> tree, that's fine with me.
Yes, this feels like the right way forward to me.
ATB,
Mark.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC 5/7] system: add qemu_irq_new / qemu_irq_new_child / qemu_irq_new_array
2026-06-16 16:22 ` Peter Maydell
2026-06-16 16:36 ` Daniel P. Berrangé
@ 2026-06-17 10:45 ` Mark Cave-Ayland
1 sibling, 0 replies; 27+ messages in thread
From: Mark Cave-Ayland @ 2026-06-17 10:45 UTC (permalink / raw)
To: Peter Maydell, Daniel P. Berrangé
Cc: qemu-devel, Philippe Mathieu-Daudé, Pierrick Bouvier,
Peter Xu, Hervé Poussineau, Alex Bennée,
Michael S. Tsirkin, Akihiko Odaki, Aurelien Jarno, Fabiano Rosas,
Paolo Bonzini, BALATON Zoltan, Mark Cave-Ayland,
Marc-André Lureau
On 16/06/2026 17:22, Peter Maydell wrote:
> On Tue, 16 Jun 2026 at 16:57, Daniel P. Berrangé <berrange@redhat.com> wrote:
>>
>> Prepare for the move to dynamically allocated IRQ objects by
>> introducing qemu_irq_new / qemu_irq_new_child / qemu_irq_new_array
>> functions which call through to object_new instead of object_initialize.
>>
>> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
>> ---
>> hw/core/irq.c | 35 ++++++++++++++++++++
>> include/hw/core/irq.h | 75 ++++++++++++++++++++++++++++++++++++++++---
>> 2 files changed, 106 insertions(+), 4 deletions(-)
>>
>> diff --git a/hw/core/irq.c b/hw/core/irq.c
>> index 106805e241..e943c87b81 100644
>> --- a/hw/core/irq.c
>> +++ b/hw/core/irq.c
>> @@ -49,6 +49,13 @@ void qemu_init_irq(IRQState *irq, qemu_irq_handler handler, void *opaque,
>> init_irq_fields(irq, handler, opaque, n);
>> }
>>
>> +IRQState *qemu_irq_new(qemu_irq_handler handler, void *opaque, int n)
>> +{
>> + IRQState *irq = IRQ(object_new(TYPE_IRQ));
>> + init_irq_fields(irq, handler, opaque, n);
>> + return irq;
>> +}
>
> Isn't this the same as the existing qemu_allocate_irq() ?
>
> (I have over the past few years occasionally been trying to get rid
> of existing uses of qemu_allocate_irq() and its cousin
> qemu_allocate_irqs(), because they are persistent sources of memory
> leaks. The function returns a pointer that the caller has to deal
> with and remember to free, whereas using e.g. qdev_init_gpio_*()
> makes the new irq objects children of the device they belong to,
> so they're automatically freed when the device is destroyed.
> qemu_init_irq_child() similarly.)
Indeed, this is another case where we'd want to use
qemu_init_irq_child() since then it automatically gets cleaned up when
the refcount hits zero.
And your point about the similarity of qdev GPIOs is also valid: in
particular with Marc-André's recent work on property arrays, it feels
like we're getting closer to being able to converge everything IRQ and
GPIO-related into a single refcounted implementation.
ATB,
Mark.
^ permalink raw reply [flat|nested] 27+ messages in thread
* [RFC 6/7] hw/isa: convert PIIX embedded QOM objects to heap allocated
2026-06-16 15:55 [RFC 0/7] qom: deprecate embedded objects and instance properties Daniel P. Berrangé
` (4 preceding siblings ...)
2026-06-16 15:55 ` [RFC 5/7] system: add qemu_irq_new / qemu_irq_new_child / qemu_irq_new_array Daniel P. Berrangé
@ 2026-06-16 15:55 ` Daniel P. Berrangé
2026-06-16 15:55 ` [RFC 7/7] qom: improve error message for invalid ID values Daniel P. Berrangé
` (3 subsequent siblings)
9 siblings, 0 replies; 27+ messages in thread
From: Daniel P. Berrangé @ 2026-06-16 15:55 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Peter Xu,
Hervé Poussineau, Alex Bennée, Michael S. Tsirkin,
Akihiko Odaki, Daniel P. Berrangé, Aurelien Jarno,
Fabiano Rosas, Paolo Bonzini, BALATON Zoltan, Mark Cave-Ayland,
Marc-André Lureau
Update for the new preferred QOM design by removing embedded QOM
objects from the PIIXState struct for the RTC, IDE, UHCI, PM,
IRQ and memory region classes.
XXXX: there seems to be little benefit in having any of the
instance fields for RTC, IDE, UHCI, PM & IRQ objects. These
objects are all kept alive via the 'child' property which owns
the primary reference. The instance fields are accessed durnig
setup and then never again, so all these instances fields could
arguably go away entirely.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/isa/piix.c | 65 ++++++++++++++++++++++-------------
include/hw/southbridge/piix.h | 12 +++----
2 files changed, 47 insertions(+), 30 deletions(-)
diff --git a/hw/isa/piix.c b/hw/isa/piix.c
index 31fa53e6a4..cd23486ef9 100644
--- a/hw/isa/piix.c
+++ b/hw/isa/piix.c
@@ -308,18 +308,22 @@ static void pci_piix_realize(PCIDevice *dev, const char *uhci_type,
return;
}
- memory_region_init_io(&d->rcr_mem, OBJECT(dev), &rcr_ops, d,
- "piix-reset-control", 1);
+ d->rcr_mem = memory_region_new_io(OBJECT(dev), &rcr_ops, d,
+ "piix-reset-control", 1);
memory_region_add_subregion_overlap(pci_address_space_io(dev),
- PIIX_RCR_IOPORT, &d->rcr_mem, 1);
+ PIIX_RCR_IOPORT, d->rcr_mem, 1);
/* PIC */
if (d->has_pic) {
qemu_irq *i8259;
- qemu_init_irq_child(OBJECT(dev), "i8259-irq", &d->i8259_irq,
- piix_request_i8259_irq, d, 0);
- i8259 = i8259_init(isa_bus, &d->i8259_irq);
+ d->i8259_irq = qemu_irq_new_child(OBJECT(dev), "i8259-irq",
+ piix_request_i8259_irq, d, 0,
+ errp);
+ if (!d->i8259_irq) {
+ return;
+ }
+ i8259 = i8259_init(isa_bus, d->i8259_irq);
for (size_t i = 0; i < ISA_NUM_IRQS; i++) {
d->isa_irqs_in[i] = i8259[i];
@@ -340,38 +344,45 @@ static void pci_piix_realize(PCIDevice *dev, const char *uhci_type,
i8257_dma_init(OBJECT(dev), isa_bus, 0);
/* RTC */
- qdev_prop_set_int32(DEVICE(&d->rtc), "base_year", 2000);
- if (!qdev_realize(DEVICE(&d->rtc), BUS(isa_bus), errp)) {
+ qdev_prop_set_int32(DEVICE(d->rtc), "base_year", 2000);
+ if (!qdev_realize(DEVICE(d->rtc), BUS(isa_bus), errp)) {
return;
}
- irq = object_property_get_uint(OBJECT(&d->rtc), "irq", &error_fatal);
- isa_connect_gpio_out(ISA_DEVICE(&d->rtc), 0, irq);
+ irq = object_property_get_uint(OBJECT(d->rtc), "irq", &error_fatal);
+ isa_connect_gpio_out(ISA_DEVICE(d->rtc), 0, irq);
/* IDE */
- qdev_prop_set_int32(DEVICE(&d->ide), "addr", dev->devfn + 1);
- if (!qdev_realize(DEVICE(&d->ide), BUS(pci_bus), errp)) {
+ qdev_prop_set_int32(DEVICE(d->ide), "addr", dev->devfn + 1);
+ if (!qdev_realize(DEVICE(d->ide), BUS(pci_bus), errp)) {
return;
}
/* USB */
if (d->has_usb) {
- object_initialize_child(OBJECT(dev), "uhci", &d->uhci, uhci_type);
- qdev_prop_set_int32(DEVICE(&d->uhci), "addr", dev->devfn + 2);
- if (!qdev_realize(DEVICE(&d->uhci), BUS(pci_bus), errp)) {
+ d->uhci = UHCI(object_new_with_props(
+ uhci_type, OBJECT(d), "uhci", errp, NULL));
+ if (!d->uhci) {
+ return;
+ }
+ qdev_prop_set_int32(DEVICE(d->uhci), "addr", dev->devfn + 2);
+ if (!qdev_realize(DEVICE(d->uhci), BUS(pci_bus), errp)) {
return;
}
}
/* Power Management */
if (d->has_acpi) {
- object_initialize_child(OBJECT(d), "pm", &d->pm, TYPE_PIIX4_PM);
- qdev_prop_set_int32(DEVICE(&d->pm), "addr", dev->devfn + 3);
- qdev_prop_set_uint32(DEVICE(&d->pm), "smb_io_base", d->smb_io_base);
- qdev_prop_set_bit(DEVICE(&d->pm), "smm-enabled", d->smm_enabled);
- if (!qdev_realize(DEVICE(&d->pm), BUS(pci_bus), errp)) {
+ d->pm = PIIX4_PM(object_new_with_props(
+ TYPE_PIIX4_PM, OBJECT(d), "pm", errp, NULL));
+ if (!d->pm) {
+ }
+ qdev_prop_set_int32(DEVICE(d->pm), "addr", dev->devfn + 3);
+ qdev_prop_set_uint32(DEVICE(d->pm), "smb_io_base", d->smb_io_base);
+ qdev_prop_set_bit(DEVICE(d->pm), "smm-enabled", d->smm_enabled);
+ if (!qdev_realize(DEVICE(d->pm), BUS(pci_bus), errp)) {
return;
}
- qdev_connect_gpio_out(DEVICE(&d->pm), 0, d->isa_irqs_in[9]);
+ qdev_connect_gpio_out(DEVICE(d->pm), 0, d->isa_irqs_in[9]);
}
pci_bus_irqs(pci_bus, piix_set_pci_irq, d, PIIX_NUM_PIRQS);
@@ -406,7 +417,9 @@ static void pci_piix_init(Object *obj)
qdev_init_gpio_out_named(DEVICE(obj), d->isa_irqs_in, "isa-irqs",
ISA_NUM_IRQS);
- object_initialize_child(obj, "rtc", &d->rtc, TYPE_MC146818_RTC);
+ d->rtc = MC146818_RTC(
+ object_new_with_props(TYPE_MC146818_RTC, obj, "rtc",
+ &error_abort, NULL));
}
static const Property pci_piix_props[] = {
@@ -462,7 +475,9 @@ static void piix3_init(Object *obj)
{
PIIXState *d = PIIX_PCI_DEVICE(obj);
- object_initialize_child(obj, "ide", &d->ide, TYPE_PIIX3_IDE);
+ d->ide = PCI_IDE(
+ object_new_with_props(TYPE_PIIX3_IDE, obj, "ide",
+ &error_abort, NULL));
}
static void piix3_class_init(ObjectClass *klass, const void *data)
@@ -492,7 +507,9 @@ static void piix4_init(Object *obj)
{
PIIXState *s = PIIX_PCI_DEVICE(obj);
- object_initialize_child(obj, "ide", &s->ide, TYPE_PIIX4_IDE);
+ s->ide = PCI_IDE(
+ object_new_with_props(TYPE_PIIX4_IDE, obj, "ide",
+ &error_abort, NULL));
}
static void piix4_class_init(ObjectClass *klass, const void *data)
diff --git a/include/hw/southbridge/piix.h b/include/hw/southbridge/piix.h
index a296b1205a..8bd24946de 100644
--- a/include/hw/southbridge/piix.h
+++ b/include/hw/southbridge/piix.h
@@ -53,15 +53,15 @@ struct PIIXState {
qemu_irq cpu_intr;
qemu_irq isa_irqs_in[ISA_NUM_IRQS];
- IRQState i8259_irq;
+ IRQState *i8259_irq;
/* This member isn't used. Just for save/load compatibility */
int32_t pci_irq_levels_vmstate[PIIX_NUM_PIRQS];
- MC146818RtcState rtc;
- PCIIDEState ide;
- UHCIState uhci;
- PIIX4PMState pm;
+ MC146818RtcState *rtc;
+ PCIIDEState *ide;
+ UHCIState *uhci;
+ PIIX4PMState *pm;
uint32_t smb_io_base;
@@ -69,7 +69,7 @@ struct PIIXState {
uint8_t rcr;
/* IO memory region for Reset Control Register (PIIX_RCR_IOPORT) */
- MemoryRegion rcr_mem;
+ MemoryRegion *rcr_mem;
bool has_acpi;
bool has_pic;
--
2.54.0
^ permalink raw reply related [flat|nested] 27+ messages in thread* [RFC 7/7] qom: improve error message for invalid ID values
2026-06-16 15:55 [RFC 0/7] qom: deprecate embedded objects and instance properties Daniel P. Berrangé
` (5 preceding siblings ...)
2026-06-16 15:55 ` [RFC 6/7] hw/isa: convert PIIX embedded QOM objects to heap allocated Daniel P. Berrangé
@ 2026-06-16 15:55 ` Daniel P. Berrangé
2026-06-17 10:46 ` Markus Armbruster
2026-06-16 16:12 ` [RFC 0/7] qom: deprecate embedded objects and instance properties Peter Maydell
` (2 subsequent siblings)
9 siblings, 1 reply; 27+ messages in thread
From: Daniel P. Berrangé @ 2026-06-16 15:55 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Peter Xu,
Hervé Poussineau, Alex Bennée, Michael S. Tsirkin,
Akihiko Odaki, Daniel P. Berrangé, Aurelien Jarno,
Fabiano Rosas, Paolo Bonzini, BALATON Zoltan, Mark Cave-Ayland,
Marc-André Lureau
Include the actual ID that was validated, since this may not be
obvious in all contexts.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
qom/object.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/qom/object.c b/qom/object.c
index 415d5c5291..9cd17e3bcc 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -774,7 +774,7 @@ object_new_with_props_helper(const char *typename,
(id == NULL && parent == NULL));
if (id != NULL && !id_wellformed(id)) {
- error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "id", "an identifier");
+ error_setg(errp, "QOM ID value '%s' is not valid", id);
error_append_hint(errp, "Identifiers consist of letters, digits, "
"'-', '.', '_', starting with a letter.\n");
return NULL;
--
2.54.0
^ permalink raw reply related [flat|nested] 27+ messages in thread* Re: [RFC 7/7] qom: improve error message for invalid ID values
2026-06-16 15:55 ` [RFC 7/7] qom: improve error message for invalid ID values Daniel P. Berrangé
@ 2026-06-17 10:46 ` Markus Armbruster
2026-06-17 11:22 ` Daniel P. Berrangé
0 siblings, 1 reply; 27+ messages in thread
From: Markus Armbruster @ 2026-06-17 10:46 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: qemu-devel, Philippe Mathieu-Daudé, Pierrick Bouvier,
Peter Xu, Hervé Poussineau, Alex Bennée,
Michael S. Tsirkin, Akihiko Odaki, Aurelien Jarno, Fabiano Rosas,
Paolo Bonzini, BALATON Zoltan, Mark Cave-Ayland,
Marc-André Lureau
Daniel P. Berrangé <berrange@redhat.com> writes:
> Include the actual ID that was validated, since this may not be
> obvious in all contexts.
>
> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Reproducer?
I'm asking because:
$ qemu-system-x86_64 -object id=@
qemu-system-x86_64: -object id=@: Parameter 'id' expects an identifier
Identifiers consist of letters, digits, '-', '.', '_', starting with a letter.
This is qemu_opts_create().
And:
{"execute":"device_add","arguments":{"driver":"e1000", "id":"@"}}
{"error": {"class": "GenericError", "desc": "Invalid qdev ID '@'"}}
This is qdev_set_id().
Ah, found it:
$ qemu-system-x86_64 -object '{"id": "@", "qom-type": "iothread"}'
qemu-system-x86_64: QOM ID value '@' is not valid
Identifiers consist of letters, digits, '-', '.', '_', starting with a letter.
> ---
> qom/object.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/qom/object.c b/qom/object.c
> index 415d5c5291..9cd17e3bcc 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -774,7 +774,7 @@ object_new_with_props_helper(const char *typename,
> (id == NULL && parent == NULL));
>
> if (id != NULL && !id_wellformed(id)) {
> - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "id", "an identifier");
> + error_setg(errp, "QOM ID value '%s' is not valid", id);
> error_append_hint(errp, "Identifiers consist of letters, digits, "
> "'-', '.', '_', starting with a letter.\n");
> return NULL;
Improvement, but what about other places reporting an error when
id_wellformed() fails?
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [RFC 7/7] qom: improve error message for invalid ID values
2026-06-17 10:46 ` Markus Armbruster
@ 2026-06-17 11:22 ` Daniel P. Berrangé
0 siblings, 0 replies; 27+ messages in thread
From: Daniel P. Berrangé @ 2026-06-17 11:22 UTC (permalink / raw)
To: Markus Armbruster
Cc: qemu-devel, Philippe Mathieu-Daudé, Pierrick Bouvier,
Peter Xu, Hervé Poussineau, Alex Bennée,
Michael S. Tsirkin, Akihiko Odaki, Aurelien Jarno, Fabiano Rosas,
Paolo Bonzini, BALATON Zoltan, Mark Cave-Ayland,
Marc-André Lureau
On Wed, Jun 17, 2026 at 12:46:51PM +0200, Markus Armbruster wrote:
> Daniel P. Berrangé <berrange@redhat.com> writes:
>
> > Include the actual ID that was validated, since this may not be
> > obvious in all contexts.
> >
> > Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
>
> Reproducer?
>
> I'm asking because:
>
> $ qemu-system-x86_64 -object id=@
> qemu-system-x86_64: -object id=@: Parameter 'id' expects an identifier
> Identifiers consist of letters, digits, '-', '.', '_', starting with a letter.
>
> This is qemu_opts_create().
>
> And:
>
> {"execute":"device_add","arguments":{"driver":"e1000", "id":"@"}}
> {"error": {"class": "GenericError", "desc": "Invalid qdev ID '@'"}}
>
> This is qdev_set_id().
>
> Ah, found it:
>
> $ qemu-system-x86_64 -object '{"id": "@", "qom-type": "iothread"}'
> qemu-system-x86_64: QOM ID value '@' is not valid
> Identifiers consist of letters, digits, '-', '.', '_', starting with a letter.
Actually in this case it wasn't anything user controlled,
I was calling object_new_with_props internally to create
child objects and it tripped over this due to a bug of
my own making. It was just rather confusing as to what I
had done wrong
>
> > ---
> > qom/object.c | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/qom/object.c b/qom/object.c
> > index 415d5c5291..9cd17e3bcc 100644
> > --- a/qom/object.c
> > +++ b/qom/object.c
> > @@ -774,7 +774,7 @@ object_new_with_props_helper(const char *typename,
> > (id == NULL && parent == NULL));
> >
> > if (id != NULL && !id_wellformed(id)) {
> > - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "id", "an identifier");
> > + error_setg(errp, "QOM ID value '%s' is not valid", id);
> > error_append_hint(errp, "Identifiers consist of letters, digits, "
> > "'-', '.', '_', starting with a letter.\n");
> > return NULL;
>
> Improvement, but what about other places reporting an error when
> id_wellformed() fails?
>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC 0/7] qom: deprecate embedded objects and instance properties
2026-06-16 15:55 [RFC 0/7] qom: deprecate embedded objects and instance properties Daniel P. Berrangé
` (6 preceding siblings ...)
2026-06-16 15:55 ` [RFC 7/7] qom: improve error message for invalid ID values Daniel P. Berrangé
@ 2026-06-16 16:12 ` Peter Maydell
2026-06-16 16:40 ` Daniel P. Berrangé
2026-06-17 10:39 ` Mark Cave-Ayland
2026-06-17 10:31 ` Mark Cave-Ayland
2026-06-17 10:59 ` Markus Armbruster
9 siblings, 2 replies; 27+ messages in thread
From: Peter Maydell @ 2026-06-16 16:12 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: qemu-devel, Philippe Mathieu-Daudé, Pierrick Bouvier,
Peter Xu, Hervé Poussineau, Alex Bennée,
Michael S. Tsirkin, Akihiko Odaki, Aurelien Jarno, Fabiano Rosas,
Paolo Bonzini, BALATON Zoltan, Mark Cave-Ayland,
Marc-André Lureau
On Tue, 16 Jun 2026 at 16:56, Daniel P. Berrangé <berrange@redhat.com> wrote:
>
> QOM has two rather unusual / surprising features historicall
>
> * The ability to embed a QOM instance's memory inside another
> struct
> * The ability to register properties against the instnce
> instead of struct
>
> While they both look convenient on the surface, they also
> have significant undesirable side effects (see the commit
> message for each patch for details).
>
> The premise of this series is that their convenience does
> not outweigh their downsides, and we would be better off
> long term by eliminating their usage, rather than trying
> to add more hacks on top to mitigate their downsides.
The thing I would like to see before we mark object_initialize_child
and friends as deprecated is clear documentation of "this is how
we would like you to write 'container/SoC' style devices, here is
an device written to the approved style you can look at".
Currently we have in the codebase a pretty wide range of
different ways to write devices:
- really ancient, not QOM/qdev at all
- qdev style (lots of Device* pointers)
- embedded-struct style
and I'm not sure if this would be adding a fourth style, or
rolling back to qdev style.
(Borrowing a paragraph I wrote last time this came up:)
I'm not opposed to the idea of making a design decision that this
struct-embedding is no longer what we want to do, and defining
that something else is our new best practice for how to write devices.
But I think we would need to start by reaching a consensus that that
*is* what we want to do, and documenting that "best practice" somewhere
in docs/devel/. Then we can all be on the same page about the design
patterns we want and it will be clearer to reviewers whether new
code and new APIs and conversions of old code fit into those
patterns or not.
I think we're getting closer on the "consensus" part but
the "document the new best practice" part is important I think.
thanks
-- PMM
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [RFC 0/7] qom: deprecate embedded objects and instance properties
2026-06-16 16:12 ` [RFC 0/7] qom: deprecate embedded objects and instance properties Peter Maydell
@ 2026-06-16 16:40 ` Daniel P. Berrangé
2026-06-17 10:53 ` Mark Cave-Ayland
2026-06-17 10:39 ` Mark Cave-Ayland
1 sibling, 1 reply; 27+ messages in thread
From: Daniel P. Berrangé @ 2026-06-16 16:40 UTC (permalink / raw)
To: Peter Maydell
Cc: qemu-devel, Philippe Mathieu-Daudé, Pierrick Bouvier,
Peter Xu, Hervé Poussineau, Alex Bennée,
Michael S. Tsirkin, Akihiko Odaki, Aurelien Jarno, Fabiano Rosas,
Paolo Bonzini, BALATON Zoltan, Mark Cave-Ayland,
Marc-André Lureau
On Tue, Jun 16, 2026 at 05:12:27PM +0100, Peter Maydell wrote:
> On Tue, 16 Jun 2026 at 16:56, Daniel P. Berrangé <berrange@redhat.com> wrote:
> >
> > QOM has two rather unusual / surprising features historicall
> >
> > * The ability to embed a QOM instance's memory inside another
> > struct
> > * The ability to register properties against the instnce
> > instead of struct
> >
> > While they both look convenient on the surface, they also
> > have significant undesirable side effects (see the commit
> > message for each patch for details).
> >
> > The premise of this series is that their convenience does
> > not outweigh their downsides, and we would be better off
> > long term by eliminating their usage, rather than trying
> > to add more hacks on top to mitigate their downsides.
>
> The thing I would like to see before we mark object_initialize_child
> and friends as deprecated is clear documentation of "this is how
> we would like you to write 'container/SoC' style devices, here is
> an device written to the approved style you can look at".
Do we have any documentation currently that touches on
this area that we can start from / adapt to best
practices ? I can do adaptation, but I'm not an expert
on Device code, so probably not best placed to write a
new doc fro mscratch.
> Currently we have in the codebase a pretty wide range of
> different ways to write devices:
> - really ancient, not QOM/qdev at all
> - qdev style (lots of Device* pointers)
> - embedded-struct style
> and I'm not sure if this would be adding a fourth style, or
> rolling back to qdev style.
Per my commit message in the PIIX patch, I'm not convinced
we need to store any device pointers in the instance
structs at all in many (possibly most) cases. The instance
struct fields are mostly only referenced during creation
time and then never again, with the QOM 'child' property
holding the permanent reference.
> I'm not opposed to the idea of making a design decision that this
> struct-embedding is no longer what we want to do, and defining
> that something else is our new best practice for how to write devices.
> But I think we would need to start by reaching a consensus that that
> *is* what we want to do, and documenting that "best practice" somewhere
> in docs/devel/. Then we can all be on the same page about the design
> patterns we want and it will be clearer to reviewers whether new
> code and new APIs and conversions of old code fit into those
> patterns or not.
>
> I think we're getting closer on the "consensus" part but
> the "document the new best practice" part is important I think.
Yep, best practice docs must be a key part of the story.
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC 0/7] qom: deprecate embedded objects and instance properties
2026-06-16 16:40 ` Daniel P. Berrangé
@ 2026-06-17 10:53 ` Mark Cave-Ayland
0 siblings, 0 replies; 27+ messages in thread
From: Mark Cave-Ayland @ 2026-06-17 10:53 UTC (permalink / raw)
To: Daniel P. Berrangé, Peter Maydell
Cc: qemu-devel, Philippe Mathieu-Daudé, Pierrick Bouvier,
Peter Xu, Hervé Poussineau, Alex Bennée,
Michael S. Tsirkin, Akihiko Odaki, Aurelien Jarno, Fabiano Rosas,
Paolo Bonzini, BALATON Zoltan, Mark Cave-Ayland,
Marc-André Lureau
On 16/06/2026 17:40, Daniel P. Berrangé wrote:
> On Tue, Jun 16, 2026 at 05:12:27PM +0100, Peter Maydell wrote:
>> On Tue, 16 Jun 2026 at 16:56, Daniel P. Berrangé <berrange@redhat.com> wrote:
>>>
>>> QOM has two rather unusual / surprising features historicall
>>>
>>> * The ability to embed a QOM instance's memory inside another
>>> struct
>>> * The ability to register properties against the instnce
>>> instead of struct
>>>
>>> While they both look convenient on the surface, they also
>>> have significant undesirable side effects (see the commit
>>> message for each patch for details).
>>>
>>> The premise of this series is that their convenience does
>>> not outweigh their downsides, and we would be better off
>>> long term by eliminating their usage, rather than trying
>>> to add more hacks on top to mitigate their downsides.
>>
>> The thing I would like to see before we mark object_initialize_child
>> and friends as deprecated is clear documentation of "this is how
>> we would like you to write 'container/SoC' style devices, here is
>> an device written to the approved style you can look at".
>
> Do we have any documentation currently that touches on
> this area that we can start from / adapt to best
> practices ? I can do adaptation, but I'm not an expert
> on Device code, so probably not best placed to write a
> new doc fro mscratch.
>
>> Currently we have in the codebase a pretty wide range of
>> different ways to write devices:
>> - really ancient, not QOM/qdev at all
>> - qdev style (lots of Device* pointers)
>> - embedded-struct style
>> and I'm not sure if this would be adding a fourth style, or
>> rolling back to qdev style.
>
> Per my commit message in the PIIX patch, I'm not convinced
> we need to store any device pointers in the instance
> structs at all in many (possibly most) cases. The instance
> struct fields are mostly only referenced during creation
> time and then never again, with the QOM 'child' property
> holding the permanent reference.
I think it depends: we do already have hot paths where people use a
direct pointer reference instead of an object property lookup, but these
cases are generally in the minority. And there's no reason why for those
cases the pointer couldn't be cached within the device state during
device realize or similar, along with a suitable comment of course.
The other case in which I've found device pointers in the device state
useful is during low-level debugging sessions i.e. where state is
corrupted enough that calling object functions in gdb may fail.
>> I'm not opposed to the idea of making a design decision that this
>> struct-embedding is no longer what we want to do, and defining
>> that something else is our new best practice for how to write devices.
>> But I think we would need to start by reaching a consensus that that
>> *is* what we want to do, and documenting that "best practice" somewhere
>> in docs/devel/. Then we can all be on the same page about the design
>> patterns we want and it will be clearer to reviewers whether new
>> code and new APIs and conversions of old code fit into those
>> patterns or not.
>>
>> I think we're getting closer on the "consensus" part but
>> the "document the new best practice" part is important I think.
>
> Yep, best practice docs must be a key part of the story.
ATB,
Mark.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC 0/7] qom: deprecate embedded objects and instance properties
2026-06-16 16:12 ` [RFC 0/7] qom: deprecate embedded objects and instance properties Peter Maydell
2026-06-16 16:40 ` Daniel P. Berrangé
@ 2026-06-17 10:39 ` Mark Cave-Ayland
2026-06-17 11:00 ` Daniel P. Berrangé
1 sibling, 1 reply; 27+ messages in thread
From: Mark Cave-Ayland @ 2026-06-17 10:39 UTC (permalink / raw)
To: Peter Maydell, Daniel P. Berrangé
Cc: qemu-devel, Philippe Mathieu-Daudé, Pierrick Bouvier,
Peter Xu, Hervé Poussineau, Alex Bennée,
Michael S. Tsirkin, Akihiko Odaki, Aurelien Jarno, Fabiano Rosas,
Paolo Bonzini, BALATON Zoltan, Mark Cave-Ayland,
Marc-André Lureau
On 16/06/2026 17:12, Peter Maydell wrote:
> On Tue, 16 Jun 2026 at 16:56, Daniel P. Berrangé <berrange@redhat.com> wrote:
>>
>> QOM has two rather unusual / surprising features historicall
>>
>> * The ability to embed a QOM instance's memory inside another
>> struct
>> * The ability to register properties against the instnce
>> instead of struct
>>
>> While they both look convenient on the surface, they also
>> have significant undesirable side effects (see the commit
>> message for each patch for details).
>>
>> The premise of this series is that their convenience does
>> not outweigh their downsides, and we would be better off
>> long term by eliminating their usage, rather than trying
>> to add more hacks on top to mitigate their downsides.
>
> The thing I would like to see before we mark object_initialize_child
> and friends as deprecated is clear documentation of "this is how
> we would like you to write 'container/SoC' style devices, here is
> an device written to the approved style you can look at".
>
> Currently we have in the codebase a pretty wide range of
> different ways to write devices:
> - really ancient, not QOM/qdev at all
> - qdev style (lots of Device* pointers)
> - embedded-struct style
> and I'm not sure if this would be adding a fourth style, or
> rolling back to qdev style.
>
> (Borrowing a paragraph I wrote last time this came up:)
>
> I'm not opposed to the idea of making a design decision that this
> struct-embedding is no longer what we want to do, and defining
> that something else is our new best practice for how to write devices.
> But I think we would need to start by reaching a consensus that that
> *is* what we want to do, and documenting that "best practice" somewhere
> in docs/devel/. Then we can all be on the same page about the design
> patterns we want and it will be clearer to reviewers whether new
> code and new APIs and conversions of old code fit into those
> patterns or not.
>
> I think we're getting closer on the "consensus" part but
> the "document the new best practice" part is important I think.
Agreed. The only issue I can see here is that often documentation isn't
good enough: as an example, we've standardised on using "parent_obj" as
the field name for several years now, but we still get patches using
different names because developers struggle to find the documentation,
and reviewers aren't often aware of changes in how we model devices etc.
Based on this experience, I think the only way we can realistically do
this is to teach checkpatch.pl about it so that using functions such as
object_initialize_child(), object_property_add() etc. will cause CI failure.
I'd love to be able to teach it about "parent_obj" and not to embed
objects that aren't pointers, but I don't know if that's possible?
ATB,
Mark.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC 0/7] qom: deprecate embedded objects and instance properties
2026-06-17 10:39 ` Mark Cave-Ayland
@ 2026-06-17 11:00 ` Daniel P. Berrangé
0 siblings, 0 replies; 27+ messages in thread
From: Daniel P. Berrangé @ 2026-06-17 11:00 UTC (permalink / raw)
To: Mark Cave-Ayland
Cc: Peter Maydell, qemu-devel, Philippe Mathieu-Daudé,
Pierrick Bouvier, Peter Xu, Hervé Poussineau,
Alex Bennée, Michael S. Tsirkin, Akihiko Odaki,
Aurelien Jarno, Fabiano Rosas, Paolo Bonzini, BALATON Zoltan,
Mark Cave-Ayland, Marc-André Lureau
On Wed, Jun 17, 2026 at 11:39:57AM +0100, Mark Cave-Ayland wrote:
> On 16/06/2026 17:12, Peter Maydell wrote:
>
> > On Tue, 16 Jun 2026 at 16:56, Daniel P. Berrangé <berrange@redhat.com> wrote:
> > >
> > > QOM has two rather unusual / surprising features historicall
> > >
> > > * The ability to embed a QOM instance's memory inside another
> > > struct
> > > * The ability to register properties against the instnce
> > > instead of struct
> > >
> > > While they both look convenient on the surface, they also
> > > have significant undesirable side effects (see the commit
> > > message for each patch for details).
> > >
> > > The premise of this series is that their convenience does
> > > not outweigh their downsides, and we would be better off
> > > long term by eliminating their usage, rather than trying
> > > to add more hacks on top to mitigate their downsides.
> >
> > The thing I would like to see before we mark object_initialize_child
> > and friends as deprecated is clear documentation of "this is how
> > we would like you to write 'container/SoC' style devices, here is
> > an device written to the approved style you can look at".
> >
> > Currently we have in the codebase a pretty wide range of
> > different ways to write devices:
> > - really ancient, not QOM/qdev at all
> > - qdev style (lots of Device* pointers)
> > - embedded-struct style
> > and I'm not sure if this would be adding a fourth style, or
> > rolling back to qdev style.
> >
> > (Borrowing a paragraph I wrote last time this came up:)
> >
> > I'm not opposed to the idea of making a design decision that this
> > struct-embedding is no longer what we want to do, and defining
> > that something else is our new best practice for how to write devices.
> > But I think we would need to start by reaching a consensus that that
> > *is* what we want to do, and documenting that "best practice" somewhere
> > in docs/devel/. Then we can all be on the same page about the design
> > patterns we want and it will be clearer to reviewers whether new
> > code and new APIs and conversions of old code fit into those
> > patterns or not.
> >
> > I think we're getting closer on the "consensus" part but
> > the "document the new best practice" part is important I think.
>
> Agreed. The only issue I can see here is that often documentation isn't good
> enough: as an example, we've standardised on using "parent_obj" as the field
> name for several years now, but we still get patches using different names
> because developers struggle to find the documentation, and reviewers aren't
> often aware of changes in how we model devices etc.
>
> Based on this experience, I think the only way we can realistically do this
> is to teach checkpatch.pl about it so that using functions such as
> object_initialize_child(), object_property_add() etc. will cause CI failure.
>
> I'd love to be able to teach it about "parent_obj" and not to embed objects
> that aren't pointers, but I don't know if that's possible?
For embedding we can teach checkpatch to whine about any use of
object_initialize() in new code easily enough which catches most
cases.
For 'parent_obj' I thought about a macro assert:
$ git diff
diff --git a/include/qom/object.h b/include/qom/object.h
index e9ce15d595..00d9424e3d 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -283,6 +283,7 @@ struct Object
module_obj_name##_class_init(ObjectClass *oc, const void *data); \
static void \
module_obj_name##_init(Object *obj); \
+ G_STATIC_ASSERT(offsetof(ModuleObjName, parent_obj) == 0); \
\
static const TypeInfo module_obj_name##_info = { \
.parent = TYPE_##PARENT_MODULE_OBJ_NAME, \
Unfortunately only a small number use OBJECT_DEFINE_TYPE macros,
most use DEFINE_TYPES which does not have access to the struct
names :-( Still that does show a few violators of the current
rule.
I also tried the same assert in OBJECT_DECLARE_TYPE which would
catch all usage, but that falls over when the header pre-declares
the struct name, and the source file has its actual definition.
We don't want to force the struct definition into the header
so I'm out of options for build-time checks there :-(
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [RFC 0/7] qom: deprecate embedded objects and instance properties
2026-06-16 15:55 [RFC 0/7] qom: deprecate embedded objects and instance properties Daniel P. Berrangé
` (7 preceding siblings ...)
2026-06-16 16:12 ` [RFC 0/7] qom: deprecate embedded objects and instance properties Peter Maydell
@ 2026-06-17 10:31 ` Mark Cave-Ayland
2026-06-17 13:59 ` BALATON Zoltan
2026-06-17 10:59 ` Markus Armbruster
9 siblings, 1 reply; 27+ messages in thread
From: Mark Cave-Ayland @ 2026-06-17 10:31 UTC (permalink / raw)
To: Daniel P. Berrangé, qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Peter Xu,
Hervé Poussineau, Alex Bennée, Michael S. Tsirkin,
Akihiko Odaki, Aurelien Jarno, Fabiano Rosas, Paolo Bonzini,
BALATON Zoltan, Mark Cave-Ayland, Marc-André Lureau
On 16/06/2026 16:55, Daniel P. Berrangé wrote:
> QOM has two rather unusual / surprising features historicall
>
> * The ability to embed a QOM instance's memory inside another
> struct
> * The ability to register properties against the instnce
> instead of struct
>
> While they both look convenient on the surface, they also
> have significant undesirable side effects (see the commit
> message for each patch for details).
>
> The premise of this series is that their convenience does
> not outweigh their downsides, and we would be better off
> long term by eliminating their usage, rather than trying
> to add more hacks on top to mitigate their downsides.
>
> This comes out of two separate conversations this week
>
> * Migration series where Peter proposed changes that
> make use of instance properties. When I commented,
> Peter rightly pointed out that our docs do not
> discourage use of instance properties:
>
> https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.gnu.org_archive_html_qemu-2Ddevel_2026-2D06_msg02368.html&d=DwIDaQ&c=s883GpUCOChKOHiocYtGcg&r=c23RpsaH4D2MKyD3EPJTDa0BAxz6tV8aUJqVSoytEiY&m=VzbegkrZ5TGWl9jpxLUfD3gMp4ZZjyUrMiBfOzSjpcaOU-hz3SuUIaGUiIM4BQdV&s=v-N9FJZ1ugUjERquAp1KfuZ3B20G9mdbHpEEFP5zkfs&e=
>
> * QOM series where Akihiko proposed some funky hacks
> to reference counting to better track object lifecycle
> when embedding structs. We had a short discussion about
> discouraging QOM embedding, so this is a real world
> proposal:
>
> https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.gnu.org_archive_html_qemu-2Ddevel_2026-2D06_msg03459.html&d=DwIDaQ&c=s883GpUCOChKOHiocYtGcg&r=c23RpsaH4D2MKyD3EPJTDa0BAxz6tV8aUJqVSoytEiY&m=VzbegkrZ5TGWl9jpxLUfD3gMp4ZZjyUrMiBfOzSjpcaOU-hz3SuUIaGUiIM4BQdV&s=mHTDgFeywt1U_2Q9uTnAyG6zp-VjguJ4DZIJAX59vaY&e=
>
> This is not likely to be a quick task, so this series
> starts small
>
> * Adds a "QEMU_DEPRECATIONS" annotation for internal APIs
> * Deprecate the QOM instance embedding
> * Deprecate the QOM instance properties
> * Deprecate the memory region embedding APIs
> * Deprecate the IRQ embedding APIs
> * Convert PIIX to eliminate embedding as a
> demonstration.
>
> The QEMU_DEPRECATIONS idea is an effect to improve our our
> historic practice where we introduce a new preferred API
> and never really tell anyone the old APIs is bad to use.
>
> If --enable-deprecations is given to configure, every use
> of a deprecated API emits a compiler warning. This is not
> enabled by default in this series, since we have -Werror
> by default.
I'm not sure if we're ready to start flagging things via the compiler,
however I'm in broad agreement that this is direction we need to travel.
Thanks for beating me to it, and starting the conversation :)
> Note that the proposal to stop embedding memory regions has
> been made by Zoltan earlier this year and was rejected by Paolo:
>
> https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.nongnu.org_archive_html_qemu-2Ddevel_2026-2D01_msg05435.html&d=DwIDaQ&c=s883GpUCOChKOHiocYtGcg&r=c23RpsaH4D2MKyD3EPJTDa0BAxz6tV8aUJqVSoytEiY&m=VzbegkrZ5TGWl9jpxLUfD3gMp4ZZjyUrMiBfOzSjpcaOU-hz3SuUIaGUiIM4BQdV&s=oAY3a1R4rnhYdl7-qnoTVjVdGOX1Qj-GvGlOX77oZrk&e=
> https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.nongnu.org_archive_html_qemu-2Ddevel_2026-2D05_msg06665.html&d=DwIDaQ&c=s883GpUCOChKOHiocYtGcg&r=c23RpsaH4D2MKyD3EPJTDa0BAxz6tV8aUJqVSoytEiY&m=VzbegkrZ5TGWl9jpxLUfD3gMp4ZZjyUrMiBfOzSjpcaOU-hz3SuUIaGUiIM4BQdV&s=WmpukrnrmuhhTz7hLgAA-9FStZ3fbzH3P1aT_U9f6GY&e=
>
> I don't really agree with the analysis there. IMHO, the
> concept of embedding objects is to horrendous to allow to
> live any longer. Yes, that's a big job, but long term it
> is worth it.
FWIW my main objection to the series was that it added yet another way
of doing something to fix a particular issue in legacy code. I have a
suspicion that if we can make everything in QOM properly refcounted then
this approach could work globally: in particular I can see it would fix
issues where the flatviews hold references to memory regions outside of
the device lifecycle until the RCU thread tidies up.
However as you can see, there would be quite a bit of work to get there.
But at least if we can all agree on the way forward, we can start to get
the relevant changes in place.
> Daniel P. Berrangé (7):
> meson: add --enable-deprecations configure flag
> qom: deprecated embedding object structs within other objects
> qom: deprecate use of instance properties
> system: add memory_region_new / memory_region_new_io
> system: add qemu_irq_new / qemu_irq_new_child / qemu_irq_new_array
> hw/isa: convert PIIX embedded QOM objects to heap allocated
> qom: improve error message for invalid ID values
>
> hw/core/irq.c | 35 +++++++++++++
> hw/isa/piix.c | 65 ++++++++++++++---------
> include/hw/core/irq.h | 75 +++++++++++++++++++++++++--
> include/hw/southbridge/piix.h | 12 ++---
> include/qemu/osdep.h | 19 +++++++
> include/qom/object.h | 98 ++++++++++++++++++++++++++++++-----
> include/system/memory.h | 76 +++++++++++++++++++++++----
> meson.build | 1 +
> meson_options.txt | 2 +
> qom/object.c | 36 ++++++++++++-
> scripts/meson-buildoptions.sh | 3 ++
> system/memory.c | 85 +++++++++++++++++++++++++-----
> 12 files changed, 433 insertions(+), 74 deletions(-)
ATB,
Mark.
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [RFC 0/7] qom: deprecate embedded objects and instance properties
2026-06-17 10:31 ` Mark Cave-Ayland
@ 2026-06-17 13:59 ` BALATON Zoltan
0 siblings, 0 replies; 27+ messages in thread
From: BALATON Zoltan @ 2026-06-17 13:59 UTC (permalink / raw)
To: Mark Cave-Ayland
Cc: Daniel P. Berrangé, qemu-devel, Philippe Mathieu-Daudé,
Pierrick Bouvier, Peter Xu, Hervé Poussineau,
Alex Bennée, Michael S. Tsirkin, Akihiko Odaki,
Aurelien Jarno, Fabiano Rosas, Paolo Bonzini, Mark Cave-Ayland,
Marc-André Lureau
[-- Attachment #1: Type: text/plain, Size: 5818 bytes --]
On Wed, 17 Jun 2026, Mark Cave-Ayland wrote:
> On 16/06/2026 16:55, Daniel P. Berrangé wrote:
>
>> QOM has two rather unusual / surprising features historicall
>>
>> * The ability to embed a QOM instance's memory inside another
>> struct
>> * The ability to register properties against the instnce
>> instead of struct
>>
>> While they both look convenient on the surface, they also
>> have significant undesirable side effects (see the commit
>> message for each patch for details).
>>
>> The premise of this series is that their convenience does
>> not outweigh their downsides, and we would be better off
>> long term by eliminating their usage, rather than trying
>> to add more hacks on top to mitigate their downsides.
>>
>> This comes out of two separate conversations this week
>>
>> * Migration series where Peter proposed changes that
>> make use of instance properties. When I commented,
>> Peter rightly pointed out that our docs do not
>> discourage use of instance properties:
>> https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.gnu.org_archive_html_qemu-2Ddevel_2026-2D06_msg02368.html&d=DwIDaQ&c=s883GpUCOChKOHiocYtGcg&r=c23RpsaH4D2MKyD3EPJTDa0BAxz6tV8aUJqVSoytEiY&m=VzbegkrZ5TGWl9jpxLUfD3gMp4ZZjyUrMiBfOzSjpcaOU-hz3SuUIaGUiIM4BQdV&s=v-N9FJZ1ugUjERquAp1KfuZ3B20G9mdbHpEEFP5zkfs&e=
>>
>> * QOM series where Akihiko proposed some funky hacks
>> to reference counting to better track object lifecycle
>> when embedding structs. We had a short discussion about
>> discouraging QOM embedding, so this is a real world
>> proposal:
>>
>> https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.gnu.org_archive_html_qemu-2Ddevel_2026-2D06_msg03459.html&d=DwIDaQ&c=s883GpUCOChKOHiocYtGcg&r=c23RpsaH4D2MKyD3EPJTDa0BAxz6tV8aUJqVSoytEiY&m=VzbegkrZ5TGWl9jpxLUfD3gMp4ZZjyUrMiBfOzSjpcaOU-hz3SuUIaGUiIM4BQdV&s=mHTDgFeywt1U_2Q9uTnAyG6zp-VjguJ4DZIJAX59vaY&e=
>>
>> This is not likely to be a quick task, so this series
>> starts small
>>
>> * Adds a "QEMU_DEPRECATIONS" annotation for internal APIs
>> * Deprecate the QOM instance embedding
>> * Deprecate the QOM instance properties
>> * Deprecate the memory region embedding APIs
>> * Deprecate the IRQ embedding APIs
>> * Convert PIIX to eliminate embedding as a
>> demonstration.
>>
>> The QEMU_DEPRECATIONS idea is an effect to improve our our
>> historic practice where we introduce a new preferred API
>> and never really tell anyone the old APIs is bad to use.
>>
>> If --enable-deprecations is given to configure, every use
>> of a deprecated API emits a compiler warning. This is not
>> enabled by default in this series, since we have -Werror
>> by default.
>
> I'm not sure if we're ready to start flagging things via the compiler,
> however I'm in broad agreement that this is direction we need to travel.
> Thanks for beating me to it, and starting the conversation :)
>
>> Note that the proposal to stop embedding memory regions has
>> been made by Zoltan earlier this year and was rejected by Paolo:
>>
>> https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.nongnu.org_archive_html_qemu-2Ddevel_2026-2D01_msg05435.html&d=DwIDaQ&c=s883GpUCOChKOHiocYtGcg&r=c23RpsaH4D2MKyD3EPJTDa0BAxz6tV8aUJqVSoytEiY&m=VzbegkrZ5TGWl9jpxLUfD3gMp4ZZjyUrMiBfOzSjpcaOU-hz3SuUIaGUiIM4BQdV&s=oAY3a1R4rnhYdl7-qnoTVjVdGOX1Qj-GvGlOX77oZrk&e=
>> https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.nongnu.org_archive_html_qemu-2Ddevel_2026-2D05_msg06665.html&d=DwIDaQ&c=s883GpUCOChKOHiocYtGcg&r=c23RpsaH4D2MKyD3EPJTDa0BAxz6tV8aUJqVSoytEiY&m=VzbegkrZ5TGWl9jpxLUfD3gMp4ZZjyUrMiBfOzSjpcaOU-hz3SuUIaGUiIM4BQdV&s=WmpukrnrmuhhTz7hLgAA-9FStZ3fbzH3P1aT_U9f6GY&e=
>>
>> I don't really agree with the analysis there. IMHO, the
>> concept of embedding objects is to horrendous to allow to
>> live any longer. Yes, that's a big job, but long term it
>> is worth it.
>
> FWIW my main objection to the series was that it added yet another way of
> doing something to fix a particular issue in legacy code. I have a suspicion
> that if we can make everything in QOM properly refcounted then this approach
> could work globally: in particular I can see it would fix issues where the
> flatviews hold references to memory regions outside of the device lifecycle
> until the RCU thread tidies up.
>
> However as you can see, there would be quite a bit of work to get there. But
> at least if we can all agree on the way forward, we can start to get the
> relevant changes in place.
We can't convert the whole code base at once and it's unrealistic to
expect a single contributor like me to do that to accept my patch. What I
proposed is a start that can be used now for the cases I have and can
serve as a basis for future conversions. I did not propose to convert
everything either because I think having both ref counted and externally
managed memory regions can be useful in different cases and I don't see
having two ways for this confusing considering we have object_new and
object_initialize for same reasons. But if we deprecate object_initialize
then the memory_region_init functions are not needed either.
Originally I also thought about splitting alloc and init similar to how
macOS Foundation does it (i.e. [[obj alloc] init]) so the allocation of
the memory region could be done by either object_new or embedded but that
does not work due to object_new setting free function and
object_initialize clearing it so you can only use either one or the other.
Therefore since memory_region_init calls object_initialize we need a
memory_region_new variant that uses object_new instead or we end up
having to convert the whole code base again to decouple object
initialization from memory_region_init so I did not go that way.
Regards,
BALATON Zoltan
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [RFC 0/7] qom: deprecate embedded objects and instance properties
2026-06-16 15:55 [RFC 0/7] qom: deprecate embedded objects and instance properties Daniel P. Berrangé
` (8 preceding siblings ...)
2026-06-17 10:31 ` Mark Cave-Ayland
@ 2026-06-17 10:59 ` Markus Armbruster
2026-06-17 11:05 ` Daniel P. Berrangé
9 siblings, 1 reply; 27+ messages in thread
From: Markus Armbruster @ 2026-06-17 10:59 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: qemu-devel, Philippe Mathieu-Daudé, Pierrick Bouvier,
Peter Xu, Hervé Poussineau, Alex Bennée,
Michael S. Tsirkin, Akihiko Odaki, Aurelien Jarno, Fabiano Rosas,
Paolo Bonzini, BALATON Zoltan, Mark Cave-Ayland,
Marc-André Lureau
Daniel P. Berrangé <berrange@redhat.com> writes:
> QOM has two rather unusual / surprising features historicall
>
> * The ability to embed a QOM instance's memory inside another
> struct
> * The ability to register properties against the instnce
> instead of struct
I figure you mean "against the instance instead of the class".
[...]
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [RFC 0/7] qom: deprecate embedded objects and instance properties
2026-06-17 10:59 ` Markus Armbruster
@ 2026-06-17 11:05 ` Daniel P. Berrangé
0 siblings, 0 replies; 27+ messages in thread
From: Daniel P. Berrangé @ 2026-06-17 11:05 UTC (permalink / raw)
To: Markus Armbruster
Cc: qemu-devel, Philippe Mathieu-Daudé, Pierrick Bouvier,
Peter Xu, Hervé Poussineau, Alex Bennée,
Michael S. Tsirkin, Akihiko Odaki, Aurelien Jarno, Fabiano Rosas,
Paolo Bonzini, BALATON Zoltan, Mark Cave-Ayland,
Marc-André Lureau
On Wed, Jun 17, 2026 at 12:59:21PM +0200, Markus Armbruster wrote:
> Daniel P. Berrangé <berrange@redhat.com> writes:
>
> > QOM has two rather unusual / surprising features historicall
> >
> > * The ability to embed a QOM instance's memory inside another
> > struct
> > * The ability to register properties against the instnce
> > instead of struct
>
> I figure you mean "against the instance instead of the class".
Yes indeed
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 27+ messages in thread