public inbox for qemu-devel@nongnu.org
 help / color / mirror / Atom feed
* [PATCH v2 00/21] qom: introduce property flags to track external user input
@ 2026-02-10  3:23 Zhao Liu
  2026-02-10  3:23 ` [PATCH v2 01/21] qom/object: use BIT macro for ObjectPropertyFlags Zhao Liu
                   ` (22 more replies)
  0 siblings, 23 replies; 68+ messages in thread
From: Zhao Liu @ 2026-02-10  3:23 UTC (permalink / raw)
  To: Paolo Bonzini, Daniel P . Berrangé, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé
  Cc: Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, Zhao Liu, qemu-devel, devel

Hi,

This is the v2 trying to introduce property flags to detect user's
property setting (from CLI/QMP/HMP). I dropped RFC tag since previous
RFC v1 [1].

Though this work the follow-up of v2.6 & v2.7 machines' removal [2],
now it is decoupled from [2] totally since v2 doesn't detect compat
property and only focuses on external user setting, so this series is
based on master branch at the commit 28a6ca268c2c ("Merge tag 'single-
binary-20260203' of https://github.com/philmd/qemu into staging"). And
you can also find the code here:

https://gitlab.com/zhao.liu/qemu/-/tree/prop-flags-v2.3-02-08-2026

This series introduces 3 property flags:
 * USER_SET:
   Any external user property setting (from CLI/HMP/QMP) is marked as
   USER_SET.
 * DEPRECATED:
   Once a property is marked as DEPRECATED, any external user property
   setting will trigger a warning.
 * INTERNAL:
   Once a  property is marked as INTERNAL, any external user property
   setting will cause an error.

More details or document for these 3 flags, you can refer patch 7.


Compared with RFC v1, v2 mainly:
 * introduce USER_SET property flag to identify all user's setting.
   - patch 7 for document.
 * construct DEPRECATED & INTERNAL flag on USER_SET.
   - patch 7 for document.
 * cover more comprehensive user set cases.
   - patch 8-13.
 * provide examples about new flags (USER_SET/DEPRECATED/INTELNAL).
   - patch 15/16/17 are examples for DEPRECATED flag.
   - patch 18 is the example for INTERNAL flag.
   - patch 20 is the example for USER_SET flag.

I think v2 should now cover "nearly" all cases (patch 8-13) where users
set properties: one approach is to trace the call chain of
object_property_set().

Even if there are cases that were missed, they can be easily addressed
based on this series:

  object_property_set(obj, ...);
  /* Insert this call after object_property_set(). */
  object_property_set_flags(obj, ..., OBJ_PROP_FLAG_USER_SET, ...);

[1]: RFC v1:
     https://lore.kernel.org/qemu-devel/20251202170502.3228625-1-zhao1.liu@intel.com/
[2]: hw/i386/pc: Remove deprecated 2.6 and 2.7 PC machines
     https://lore.kernel.org/qemu-devel/20260108033051.777361-1-zhao1.liu@intel.com/

Thanks and Best Regards,
Zhao
---
Zhao Liu (21):
  qom/object: use BIT macro for ObjectPropertyFlags
  qom/object: cache ObjectPropertyFlags in ObjectProperty
  qom/object: factor out object_class_property_try_add()
  qom/object: add flags argument in object_{class_}property_try_add()
  qom/object: rename object_{class_}property_try_add() to
    object_{class_}property_add_full()
  qom/object: add helpers to set/get/clear property flags
  qom/object: introduce user interaction flags for properties
  qom/object: add from_user argument in object_property_parse()
  qom/object: mark global property set from CLI as USER_SET
  qom/qom-hmp-cmd: mark properties set from HMP (non-JSON) "qom-set" as
    USER_SET
  qom/qom-qmp-cmd: mark properties set from QMP/HMP (JSON) "qom-set" as
    USER_SET
  qom/object_interfaces: mark properties set from qdict & keyval as
    USER_SET
  system/vl: mark property set in object_parse_property_opt() as
    USER_SET
  hw/core/qdev-properties: allow qdev properties accept flags
  target/i386: deprecate fill-mtrr-mask property
  target/i386: deprecate cpuid-0xb property
  hw/intc/ioapic: deprecate version property
  target/i386: mark x-consistent-cache property as internal-only
  target/i386: remove redundant validation for lbr-fmt property
  target/i386: detect user provided lbr-fmt via property flag
  hw/core/qdev-properties: support valid default value for
    DEFINE_PROP_UINT64_CHECKMASK

 docs/about/deprecated.rst         |  31 +++++
 hw/core/qdev-properties.c         |  29 ++--
 hw/i386/sgx.c                     |   2 +-
 hw/intc/ioapic.c                  |   3 +-
 include/hw/core/qdev-properties.h |  38 +++---
 include/qom/object.h              | 215 +++++++++++++++++++++++++++---
 qom/object.c                      | 177 ++++++++++++++++++++----
 qom/object_interfaces.c           |   5 +
 qom/qom-hmp-cmds.c                |   2 +-
 qom/qom-qmp-cmds.c                |   7 +-
 system/vl.c                       |   6 +-
 target/i386/cpu.c                 |  28 ++--
 12 files changed, 448 insertions(+), 95 deletions(-)

-- 
2.34.1



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

* [PATCH v2 01/21] qom/object: use BIT macro for ObjectPropertyFlags
  2026-02-10  3:23 [PATCH v2 00/21] qom: introduce property flags to track external user input Zhao Liu
@ 2026-02-10  3:23 ` Zhao Liu
  2026-03-20  9:53   ` Thomas Huth
  2026-02-10  3:23 ` [PATCH v2 02/21] qom/object: cache ObjectPropertyFlags in ObjectProperty Zhao Liu
                   ` (21 subsequent siblings)
  22 siblings, 1 reply; 68+ messages in thread
From: Zhao Liu @ 2026-02-10  3:23 UTC (permalink / raw)
  To: Paolo Bonzini, Daniel P . Berrangé, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé
  Cc: Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, Zhao Liu, qemu-devel, devel

Standardize the definition of ObjectPropertyFlags by using the BIT()
macro instead of manual bit shifts to improve readability.

Suggested-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
 include/qom/object.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/include/qom/object.h b/include/qom/object.h
index 26df6137b911..6226b88c1eda 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -16,6 +16,7 @@
 
 #include "qapi/qapi-builtin-types.h"
 #include "qemu/module.h"
+#include "qemu/bitops.h"
 
 struct TypeImpl;
 typedef struct TypeImpl *Type;
@@ -1841,9 +1842,9 @@ ObjectProperty *object_class_property_add_tm(ObjectClass *klass,
 
 typedef enum {
     /* Automatically add a getter to the property */
-    OBJ_PROP_FLAG_READ = 1 << 0,
+    OBJ_PROP_FLAG_READ = BIT(0),
     /* Automatically add a setter to the property */
-    OBJ_PROP_FLAG_WRITE = 1 << 1,
+    OBJ_PROP_FLAG_WRITE = BIT(1),
     /* Automatically add a getter and a setter to the property */
     OBJ_PROP_FLAG_READWRITE = (OBJ_PROP_FLAG_READ | OBJ_PROP_FLAG_WRITE),
 } ObjectPropertyFlags;
-- 
2.34.1



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

* [PATCH v2 02/21] qom/object: cache ObjectPropertyFlags in ObjectProperty
  2026-02-10  3:23 [PATCH v2 00/21] qom: introduce property flags to track external user input Zhao Liu
  2026-02-10  3:23 ` [PATCH v2 01/21] qom/object: use BIT macro for ObjectPropertyFlags Zhao Liu
@ 2026-02-10  3:23 ` Zhao Liu
  2026-03-20  9:53   ` Thomas Huth
  2026-02-10  3:23 ` [PATCH v2 03/21] qom/object: factor out object_class_property_try_add() Zhao Liu
                   ` (20 subsequent siblings)
  22 siblings, 1 reply; 68+ messages in thread
From: Zhao Liu @ 2026-02-10  3:23 UTC (permalink / raw)
  To: Paolo Bonzini, Daniel P . Berrangé, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé
  Cc: Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, Zhao Liu, qemu-devel, devel

Introduce a 'flags' field in the ObjectProperty structure to store
property-specific behavior modifiers.

Currently, ObjectPropertyFlags (READ/WRITE) are only used for property
creation (e.g., initialize accessors for pointer properties).

By caching these flags directly in ObjectProperty, we can:
1. Preserve the initial access intent (read/write) of the property.
   * the READ/WRITE flags cached in ObjectProperty have no effect for
     now, but they may be useful for cases need write-once, if needed.

2. Reuse existing ObjectPropertyFlags and provide a foundation for
   future flags (e.g., to track if a property was explicitly set by
   external user).

To avoid "incomplete type" error, move ObjectPropertyFlags before
ObjectProperty definition, and polish the comment of ObjectPropertyFlags
to clarify how READ/WRITE flags work for general properties.

Suggested-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
 include/qom/object.h | 34 +++++++++++++++++++++++++---------
 qom/object.c         | 16 +++++++++++++++-
 2 files changed, 40 insertions(+), 10 deletions(-)

diff --git a/include/qom/object.h b/include/qom/object.h
index 6226b88c1eda..05706d4d7e3a 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -87,6 +87,30 @@ typedef void (ObjectPropertyRelease)(Object *obj,
  */
 typedef void (ObjectPropertyInit)(Object *obj, ObjectProperty *prop);
 
+typedef enum {
+    /*
+     * The property is readable and has a getter.
+     *
+     * For pointer property, this flag (set in object_{class_}property_add_*_ptr())
+     * will automatically add a getter to this property.
+     */
+    OBJ_PROP_FLAG_READ = BIT(0),
+    /*
+     * The property is writable and has a setter.
+     *
+     * For pointer property, this flag (set in object_{class_}property_add_*_ptr())
+     * will automatically add a setter to this property.
+     */
+    OBJ_PROP_FLAG_WRITE = BIT(1),
+    /*
+     * The property is readable and writable, as well as has a getter and a setter.
+     *
+     * For pointer property, this flag (set in object_{class_}property_add_*_ptr())
+     * will automatically add a getter and a setter to this property.
+     */
+    OBJ_PROP_FLAG_READWRITE = (OBJ_PROP_FLAG_READ | OBJ_PROP_FLAG_WRITE),
+} ObjectPropertyFlags;
+
 struct ObjectProperty
 {
     char *name;
@@ -99,6 +123,7 @@ struct ObjectProperty
     ObjectPropertyInit *init;
     void *opaque;
     QObject *defval;
+    ObjectPropertyFlags flags;
 };
 
 /**
@@ -1840,15 +1865,6 @@ ObjectProperty *object_class_property_add_tm(ObjectClass *klass,
                             const char *name,
                             void (*get)(Object *, struct tm *, Error **));
 
-typedef enum {
-    /* Automatically add a getter to the property */
-    OBJ_PROP_FLAG_READ = BIT(0),
-    /* Automatically add a setter to the property */
-    OBJ_PROP_FLAG_WRITE = BIT(1),
-    /* Automatically add a getter and a setter to the property */
-    OBJ_PROP_FLAG_READWRITE = (OBJ_PROP_FLAG_READ | OBJ_PROP_FLAG_WRITE),
-} ObjectPropertyFlags;
-
 /**
  * object_property_add_uint8_ptr:
  * @obj: the object to add a property to
diff --git a/qom/object.c b/qom/object.c
index ff8ede8a328e..f5801f4624c8 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1233,6 +1233,19 @@ void object_unref(void *objptr)
     }
 }
 
+static inline void object_property_flags_init(ObjectProperty *prop)
+{
+    uint8_t flags = 0;
+
+    if (prop->set) {
+        flags |= OBJ_PROP_FLAG_WRITE;
+    }
+    if (prop->get) {
+        flags |= OBJ_PROP_FLAG_READ;
+    }
+    prop->flags |= flags;
+}
+
 ObjectProperty *
 object_property_try_add(Object *obj, const char *name, const char *type,
                         ObjectPropertyAccessor *get,
@@ -1279,6 +1292,7 @@ object_property_try_add(Object *obj, const char *name, const char *type,
     prop->set = set;
     prop->release = release;
     prop->opaque = opaque;
+    object_property_flags_init(prop);
 
     g_hash_table_insert(obj->properties, prop->name, prop);
     return prop;
@@ -1317,9 +1331,9 @@ object_class_property_add(ObjectClass *klass,
     prop->set = set;
     prop->release = release;
     prop->opaque = opaque;
+    object_property_flags_init(prop);
 
     g_hash_table_insert(klass->properties, prop->name, prop);
-
     return prop;
 }
 
-- 
2.34.1



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

* [PATCH v2 03/21] qom/object: factor out object_class_property_try_add()
  2026-02-10  3:23 [PATCH v2 00/21] qom: introduce property flags to track external user input Zhao Liu
  2026-02-10  3:23 ` [PATCH v2 01/21] qom/object: use BIT macro for ObjectPropertyFlags Zhao Liu
  2026-02-10  3:23 ` [PATCH v2 02/21] qom/object: cache ObjectPropertyFlags in ObjectProperty Zhao Liu
@ 2026-02-10  3:23 ` Zhao Liu
  2026-02-10 14:41   ` BALATON Zoltan
  2026-02-10  3:23 ` [PATCH v2 04/21] qom/object: add flags argument in object_{class_}property_try_add() Zhao Liu
                   ` (19 subsequent siblings)
  22 siblings, 1 reply; 68+ messages in thread
From: Zhao Liu @ 2026-02-10  3:23 UTC (permalink / raw)
  To: Paolo Bonzini, Daniel P . Berrangé, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé
  Cc: Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, Zhao Liu, qemu-devel, devel

Similar to object_property_try_add(), factor out
object_class_property_try_add().

This allows adding more arguments to the core implementation without
changing the signature of object_class_property_add(), avoiding the
need to modify the extensive number of callers distributed throughout
the code tree.

While at it, add documentation for these functions.

Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
 include/qom/object.h | 56 ++++++++++++++++++++++++++++++++++++++++++++
 qom/object.c         | 34 ++++++++++++++++++++-------
 2 files changed, 82 insertions(+), 8 deletions(-)

diff --git a/include/qom/object.h b/include/qom/object.h
index 05706d4d7e3a..060db136988b 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1147,6 +1147,62 @@ ObjectProperty *object_property_add(Object *obj, const char *name,
 
 void object_property_del(Object *obj, const char *name);
 
+/**
+ * object_class_property_try_add:
+ * @klass: the object class to add a property to
+ * @name: the name of the property.  This can contain any character except for
+ *  a forward slash.  In general, you should use hyphens '-' instead of
+ *  underscores '_' when naming properties.
+ * @type: the type name of the property.  This namespace is pretty loosely
+ *   defined.  Sub namespaces are constructed by using a prefix and then
+ *   to angle brackets.  For instance, the type 'virtio-net-pci' in the
+ *   'link' namespace would be 'link<virtio-net-pci>'.
+ * @get: The getter to be called to read a property.  If this is NULL, then
+ *   the property cannot be read.
+ * @set: the setter to be called to write a property.  If this is NULL,
+ *   then the property cannot be written.
+ * @release: called when the property is removed from the object.  This is
+ *   meant to allow a property to free its opaque upon object
+ *   destruction.  This may be NULL.
+ * @opaque: an opaque pointer to pass to the callbacks for the property
+ * @errp: pointer to error object
+ *
+ * Returns: The #ObjectProperty; this can be used to set the @resolve
+ * callback for child and link properties.
+ */
+ObjectProperty *object_class_property_try_add(ObjectClass *klass, const char *name,
+                                              const char *type,
+                                              ObjectPropertyAccessor *get,
+                                              ObjectPropertyAccessor *set,
+                                              ObjectPropertyRelease *release,
+                                              void *opaque, Error **errp);
+
+
+/**
+ * object_class_property_add:
+ * Same as object_class_property_try_add() with @errp hardcoded to
+ * &error_abort.
+ *
+ * @klass: the object class to add a property to
+ * @name: the name of the property.  This can contain any character except for
+ *  a forward slash.  In general, you should use hyphens '-' instead of
+ *  underscores '_' when naming properties.
+ * @type: the type name of the property.  This namespace is pretty loosely
+ *   defined.  Sub namespaces are constructed by using a prefix and then
+ *   to angle brackets.  For instance, the type 'virtio-net-pci' in the
+ *   'link' namespace would be 'link<virtio-net-pci>'.
+ * @get: The getter to be called to read a property.  If this is NULL, then
+ *   the property cannot be read.
+ * @set: the setter to be called to write a property.  If this is NULL,
+ *   then the property cannot be written.
+ * @release: called when the property is removed from the object.  This is
+ *   meant to allow a property to free its opaque upon object
+ *   destruction.  This may be NULL.
+ * @opaque: an opaque pointer to pass to the callbacks for the property
+ *
+ * Returns: The #ObjectProperty; this can be used to set the @resolve
+ * callback for child and link properties.
+ */
 ObjectProperty *object_class_property_add(ObjectClass *klass, const char *name,
                                           const char *type,
                                           ObjectPropertyAccessor *get,
diff --git a/qom/object.c b/qom/object.c
index f5801f4624c8..f101b48154d1 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1310,17 +1310,22 @@ object_property_add(Object *obj, const char *name, const char *type,
 }
 
 ObjectProperty *
-object_class_property_add(ObjectClass *klass,
-                          const char *name,
-                          const char *type,
-                          ObjectPropertyAccessor *get,
-                          ObjectPropertyAccessor *set,
-                          ObjectPropertyRelease *release,
-                          void *opaque)
+object_class_property_try_add(ObjectClass *klass,
+                              const char *name,
+                              const char *type,
+                              ObjectPropertyAccessor *get,
+                              ObjectPropertyAccessor *set,
+                              ObjectPropertyRelease *release,
+                              void *opaque, Error **errp)
 {
     ObjectProperty *prop;
 
-    assert(!object_class_property_find(klass, name));
+    if (object_class_property_find(klass, name) != NULL) {
+        error_setg(errp, "attempt to add duplicate property '%s'"
+                   " to object class (type '%s')",
+                   name, object_class_get_name(klass));
+        return NULL;
+    }
 
     prop = g_malloc0(sizeof(*prop));
 
@@ -1337,6 +1342,19 @@ object_class_property_add(ObjectClass *klass,
     return prop;
 }
 
+ObjectProperty *
+object_class_property_add(ObjectClass *klass,
+                          const char *name,
+                          const char *type,
+                          ObjectPropertyAccessor *get,
+                          ObjectPropertyAccessor *set,
+                          ObjectPropertyRelease *release,
+                          void *opaque)
+{
+    return object_class_property_try_add(klass, name, type, get, set, release,
+                                         opaque, &error_abort);
+}
+
 ObjectProperty *object_property_find(Object *obj, const char *name)
 {
     ObjectProperty *prop;
-- 
2.34.1



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

* [PATCH v2 04/21] qom/object: add flags argument in object_{class_}property_try_add()
  2026-02-10  3:23 [PATCH v2 00/21] qom: introduce property flags to track external user input Zhao Liu
                   ` (2 preceding siblings ...)
  2026-02-10  3:23 ` [PATCH v2 03/21] qom/object: factor out object_class_property_try_add() Zhao Liu
@ 2026-02-10  3:23 ` Zhao Liu
  2026-02-10  3:23 ` [PATCH v2 05/21] qom/object: rename object_{class_}property_try_add() to object_{class_}property_add_full() Zhao Liu
                   ` (18 subsequent siblings)
  22 siblings, 0 replies; 68+ messages in thread
From: Zhao Liu @ 2026-02-10  3:23 UTC (permalink / raw)
  To: Paolo Bonzini, Daniel P . Berrangé, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé
  Cc: Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, Zhao Liu, qemu-devel, devel

Add the flags argument in object_property_try_add() and
object_class_property_try_add(), allowing callers to explicitly specify
the property flags during creation.

This will be helpful to extend qdev property definition to support
marking as deprecated or internal-only.

Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
 include/qom/object.h | 21 ++++++++++++++++-----
 qom/object.c         | 19 ++++++++++---------
 2 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/include/qom/object.h b/include/qom/object.h
index 060db136988b..7d8a7be1bad3 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1103,6 +1103,11 @@ void object_unref(void *obj);
  * @release: called when the property is removed from the object.  This is
  *   meant to allow a property to free its opaque upon object
  *   destruction.  This may be NULL.
+ * @flags: property flags used to control property uses.  The
+ *   OBJ_PROP_FLAG_READ and OBJ_PROP_FLAG_WRITE flags are automatically
+ *   set based on the presence of the @get and @set callbacks.  The value
+ *   passed here is bitwise-ORed with those automatic flags.  Pass 0 if no
+ *   other flags are needed.
  * @opaque: an opaque pointer to pass to the callbacks for the property
  * @errp: pointer to error object
  *
@@ -1114,12 +1119,13 @@ ObjectProperty *object_property_try_add(Object *obj, const char *name,
                                         ObjectPropertyAccessor *get,
                                         ObjectPropertyAccessor *set,
                                         ObjectPropertyRelease *release,
+                                        ObjectPropertyFlags flags,
                                         void *opaque, Error **errp);
 
 /**
  * object_property_add:
- * Same as object_property_try_add() with @errp hardcoded to
- * &error_abort.
+ * Same as object_property_try_add() with @flags hardcoded to 0 and @errp
+ * hardcoded to &error_abort.
  *
  * @obj: the object to add a property to
  * @name: the name of the property.  This can contain any character except for
@@ -1164,6 +1170,11 @@ void object_property_del(Object *obj, const char *name);
  * @release: called when the property is removed from the object.  This is
  *   meant to allow a property to free its opaque upon object
  *   destruction.  This may be NULL.
+ * @flags: property flags used to control property uses.  The
+ *   OBJ_PROP_FLAG_READ and OBJ_PROP_FLAG_WRITE flags are automatically
+ *   set based on the presence of the @get and @set callbacks.  The value
+ *   passed here is bitwise-ORed with those automatic flags.  Pass 0 if no
+ *   other flags are needed.
  * @opaque: an opaque pointer to pass to the callbacks for the property
  * @errp: pointer to error object
  *
@@ -1175,13 +1186,13 @@ ObjectProperty *object_class_property_try_add(ObjectClass *klass, const char *na
                                               ObjectPropertyAccessor *get,
                                               ObjectPropertyAccessor *set,
                                               ObjectPropertyRelease *release,
+                                              ObjectPropertyFlags flags,
                                               void *opaque, Error **errp);
 
-
 /**
  * object_class_property_add:
- * Same as object_class_property_try_add() with @errp hardcoded to
- * &error_abort.
+ * Same as object_class_property_try_add() with @flags hardcoded to 0 and @errp
+ * hardcoded to &error_abort.
  *
  * @klass: the object class to add a property to
  * @name: the name of the property.  This can contain any character except for
diff --git a/qom/object.c b/qom/object.c
index f101b48154d1..543e42cd6f16 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1233,10 +1233,9 @@ void object_unref(void *objptr)
     }
 }
 
-static inline void object_property_flags_init(ObjectProperty *prop)
+static inline void object_property_flags_init(ObjectProperty *prop,
+                                              ObjectPropertyFlags flags)
 {
-    uint8_t flags = 0;
-
     if (prop->set) {
         flags |= OBJ_PROP_FLAG_WRITE;
     }
@@ -1251,6 +1250,7 @@ object_property_try_add(Object *obj, const char *name, const char *type,
                         ObjectPropertyAccessor *get,
                         ObjectPropertyAccessor *set,
                         ObjectPropertyRelease *release,
+                        ObjectPropertyFlags flags,
                         void *opaque, Error **errp)
 {
     ObjectProperty *prop;
@@ -1266,7 +1266,7 @@ object_property_try_add(Object *obj, const char *name, const char *type,
             char *full_name = g_strdup_printf("%s[%d]", name_no_array, i);
 
             ret = object_property_try_add(obj, full_name, type, get, set,
-                                          release, opaque, NULL);
+                                          release, flags, opaque, NULL);
             g_free(full_name);
             if (ret) {
                 break;
@@ -1292,7 +1292,7 @@ object_property_try_add(Object *obj, const char *name, const char *type,
     prop->set = set;
     prop->release = release;
     prop->opaque = opaque;
-    object_property_flags_init(prop);
+    object_property_flags_init(prop, flags);
 
     g_hash_table_insert(obj->properties, prop->name, prop);
     return prop;
@@ -1306,7 +1306,7 @@ object_property_add(Object *obj, const char *name, const char *type,
                     void *opaque)
 {
     return object_property_try_add(obj, name, type, get, set, release,
-                                   opaque, &error_abort);
+                                   0, opaque, &error_abort);
 }
 
 ObjectProperty *
@@ -1316,6 +1316,7 @@ object_class_property_try_add(ObjectClass *klass,
                               ObjectPropertyAccessor *get,
                               ObjectPropertyAccessor *set,
                               ObjectPropertyRelease *release,
+                              ObjectPropertyFlags flags,
                               void *opaque, Error **errp)
 {
     ObjectProperty *prop;
@@ -1336,7 +1337,7 @@ object_class_property_try_add(ObjectClass *klass,
     prop->set = set;
     prop->release = release;
     prop->opaque = opaque;
-    object_property_flags_init(prop);
+    object_property_flags_init(prop, flags);
 
     g_hash_table_insert(klass->properties, prop->name, prop);
     return prop;
@@ -1352,7 +1353,7 @@ object_class_property_add(ObjectClass *klass,
                           void *opaque)
 {
     return object_class_property_try_add(klass, name, type, get, set, release,
-                                         opaque, &error_abort);
+                                         0, opaque, &error_abort);
 }
 
 ObjectProperty *object_property_find(Object *obj, const char *name)
@@ -1863,7 +1864,7 @@ object_property_try_add_child(Object *obj, const char *name,
     type = g_strdup_printf("child<%s>", object_get_typename(child));
 
     op = object_property_try_add(obj, name, type, object_get_child_property,
-                                 NULL, object_finalize_child_property,
+                                 NULL, object_finalize_child_property, 0,
                                  child, errp);
     if (!op) {
         return NULL;
-- 
2.34.1



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

* [PATCH v2 05/21] qom/object: rename object_{class_}property_try_add() to object_{class_}property_add_full()
  2026-02-10  3:23 [PATCH v2 00/21] qom: introduce property flags to track external user input Zhao Liu
                   ` (3 preceding siblings ...)
  2026-02-10  3:23 ` [PATCH v2 04/21] qom/object: add flags argument in object_{class_}property_try_add() Zhao Liu
@ 2026-02-10  3:23 ` Zhao Liu
  2026-02-10  3:23 ` [PATCH v2 06/21] qom/object: add helpers to set/get/clear property flags Zhao Liu
                   ` (17 subsequent siblings)
  22 siblings, 0 replies; 68+ messages in thread
From: Zhao Liu @ 2026-02-10  3:23 UTC (permalink / raw)
  To: Paolo Bonzini, Daniel P . Berrangé, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé
  Cc: Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, Zhao Liu, qemu-devel, devel

The suffixes "_try_add" and "_add" typically distinguish functions based
solely on their error-handling behavior.

However, the object_{class_}property_try_add() variants now support the
additional 'flags' argument. Consequently, naming them based only on
error handling no longer accurately reflects the distinction between the
two interface variants.

Rename object_{class_}property_try_add() to
object_{class_}property_add_full() to indicate that these interfaces
offer comprehensive argument support, including the new flags.

Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
 include/qom/object.h | 38 ++++++++++++++++++------------------
 qom/object.c         | 46 ++++++++++++++++++++++----------------------
 2 files changed, 42 insertions(+), 42 deletions(-)

diff --git a/include/qom/object.h b/include/qom/object.h
index 7d8a7be1bad3..30c9f20b1d18 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1087,7 +1087,7 @@ Object *object_ref(void *obj);
 void object_unref(void *obj);
 
 /**
- * object_property_try_add:
+ * object_property_add_full:
  * @obj: the object to add a property to
  * @name: the name of the property.  This can contain any character except for
  *  a forward slash.  In general, you should use hyphens '-' instead of
@@ -1114,17 +1114,17 @@ void object_unref(void *obj);
  * Returns: The #ObjectProperty; this can be used to set the @resolve
  * callback for child and link properties.
  */
-ObjectProperty *object_property_try_add(Object *obj, const char *name,
-                                        const char *type,
-                                        ObjectPropertyAccessor *get,
-                                        ObjectPropertyAccessor *set,
-                                        ObjectPropertyRelease *release,
-                                        ObjectPropertyFlags flags,
-                                        void *opaque, Error **errp);
+ObjectProperty *object_property_add_full(Object *obj, const char *name,
+                                         const char *type,
+                                         ObjectPropertyAccessor *get,
+                                         ObjectPropertyAccessor *set,
+                                         ObjectPropertyRelease *release,
+                                         ObjectPropertyFlags flags,
+                                         void *opaque, Error **errp);
 
 /**
  * object_property_add:
- * Same as object_property_try_add() with @flags hardcoded to 0 and @errp
+ * Same as object_property_add_full() with @flags hardcoded to 0 and @errp
  * hardcoded to &error_abort.
  *
  * @obj: the object to add a property to
@@ -1154,7 +1154,7 @@ ObjectProperty *object_property_add(Object *obj, const char *name,
 void object_property_del(Object *obj, const char *name);
 
 /**
- * object_class_property_try_add:
+ * object_class_property_add_full:
  * @klass: the object class to add a property to
  * @name: the name of the property.  This can contain any character except for
  *  a forward slash.  In general, you should use hyphens '-' instead of
@@ -1181,18 +1181,18 @@ void object_property_del(Object *obj, const char *name);
  * Returns: The #ObjectProperty; this can be used to set the @resolve
  * callback for child and link properties.
  */
-ObjectProperty *object_class_property_try_add(ObjectClass *klass, const char *name,
-                                              const char *type,
-                                              ObjectPropertyAccessor *get,
-                                              ObjectPropertyAccessor *set,
-                                              ObjectPropertyRelease *release,
-                                              ObjectPropertyFlags flags,
-                                              void *opaque, Error **errp);
+ObjectProperty *object_class_property_add_full(ObjectClass *klass, const char *name,
+                                               const char *type,
+                                               ObjectPropertyAccessor *get,
+                                               ObjectPropertyAccessor *set,
+                                               ObjectPropertyRelease *release,
+                                               ObjectPropertyFlags flags,
+                                               void *opaque, Error **errp);
 
 /**
  * object_class_property_add:
- * Same as object_class_property_try_add() with @flags hardcoded to 0 and @errp
- * hardcoded to &error_abort.
+ * Same as object_class_property_add_full() with @flags hardcoded to 0 and
+ * @errp hardcoded to &error_abort.
  *
  * @klass: the object class to add a property to
  * @name: the name of the property.  This can contain any character except for
diff --git a/qom/object.c b/qom/object.c
index 543e42cd6f16..c1a1e5ff3fbe 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1246,12 +1246,12 @@ static inline void object_property_flags_init(ObjectProperty *prop,
 }
 
 ObjectProperty *
-object_property_try_add(Object *obj, const char *name, const char *type,
-                        ObjectPropertyAccessor *get,
-                        ObjectPropertyAccessor *set,
-                        ObjectPropertyRelease *release,
-                        ObjectPropertyFlags flags,
-                        void *opaque, Error **errp)
+object_property_add_full(Object *obj, const char *name, const char *type,
+                         ObjectPropertyAccessor *get,
+                         ObjectPropertyAccessor *set,
+                         ObjectPropertyRelease *release,
+                         ObjectPropertyFlags flags,
+                         void *opaque, Error **errp)
 {
     ObjectProperty *prop;
     size_t name_len = strlen(name);
@@ -1265,8 +1265,8 @@ 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);
 
-            ret = object_property_try_add(obj, full_name, type, get, set,
-                                          release, flags, opaque, NULL);
+            ret = object_property_add_full(obj, full_name, type, get, set,
+                                           release, flags, opaque, NULL);
             g_free(full_name);
             if (ret) {
                 break;
@@ -1305,19 +1305,19 @@ object_property_add(Object *obj, const char *name, const char *type,
                     ObjectPropertyRelease *release,
                     void *opaque)
 {
-    return object_property_try_add(obj, name, type, get, set, release,
-                                   0, opaque, &error_abort);
+    return object_property_add_full(obj, name, type, get, set, release,
+                                    0, opaque, &error_abort);
 }
 
 ObjectProperty *
-object_class_property_try_add(ObjectClass *klass,
-                              const char *name,
-                              const char *type,
-                              ObjectPropertyAccessor *get,
-                              ObjectPropertyAccessor *set,
-                              ObjectPropertyRelease *release,
-                              ObjectPropertyFlags flags,
-                              void *opaque, Error **errp)
+object_class_property_add_full(ObjectClass *klass,
+                               const char *name,
+                               const char *type,
+                               ObjectPropertyAccessor *get,
+                               ObjectPropertyAccessor *set,
+                               ObjectPropertyRelease *release,
+                               ObjectPropertyFlags flags,
+                               void *opaque, Error **errp)
 {
     ObjectProperty *prop;
 
@@ -1352,8 +1352,8 @@ object_class_property_add(ObjectClass *klass,
                           ObjectPropertyRelease *release,
                           void *opaque)
 {
-    return object_class_property_try_add(klass, name, type, get, set, release,
-                                         0, opaque, &error_abort);
+    return object_class_property_add_full(klass, name, type, get, set, release,
+                                          0, opaque, &error_abort);
 }
 
 ObjectProperty *object_property_find(Object *obj, const char *name)
@@ -1863,9 +1863,9 @@ object_property_try_add_child(Object *obj, const char *name,
 
     type = g_strdup_printf("child<%s>", object_get_typename(child));
 
-    op = object_property_try_add(obj, name, type, object_get_child_property,
-                                 NULL, object_finalize_child_property, 0,
-                                 child, errp);
+    op = object_property_add_full(obj, name, type, object_get_child_property,
+                                  NULL, object_finalize_child_property, 0,
+                                  child, errp);
     if (!op) {
         return NULL;
     }
-- 
2.34.1



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

* [PATCH v2 06/21] qom/object: add helpers to set/get/clear property flags
  2026-02-10  3:23 [PATCH v2 00/21] qom: introduce property flags to track external user input Zhao Liu
                   ` (4 preceding siblings ...)
  2026-02-10  3:23 ` [PATCH v2 05/21] qom/object: rename object_{class_}property_try_add() to object_{class_}property_add_full() Zhao Liu
@ 2026-02-10  3:23 ` Zhao Liu
  2026-02-10  3:23 ` [PATCH v2 07/21] qom/object: introduce user interaction flags for properties Zhao Liu
                   ` (16 subsequent siblings)
  22 siblings, 0 replies; 68+ messages in thread
From: Zhao Liu @ 2026-02-10  3:23 UTC (permalink / raw)
  To: Paolo Bonzini, Daniel P . Berrangé, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé
  Cc: Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, Zhao Liu, qemu-devel, devel

Introduce four helper functions to operate object property flags:
object_property_set_flags(), object_property_get_flags(),
object_property_check_flags() and object_property_clear_flags().

Among them, object_property_check_flags() is a complement to
object_property_get_flags(), because sometimes it's needed to check
whether certain flags are set without returning all flags.

This encapsulates and separates the flag management logic, avoiding
direct access to ObjectProperty internals in call sites.

Suggested-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
 include/qom/object.h | 64 ++++++++++++++++++++++++++++++++++++++++++++
 qom/object.c         | 63 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 127 insertions(+)

diff --git a/include/qom/object.h b/include/qom/object.h
index 30c9f20b1d18..856b12e7289c 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1086,6 +1086,70 @@ Object *object_ref(void *obj);
  */
 void object_unref(void *obj);
 
+/**
+ * object_property_set_flags:
+ * @obj: the object.
+ * @name: the name of the property.
+ * @flags: the flags to be set for the property.
+ * @errp: pointer to error object.
+ *
+ * Set the @flags to the property. Existing flags are preserved.
+ *
+ * Returns: %true on success, %false on failure.
+ */
+bool object_property_set_flags(Object *obj, const char *name,
+                               ObjectPropertyFlags flags,
+                               Error **errp);
+
+/**
+ * object_property_get_flags:
+ * @obj: the object.
+ * @name: the name of the property.
+ * @flags: pointer to a location to store the retrieved flags. Must not be
+ *  NULL.
+ * @errp: pointer to error object.
+ *
+ * Get the current flags of the specified property.
+ *
+ * Returns: %true on success, %false on failure.
+ */
+bool object_property_get_flags(Object *obj, const char *name,
+                               ObjectPropertyFlags *flags,
+                               Error **errp);
+
+/**
+ * object_property_check_flags:
+ * @obj: the object.
+ * @name: the name of the property.
+ * @flags: the flags to check for on the property.
+ * @errp: pointer to error object.
+ *
+ * Check whether the specified property has all bits in @flags set.
+ * This is useful for detecting if a property has been explicitly set
+ * by the user (e.g. with %OBJ_PROP_FLAG_USER_SET).
+ *
+ * Returns: 1 if all @flags are set, 0 if not all @flags are set,
+ * or -1 on failure (property not found).
+ */
+int object_property_check_flags(Object *obj, const char *name,
+                                ObjectPropertyFlags flags,
+                                Error **errp);
+
+/**
+ * object_property_clear_flags:
+ * @obj: the object.
+ * @name: the name of the property.
+ * @flags: the flags to be removed from the property.
+ * @errp: pointer to error object
+ *
+ * Clear the @flags from the property. Other flags remain unchanged.
+ *
+ * Returns: %true on success, %false on failure.
+ */
+bool object_property_clear_flags(Object *obj, const char *name,
+                                 ObjectPropertyFlags flags,
+                                 Error **errp);
+
 /**
  * object_property_add_full:
  * @obj: the object to add a property to
diff --git a/qom/object.c b/qom/object.c
index c1a1e5ff3fbe..49ef99a299b6 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1233,6 +1233,69 @@ void object_unref(void *objptr)
     }
 }
 
+bool object_property_set_flags(Object *obj, const char *name,
+                               ObjectPropertyFlags flags,
+                               Error **errp)
+{
+    ObjectProperty *prop = object_property_find_err(obj, name, errp);
+    if (!prop) {
+        return false;
+    }
+
+    prop->flags |= flags;
+    return true;
+}
+
+bool object_property_get_flags(Object *obj, const char *name,
+                               ObjectPropertyFlags *flags,
+                               Error **errp)
+{
+    ObjectProperty *prop;
+
+    if (!flags) {
+        error_setg(errp, "invalid argument: flags is NULL");
+        return false;
+    }
+
+    prop = object_property_find_err(obj, name, errp);
+    if (!prop) {
+        return false;
+    }
+
+    *flags = prop->flags;
+    return true;
+}
+
+int object_property_check_flags(Object *obj, const char *name,
+                                ObjectPropertyFlags flags,
+                                Error **errp)
+{
+    ObjectPropertyFlags prop_flags;
+
+    if (!object_property_get_flags(obj, name, &prop_flags, errp)) {
+        return -1;
+    }
+
+    if ((prop_flags & flags) == flags) {
+        return 1;
+    }
+
+    return 0;
+}
+
+bool object_property_clear_flags(Object *obj, const char *name,
+                                 ObjectPropertyFlags flags,
+                                 Error **errp)
+{
+    ObjectProperty *prop = object_property_find_err(obj, name, errp);
+    if (!prop) {
+        return false;
+    }
+
+    prop->flags &= ~flags;
+    return true;
+}
+
 static inline void object_property_flags_init(ObjectProperty *prop,
                                               ObjectPropertyFlags flags)
 {
-- 
2.34.1



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

* [PATCH v2 07/21] qom/object: introduce user interaction flags for properties
  2026-02-10  3:23 [PATCH v2 00/21] qom: introduce property flags to track external user input Zhao Liu
                   ` (5 preceding siblings ...)
  2026-02-10  3:23 ` [PATCH v2 06/21] qom/object: add helpers to set/get/clear property flags Zhao Liu
@ 2026-02-10  3:23 ` Zhao Liu
  2026-02-10  9:49   ` Daniel P. Berrangé
  2026-02-10 14:44   ` BALATON Zoltan
  2026-02-10  3:23 ` [PATCH v2 08/21] qom/object: add from_user argument in object_property_parse() Zhao Liu
                   ` (15 subsequent siblings)
  22 siblings, 2 replies; 68+ messages in thread
From: Zhao Liu @ 2026-02-10  3:23 UTC (permalink / raw)
  To: Paolo Bonzini, Daniel P . Berrangé, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé
  Cc: Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, Zhao Liu, qemu-devel, devel

Introduce three new flags to `ObjectPropertyFlags` to better manage
property interactions with external users (CLI, QMP, HMP):

1. OBJ_PROP_FLAG_USER_SET:
   Marks a property as having been modified by an external user.

   This flag is designed to be "sticky": once set, it persists even if
   the property value is subsequently overwritten by internal logic.
   It allows the QEMU system to distinguish user intent.

   The advantage of this design is that it is not needed to manually
   clear the USER_SET flag on every internal write. This simplifies the
   logic and decouples flag management from the current property setting
   path (object_property_set()).

   This is chosen over a strict "current origin" approach (where
   internal writes would clear the flag) for a practical reason: QEMU
   code often modifies underlying struct fields (which are defined as
   properties) directly, bypassing the property API entirely. This makes
   it impossible to "accurately" track whether the *current* value truly
   comes from the user. Therefore, a sticky "user touched this" flag is
   the only meaningful and robust solution.

2. OBJ_PROP_FLAG_DEPRECATED:
   Marks a property as deprecated.

3. OBJ_PROP_FLAG_INTERNAL:
   Marks a property as internal-only, disallowing external user access.

Additionally, update object_property_set_flags() to implement the
enforcement logic. When a property is flagged with
OBJ_PROP_FLAG_USER_SET:
 - If the property is also marked OBJ_PROP_FLAG_DEPRECATED, report a
   warning.
 - If the property is also marked OBJ_PROP_FLAG_INTERNAL, raise an error
   and stop the operation.

Suggested-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
 include/qom/object.h | 24 ++++++++++++++++++++++++
 qom/object.c         | 15 +++++++++++++++
 2 files changed, 39 insertions(+)

diff --git a/include/qom/object.h b/include/qom/object.h
index 856b12e7289c..1b77429aa28b 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -109,6 +109,30 @@ typedef enum {
      * will automatically add a getter and a setter to this property.
      */
     OBJ_PROP_FLAG_READWRITE = (OBJ_PROP_FLAG_READ | OBJ_PROP_FLAG_WRITE),
+    /*
+     * The property was explicitly set by an external user.
+     *
+     * This flag is set whenever the property is modified via external interfaces
+     * (CLI, QMP, HMP). It allows internal code to distinguish whether the
+     * property has been modified by the user.
+     *
+     * Once set, this flag persists even if the property value is subsequently
+     * overwritten by internal logic. It is NOT automatically cleared and must
+     * be explicitly cleared using object_property_clear_flags().
+     */
+    OBJ_PROP_FLAG_USER_SET = BIT(2),
+    /*
+     * The property is deprecated and will be removed in the future version.
+     *
+     * Any setting to this property by the user will raise a deprecation warning.
+     */
+    OBJ_PROP_FLAG_DEPRECATED = BIT(3),
+    /*
+     * The property is internal only and cannot be set by the user.
+     *
+     * Any setting to this property by the user will raise an error.
+     */
+    OBJ_PROP_FLAG_INTERNAL = BIT(4),
 } ObjectPropertyFlags;
 
 struct ObjectProperty
diff --git a/qom/object.c b/qom/object.c
index 49ef99a299b6..75a1fe7ea1d3 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1242,6 +1242,21 @@ bool object_property_set_flags(Object *obj, const char *name,
         return false;
     }
 
+    if ((flags & OBJ_PROP_FLAG_USER_SET)) {
+        if (prop->flags & OBJ_PROP_FLAG_DEPRECATED) {
+            warn_report("Property '%s.%s' has been deprecated. "
+                        "Please do not use it.",
+                        object_get_typename(obj), name);
+        }
+
+        if (prop->flags & OBJ_PROP_FLAG_INTERNAL) {
+            error_setg(errp, "Property '%s.%s' is internal only. "
+                       "It can't be set by external user",
+                       object_get_typename(obj), name);
+            return false;
+        }
+    }
+
     prop->flags |= flags;
     return true;
 }
-- 
2.34.1



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

* [PATCH v2 08/21] qom/object: add from_user argument in object_property_parse()
  2026-02-10  3:23 [PATCH v2 00/21] qom: introduce property flags to track external user input Zhao Liu
                   ` (6 preceding siblings ...)
  2026-02-10  3:23 ` [PATCH v2 07/21] qom/object: introduce user interaction flags for properties Zhao Liu
@ 2026-02-10  3:23 ` Zhao Liu
  2026-02-10  3:23 ` [PATCH v2 09/21] qom/object: mark global property set from CLI as USER_SET Zhao Liu
                   ` (14 subsequent siblings)
  22 siblings, 0 replies; 68+ messages in thread
From: Zhao Liu @ 2026-02-10  3:23 UTC (permalink / raw)
  To: Paolo Bonzini, Daniel P . Berrangé, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé
  Cc: Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, Zhao Liu, qemu-devel, devel

Currently, object_property_parse() is used for both internal property
settings and external user configurations (e.g., via HMP or global
properties).

To properly manage property flags (specifically OBJ_PROP_FLAG_USER_SET),
it is necessary to identify the source of the property setting.

Update object_property_parse() to accept a 'from_user' argument and
set the USER_SET flag for the property if 'from_user=true'.

As a first step, all existing callers are updated to have 'from_user=
false'. Next the cases set by specific external user will be identified
(like HMP and global properties) and will update 'from_user' argument to
'true'.

Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
 hw/i386/sgx.c        |  2 +-
 include/qom/object.h |  5 +++--
 qom/object.c         | 20 +++++++++++++++-----
 qom/qom-hmp-cmds.c   |  2 +-
 system/vl.c          |  2 +-
 target/i386/cpu.c    |  4 ++--
 6 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/hw/i386/sgx.c b/hw/i386/sgx.c
index 5e792e8e6e96..8cb71be689ff 100644
--- a/hw/i386/sgx.c
+++ b/hw/i386/sgx.c
@@ -316,7 +316,7 @@ void pc_machine_init_sgx_epc(PCMachineState *pcms)
 
         /* set the memdev link with memory backend */
         object_property_parse(OBJECT(dev), SGX_EPC_MEMDEV_PROP,
-                              list->value->memdev, &error_fatal);
+                              list->value->memdev, false, &error_fatal);
         /* set the numa node property for sgx epc object */
         object_property_set_uint(OBJECT(dev), SGX_EPC_NUMA_NODE_PROP,
                                  list->value->node, &error_fatal);
diff --git a/include/qom/object.h b/include/qom/object.h
index 1b77429aa28b..c78e1c03a106 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1655,14 +1655,15 @@ bool object_property_set(Object *obj, const char *name, Visitor *v,
  * @obj: the object
  * @name: the name of the property
  * @string: the string that will be used to parse the property value.
+ * @from_user: whether the property is being set by a external user.
  * @errp: returns an error if this function fails
  *
  * Parses a string and writes the result into a property of an object.
  *
  * Returns: %true on success, %false on failure.
  */
-bool object_property_parse(Object *obj, const char *name,
-                           const char *string, Error **errp);
+bool object_property_parse(Object *obj, const char *name, const char *string,
+                           bool from_user, Error **errp);
 
 /**
  * object_property_print:
diff --git a/qom/object.c b/qom/object.c
index 75a1fe7ea1d3..7140e3f629aa 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -460,7 +460,7 @@ bool object_apply_global_props(Object *obj, const GPtrArray *props,
             continue;
         }
         p->used = true;
-        if (!object_property_parse(obj, p->property, p->value, &err)) {
+        if (!object_property_parse(obj, p->property, p->value, false, &err)) {
             error_prepend(&err, "can't apply global %s.%s=%s: ",
                           p->driver, p->property, p->value);
             /*
@@ -882,7 +882,7 @@ bool object_set_propv(Object *obj,
         const char *value = va_arg(vargs, char *);
 
         g_assert(value != NULL);
-        if (!object_property_parse(obj, propname, value, errp)) {
+        if (!object_property_parse(obj, propname, value, false, errp)) {
             return false;
         }
         propname = va_arg(vargs, char *);
@@ -1802,13 +1802,23 @@ int object_property_get_enum(Object *obj, const char *name,
     return ret;
 }
 
-bool object_property_parse(Object *obj, const char *name,
-                           const char *string, Error **errp)
+bool object_property_parse(Object *obj, const char *name, const char *string,
+                           bool from_user, Error **errp)
 {
     Visitor *v = string_input_visitor_new(string);
-    bool ok = object_property_set(obj, name, v, errp);
+    bool ok;
 
+    ok = object_property_set(obj, name, v, errp);
     visit_free(v);
+
+    if (!ok) {
+        return false;
+    }
+
+    if (from_user) {
+        ok = object_property_set_flags(obj, name,
+                                       OBJ_PROP_FLAG_USER_SET, errp);
+    }
     return ok;
 }
 
diff --git a/qom/qom-hmp-cmds.c b/qom/qom-hmp-cmds.c
index 32e40630c96a..6bdb241e54bd 100644
--- a/qom/qom-hmp-cmds.c
+++ b/qom/qom-hmp-cmds.c
@@ -58,7 +58,7 @@ void hmp_qom_set(Monitor *mon, const QDict *qdict)
             error_set(&err, ERROR_CLASS_DEVICE_NOT_FOUND,
                       "Device '%s' not found", path);
         } else {
-            object_property_parse(obj, property, value, &err);
+            object_property_parse(obj, property, value, false, &err);
         }
     } else {
         QObject *obj = qobject_from_json(value, &err);
diff --git a/system/vl.c b/system/vl.c
index aa9a15504174..6d8167a50006 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -1708,7 +1708,7 @@ static int object_parse_property_opt(Object *obj,
         return 0;
     }
 
-    if (!object_property_parse(obj, name, value, errp)) {
+    if (!object_property_parse(obj, name, value, false, errp)) {
         return -1;
     }
 
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 0a7b884528ea..94a9dcde1eb1 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -8089,7 +8089,7 @@ void x86_cpu_apply_props(X86CPU *cpu, PropValue *props)
             continue;
         }
         object_property_parse(OBJECT(cpu), pv->prop, pv->value,
-                              &error_abort);
+                              false, &error_abort);
     }
 }
 
@@ -8112,7 +8112,7 @@ static void x86_cpu_apply_version_props(X86CPU *cpu, const X86CPUModel *model)
 
         for (p = vdef->props; p && p->prop; p++) {
             object_property_parse(OBJECT(cpu), p->prop, p->value,
-                                  &error_abort);
+                                  false, &error_abort);
         }
 
         if (vdef->version == version) {
-- 
2.34.1



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

* [PATCH v2 09/21] qom/object: mark global property set from CLI as USER_SET
  2026-02-10  3:23 [PATCH v2 00/21] qom: introduce property flags to track external user input Zhao Liu
                   ` (7 preceding siblings ...)
  2026-02-10  3:23 ` [PATCH v2 08/21] qom/object: add from_user argument in object_property_parse() Zhao Liu
@ 2026-02-10  3:23 ` Zhao Liu
  2026-02-10  3:23 ` [PATCH v2 10/21] qom/qom-hmp-cmd: mark properties set from HMP (non-JSON) "qom-set" " Zhao Liu
                   ` (13 subsequent siblings)
  22 siblings, 0 replies; 68+ messages in thread
From: Zhao Liu @ 2026-02-10  3:23 UTC (permalink / raw)
  To: Paolo Bonzini, Daniel P . Berrangé, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé
  Cc: Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, Zhao Liu, qemu-devel, devel

There are now two major categories of global properties:

One category consists of true global properties collected in
global_props(), sourced from CLI options like `-global` and CPU features
like `-cpu`.

The other category comprises compat properties derived from
object_compat_props[]. Within this, object_compat_props[0] and
object_compat_props[1] represent compat properties for accelerators and
machines, respectively. Meanwhile, object_compat_props[2] collects sugar
properties from the CLI.

Although sugar properties are also applied for legacy machine options
(MachineClass::default_machine_opts), considerring those hardcoded
defaults simulate CLI arguments, so treating them as USER_SET is
acceptable as they emulate user behavior.

Therefore, among all global properties, only those in global_props() and
object_compat_props[2] originate from external users. Consequently, when
applying global properties via object_apply_global_props(), these two
categories of user-provided properties are marked as USER_SET by passing
"from_user=true" to object_property_parse().

Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
 hw/core/qdev-properties.c | 2 +-
 include/qom/object.h      | 2 +-
 qom/object.c              | 6 ++++--
 3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index c96ccfb26353..696dc5f201d6 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -1017,7 +1017,7 @@ int qdev_prop_check_globals(void)
 
 void qdev_prop_set_globals(DeviceState *dev)
 {
-    object_apply_global_props(OBJECT(dev), global_props(),
+    object_apply_global_props(OBJECT(dev), global_props(), true,
                               dev->hotplugged ? NULL : &error_fatal);
 }
 
diff --git a/include/qom/object.h b/include/qom/object.h
index c78e1c03a106..b621803f61bb 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -751,7 +751,7 @@ Object *object_new_with_propv(const char *typename,
                               va_list vargs);
 
 bool object_apply_global_props(Object *obj, const GPtrArray *props,
-                               Error **errp);
+                               bool from_user, Error **errp);
 void object_set_machine_compat_props(GPtrArray *compat_props);
 void object_set_accelerator_compat_props(GPtrArray *compat_props);
 void object_register_sugar_prop(const char *driver, const char *prop,
diff --git a/qom/object.c b/qom/object.c
index 7140e3f629aa..4ead0befb351 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -441,7 +441,7 @@ static void object_post_init_with_type(Object *obj, TypeImpl *ti)
 }
 
 bool object_apply_global_props(Object *obj, const GPtrArray *props,
-                               Error **errp)
+                               bool from_user, Error **errp)
 {
     int i;
 
@@ -460,7 +460,8 @@ bool object_apply_global_props(Object *obj, const GPtrArray *props,
             continue;
         }
         p->used = true;
-        if (!object_property_parse(obj, p->property, p->value, false, &err)) {
+        if (!object_property_parse(obj, p->property, p->value,
+                                   from_user, &err)) {
             error_prepend(&err, "can't apply global %s.%s=%s: ",
                           p->driver, p->property, p->value);
             /*
@@ -536,6 +537,7 @@ void object_apply_compat_props(Object *obj)
 
     for (i = 0; i < ARRAY_SIZE(object_compat_props); i++) {
         object_apply_global_props(obj, object_compat_props[i],
+                                  i == 2 ? true : false,
                                   i == 2 ? &error_fatal : &error_abort);
     }
 }
-- 
2.34.1



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

* [PATCH v2 10/21] qom/qom-hmp-cmd: mark properties set from HMP (non-JSON) "qom-set" as USER_SET
  2026-02-10  3:23 [PATCH v2 00/21] qom: introduce property flags to track external user input Zhao Liu
                   ` (8 preceding siblings ...)
  2026-02-10  3:23 ` [PATCH v2 09/21] qom/object: mark global property set from CLI as USER_SET Zhao Liu
@ 2026-02-10  3:23 ` Zhao Liu
  2026-02-10  3:23 ` [PATCH v2 11/21] qom/qom-qmp-cmd: mark properties set from QMP/HMP (JSON) " Zhao Liu
                   ` (12 subsequent siblings)
  22 siblings, 0 replies; 68+ messages in thread
From: Zhao Liu @ 2026-02-10  3:23 UTC (permalink / raw)
  To: Paolo Bonzini, Daniel P . Berrangé, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé
  Cc: Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, Zhao Liu, qemu-devel, devel

The HMP command - "qom-set" is be used to set object property by
external users, and object_property_parse() is used to parse and handle
property setting for non-JSON case.

Since the property setting is from user, pass "from_user=true" to
object_property_parse() and mark properties set in this case as
USER_SET.

Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
 qom/qom-hmp-cmds.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/qom/qom-hmp-cmds.c b/qom/qom-hmp-cmds.c
index 6bdb241e54bd..175091694f5f 100644
--- a/qom/qom-hmp-cmds.c
+++ b/qom/qom-hmp-cmds.c
@@ -58,7 +58,7 @@ void hmp_qom_set(Monitor *mon, const QDict *qdict)
             error_set(&err, ERROR_CLASS_DEVICE_NOT_FOUND,
                       "Device '%s' not found", path);
         } else {
-            object_property_parse(obj, property, value, false, &err);
+            object_property_parse(obj, property, value, true, &err);
         }
     } else {
         QObject *obj = qobject_from_json(value, &err);
-- 
2.34.1



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

* [PATCH v2 11/21] qom/qom-qmp-cmd: mark properties set from QMP/HMP (JSON) "qom-set" as USER_SET
  2026-02-10  3:23 [PATCH v2 00/21] qom: introduce property flags to track external user input Zhao Liu
                   ` (9 preceding siblings ...)
  2026-02-10  3:23 ` [PATCH v2 10/21] qom/qom-hmp-cmd: mark properties set from HMP (non-JSON) "qom-set" " Zhao Liu
@ 2026-02-10  3:23 ` Zhao Liu
  2026-02-10  3:23 ` [PATCH v2 12/21] qom/object_interfaces: mark properties set from qdict & keyval " Zhao Liu
                   ` (11 subsequent siblings)
  22 siblings, 0 replies; 68+ messages in thread
From: Zhao Liu @ 2026-02-10  3:23 UTC (permalink / raw)
  To: Paolo Bonzini, Daniel P . Berrangé, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé
  Cc: Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, Zhao Liu, qemu-devel, devel

The QMP/HMP (JSON) command - "qom-set" is be used to set object property
by external users, so it's from user and should be marked as USER_SET.

Semantically, object_property_set_qobject() is used to convert a QObject
into a property value, rather than directly parsing user input.
Therefore, it is not suitable for adding a "from_user" argument like
object_property_parse() does.

Instead, use object_property_set_flags() to set USER_SET flag
immediately after object_property_set_qobject().

Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
 qom/qom-qmp-cmds.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c
index 48b38d2b7f73..5a98ea276da2 100644
--- a/qom/qom-qmp-cmds.c
+++ b/qom/qom-qmp-cmds.c
@@ -134,7 +134,12 @@ void qmp_qom_set(const char *path, const char *property, QObject *value,
         return;
     }
 
-    object_property_set_qobject(obj, property, value, errp);
+    if (!object_property_set_qobject(obj, property, value, errp)) {
+        return;
+    }
+
+    object_property_set_flags(obj, property,
+                              OBJ_PROP_FLAG_USER_SET, errp);
 }
 
 QObject *qmp_qom_get(const char *path, const char *property, Error **errp)
-- 
2.34.1



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

* [PATCH v2 12/21] qom/object_interfaces: mark properties set from qdict & keyval as USER_SET
  2026-02-10  3:23 [PATCH v2 00/21] qom: introduce property flags to track external user input Zhao Liu
                   ` (10 preceding siblings ...)
  2026-02-10  3:23 ` [PATCH v2 11/21] qom/qom-qmp-cmd: mark properties set from QMP/HMP (JSON) " Zhao Liu
@ 2026-02-10  3:23 ` Zhao Liu
  2026-02-10  3:23 ` [PATCH v2 13/21] system/vl: mark property set in object_parse_property_opt() " Zhao Liu
                   ` (10 subsequent siblings)
  22 siblings, 0 replies; 68+ messages in thread
From: Zhao Liu @ 2026-02-10  3:23 UTC (permalink / raw)
  To: Paolo Bonzini, Daniel P . Berrangé, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé
  Cc: Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, Zhao Liu, qemu-devel, devel

object_set_properties_from_qdict() serves as the common entry point for
parsing and setting properties from qdict (and keyval).

This function is primarily utilized for external user configuration:

1. User Creatable Objects (via user_creatable_add_type()):
   - QMP: object-add
   - HMP: object_add
   - CLI: -object (qemu), --object (qemu-img * / qemu-io / qemu-nbd /
         qemu-storage-daemon)
  - Authz list files ("authz-list-file")

2. Device and Machine creation (keyval-based):
   - CLI: -machine / -device
   - QMP/HMP: device_add
   - Failover devices: virtio_net parses user's "qdict" in
    failover_add_primary().

3. Built-in default machine options (MachineClass::default_machine_opts):
   - These hardcoded defaults simulate CLI arguments and are parsed via
     sugar property way or keyval. Treating them as USER_SET is
     acceptable as they emulate user behavior.

There are a few internal corner cases where devices are created using an
internal qdict:
   - Xen USB (usbback_portid_add())
   - Intel HDA (intel_hda_and_codec_init())

Creating devices via internal qdict should be considered as legacy
technical debt and this should be refactored in future work. For these
cases, applying the USER_SET flag is a temporary and acceptable side
effect.

Therefor, update object_set_properties_from_qdict() to explicitly mark
properties as USER_SET.

Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
 qom/object_interfaces.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index 415cbee8c5cf..f0d5f9d84300 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -56,6 +56,11 @@ static void object_set_properties_from_qdict(Object *obj, const QDict *qdict,
         if (!object_property_set(obj, e->key, v, errp)) {
             goto out;
         }
+
+        if (!object_property_set_flags(obj, e->key,
+                                       OBJ_PROP_FLAG_USER_SET, errp)) {
+            goto out;
+        }
     }
     visit_check_struct(v, errp);
 out:
-- 
2.34.1



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

* [PATCH v2 13/21] system/vl: mark property set in object_parse_property_opt() as USER_SET
  2026-02-10  3:23 [PATCH v2 00/21] qom: introduce property flags to track external user input Zhao Liu
                   ` (11 preceding siblings ...)
  2026-02-10  3:23 ` [PATCH v2 12/21] qom/object_interfaces: mark properties set from qdict & keyval " Zhao Liu
@ 2026-02-10  3:23 ` Zhao Liu
  2026-02-10  3:23 ` [PATCH v2 14/21] hw/core/qdev-properties: allow qdev properties accept flags Zhao Liu
                   ` (9 subsequent siblings)
  22 siblings, 0 replies; 68+ messages in thread
From: Zhao Liu @ 2026-02-10  3:23 UTC (permalink / raw)
  To: Paolo Bonzini, Daniel P . Berrangé, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé
  Cc: Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, Zhao Liu, qemu-devel, devel

At present, object_parse_property_opt() is only used for -accel, which
handles user configurations from CLI.

So, mark the property as USER_SET in object_property_parse().

Also, add a comment to the function to clarify this specific usage
context, and it can serve as a reminder to future callers that
utilizing this function implies the property setting originates from
the external user.

Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
 system/vl.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/system/vl.c b/system/vl.c
index 6d8167a50006..ef1d4e5d96af 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -1700,6 +1700,10 @@ static MachineClass *select_machine(QDict *qdict, Error **errp)
     return machine_class;
 }
 
+/*
+ * object_parse_property_opt() is only used for -accel, so mark the
+ * property as USER_SET in object_property_parse().
+ */
 static int object_parse_property_opt(Object *obj,
                                      const char *name, const char *value,
                                      const char *skip, Error **errp)
@@ -1708,7 +1712,7 @@ static int object_parse_property_opt(Object *obj,
         return 0;
     }
 
-    if (!object_property_parse(obj, name, value, false, errp)) {
+    if (!object_property_parse(obj, name, value, true, errp)) {
         return -1;
     }
 
-- 
2.34.1



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

* [PATCH v2 14/21] hw/core/qdev-properties: allow qdev properties accept flags
  2026-02-10  3:23 [PATCH v2 00/21] qom: introduce property flags to track external user input Zhao Liu
                   ` (12 preceding siblings ...)
  2026-02-10  3:23 ` [PATCH v2 13/21] system/vl: mark property set in object_parse_property_opt() " Zhao Liu
@ 2026-02-10  3:23 ` Zhao Liu
  2026-02-10  9:41   ` Peter Krempa
  2026-02-10  9:56   ` Daniel P. Berrangé
  2026-02-10  3:23 ` [PATCH v2 15/21] target/i386: deprecate fill-mtrr-mask property Zhao Liu
                   ` (8 subsequent siblings)
  22 siblings, 2 replies; 68+ messages in thread
From: Zhao Liu @ 2026-02-10  3:23 UTC (permalink / raw)
  To: Paolo Bonzini, Daniel P . Berrangé, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé
  Cc: Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, Zhao Liu, qemu-devel, devel

Update qdev property interfaces (qdev_property_add_static() and
qdev_class_add_property()) to accept and pass 'ObjectPropertyFlags'.
This enables marking qdev properties with flags such as DEPRECATED or
INTERNAL.

To facilitate this at the definition level, extend the boolean and
uint8_t property macros (as the examples) to accept variable arguments
(VA_ARGS). This allows callers to optionally specify flags in the
property definition.

Example:

DEFINE_PROP_UINT8("version", IOAPICCommonState, version, IOAPIC_VER_DEF,
                  .flags = OBJECT_PROPERTY_DEPRECATED),

Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
 hw/core/qdev-properties.c         | 26 +++++++++++++++-----------
 include/hw/core/qdev-properties.h | 24 ++++++++++++++----------
 2 files changed, 29 insertions(+), 21 deletions(-)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 696dc5f201d6..91c4010e7dc9 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -1071,11 +1071,13 @@ void qdev_property_add_static(DeviceState *dev, const Property *prop)
 
     assert(!prop->info->create);
 
-    op = object_property_add(obj, prop->name, prop->info->type,
-                             field_prop_getter(prop->info),
-                             field_prop_setter(prop->info),
-                             prop->info->release,
-                             (Property *)prop);
+    op = object_property_add_full(obj, prop->name, prop->info->type,
+                                  field_prop_getter(prop->info),
+                                  field_prop_setter(prop->info),
+                                  prop->info->release,
+                                  prop->flags,
+                                  (Property *)prop,
+                                  &error_abort);
 
     object_property_set_description(obj, prop->name,
                                     prop->info->description);
@@ -1097,12 +1099,14 @@ static void qdev_class_add_property(DeviceClass *klass, const char *name,
     if (prop->info->create) {
         op = prop->info->create(oc, name, prop);
     } else {
-        op = object_class_property_add(oc,
-                                       name, prop->info->type,
-                                       field_prop_getter(prop->info),
-                                       field_prop_setter(prop->info),
-                                       prop->info->release,
-                                       (Property *)prop);
+        op = object_class_property_add_full(oc,
+                                            name, prop->info->type,
+                                            field_prop_getter(prop->info),
+                                            field_prop_setter(prop->info),
+                                            prop->info->release,
+                                            prop->flags,
+                                            (Property *)prop,
+                                            &error_abort);
     }
     if (prop->set_default) {
         prop->info->set_default_value(op, prop);
diff --git a/include/hw/core/qdev-properties.h b/include/hw/core/qdev-properties.h
index d8745d4c65f1..c06de37b1e9d 100644
--- a/include/hw/core/qdev-properties.h
+++ b/include/hw/core/qdev-properties.h
@@ -11,6 +11,7 @@
  *     and the field retains whatever value it was given by instance_init).
  * @defval: default value for the property. This is used only if @set_default
  *     is true.
+ * @flags: property flags to control uses.
  */
 struct Property {
     const char   *name;
@@ -27,6 +28,7 @@ struct Property {
     int          arrayfieldsize;
     uint8_t      bitnr;
     bool         set_default;
+    uint8_t      flags;
 };
 
 struct PropertyInfo {
@@ -97,10 +99,11 @@ extern const PropertyInfo qdev_prop_link;
                 .set_default = true,                            \
                 .defval.u    = (bool)_defval)
 
-#define DEFINE_PROP_UNSIGNED(_name, _state, _field, _defval, _prop, _type) \
-    DEFINE_PROP(_name, _state, _field, _prop, _type,                       \
-                .set_default = true,                                       \
-                .defval.u  = (_type)_defval)
+#define DEFINE_PROP_UNSIGNED(_name, _state, _field, _defval, _prop, _type, ...) \
+    DEFINE_PROP(_name, _state, _field, _prop, _type,                            \
+                .set_default = true,                                            \
+                .defval.u  = (_type)_defval,                                    \
+                ##__VA_ARGS__)
 
 #define DEFINE_PROP_UNSIGNED_NODEFAULT(_name, _state, _field, _prop, _type) \
     DEFINE_PROP(_name, _state, _field, _prop, _type)
@@ -118,10 +121,11 @@ extern const PropertyInfo qdev_prop_link;
                 .set_default = true,                                        \
                 .defval.i = (OnOffAuto)_defval)
 
-#define DEFINE_PROP_BOOL(_name, _state, _field, _defval)     \
-    DEFINE_PROP(_name, _state, _field, qdev_prop_bool, bool, \
-                .set_default = true,                         \
-                .defval.u    = (bool)_defval)
+#define DEFINE_PROP_BOOL(_name, _state, _field, _defval, ...) \
+    DEFINE_PROP(_name, _state, _field, qdev_prop_bool, bool,  \
+                .set_default = true,                          \
+                .defval.u    = (bool)_defval,                 \
+                ##__VA_ARGS__)
 
 /**
  * The DEFINE_PROP_UINT64_CHECKMASK macro checks a user-supplied value
@@ -168,8 +172,8 @@ extern const PropertyInfo qdev_prop_link;
     DEFINE_PROP(_name, _state, _field, qdev_prop_link, _ptr_type,     \
                 .link_type  = _type)
 
-#define DEFINE_PROP_UINT8(_n, _s, _f, _d)                       \
-    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, qdev_prop_uint8, uint8_t)
+#define DEFINE_PROP_UINT8(_n, _s, _f, _d, ...)                  \
+    DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, qdev_prop_uint8, uint8_t, ##__VA_ARGS__)
 #define DEFINE_PROP_UINT16(_n, _s, _f, _d)                      \
     DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, qdev_prop_uint16, uint16_t)
 #define DEFINE_PROP_UINT32(_n, _s, _f, _d)                      \
-- 
2.34.1



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

* [PATCH v2 15/21] target/i386: deprecate fill-mtrr-mask property
  2026-02-10  3:23 [PATCH v2 00/21] qom: introduce property flags to track external user input Zhao Liu
                   ` (13 preceding siblings ...)
  2026-02-10  3:23 ` [PATCH v2 14/21] hw/core/qdev-properties: allow qdev properties accept flags Zhao Liu
@ 2026-02-10  3:23 ` Zhao Liu
  2026-02-10  3:23 ` [PATCH v2 16/21] target/i386: deprecate cpuid-0xb property Zhao Liu
                   ` (7 subsequent siblings)
  22 siblings, 0 replies; 68+ messages in thread
From: Zhao Liu @ 2026-02-10  3:23 UTC (permalink / raw)
  To: Paolo Bonzini, Daniel P . Berrangé, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé
  Cc: Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, Zhao Liu, qemu-devel, devel

"fill-mtee-mask" was previously disabled only on PC-Q35-2.6 and
PC-I440FX-2.6 machines, but PC v2.6 machines have been deprecated and
will be removed.

Considerring it may have external use, so deprecate it before removal.

Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
 docs/about/deprecated.rst | 8 ++++++++
 target/i386/cpu.c         | 3 ++-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
index 1d5c4f3707cb..0e8a25e37414 100644
--- a/docs/about/deprecated.rst
+++ b/docs/about/deprecated.rst
@@ -448,6 +448,14 @@ Backend ``memory`` (since 9.0)
 CPU device properties
 '''''''''''''''''''''
 
+``fill-mtrr-mask`` on x86 (since 11.0)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The ``fill-mtrr-mask=true`` fill the bits between 51..number-of-physical-address
+-bits in the MTRR_PHYSMASKn variable range mtrr masks. It was previously set to
+false only on PC-Q35-2.6 and PC-I440FX-2.6 machines, but PC v2.6 machines have
+been removed. Deprecate this property to stop external use.
+
 ``pmu-num=n`` on RISC-V CPUs (since 8.2)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 94a9dcde1eb1..13ccb1702d32 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -10510,7 +10510,8 @@ static const Property x86_cpu_properties[] = {
     DEFINE_PROP_UINT32("guest-phys-bits", X86CPU, guest_phys_bits, -1),
     DEFINE_PROP_BOOL("host-phys-bits", X86CPU, host_phys_bits, false),
     DEFINE_PROP_UINT8("host-phys-bits-limit", X86CPU, host_phys_bits_limit, 0),
-    DEFINE_PROP_BOOL("fill-mtrr-mask", X86CPU, fill_mtrr_mask, true),
+    DEFINE_PROP_BOOL("fill-mtrr-mask", X86CPU, fill_mtrr_mask, true,
+                     .flags = OBJ_PROP_FLAG_DEPRECATED),
     DEFINE_PROP_UINT32("level-func7", X86CPU, env.cpuid_level_func7,
                        UINT32_MAX),
     DEFINE_PROP_UINT32("level", X86CPU, env.cpuid_level, UINT32_MAX),
-- 
2.34.1



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

* [PATCH v2 16/21] target/i386: deprecate cpuid-0xb property
  2026-02-10  3:23 [PATCH v2 00/21] qom: introduce property flags to track external user input Zhao Liu
                   ` (14 preceding siblings ...)
  2026-02-10  3:23 ` [PATCH v2 15/21] target/i386: deprecate fill-mtrr-mask property Zhao Liu
@ 2026-02-10  3:23 ` Zhao Liu
  2026-02-10  3:23 ` [PATCH v2 17/21] hw/intc/ioapic: deprecate version property Zhao Liu
                   ` (6 subsequent siblings)
  22 siblings, 0 replies; 68+ messages in thread
From: Zhao Liu @ 2026-02-10  3:23 UTC (permalink / raw)
  To: Paolo Bonzini, Daniel P . Berrangé, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé
  Cc: Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, Zhao Liu, qemu-devel, devel

"cpuid-0xb" was previously disabled only on PC-Q35-2.6 and
PC-I440FX-2.6 machines, but PC v2.6 machines have been deprecated and
will be removed.

Considerring it may have external use, so deprecate it before removal.

Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
 docs/about/deprecated.rst | 10 ++++++++++
 target/i386/cpu.c         |  3 ++-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
index 0e8a25e37414..fed939b7f042 100644
--- a/docs/about/deprecated.rst
+++ b/docs/about/deprecated.rst
@@ -456,6 +456,16 @@ The ``fill-mtrr-mask=true`` fill the bits between 51..number-of-physical-address
 false only on PC-Q35-2.6 and PC-I440FX-2.6 machines, but PC v2.6 machines have
 been removed. Deprecate this property to stop external use.
 
+``cpuid-0xb`` on x86 (since 11.0)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The ``cpuid-0xb`` is used to control whether to encode CPUID 0xB leaf or not.
+Only legacy x86 CPUs didn't have 0xB leaf, and the ```level``` property can
+control whether CPUID exposes the 0xB leaf and emulate legacy CPUs. This
+property was previously set to false only on PC-Q35-2.6 and PC-I440FX-2.6
+machines, but PC v2.6 machines have been removed. Deprecate this property to
+stop external use.
+
 ``pmu-num=n`` on RISC-V CPUs (since 8.2)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 13ccb1702d32..3766d453157b 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -10523,7 +10523,8 @@ static const Property x86_cpu_properties[] = {
     DEFINE_PROP_UINT64("ucode-rev", X86CPU, ucode_rev, 0),
     DEFINE_PROP_BOOL("full-cpuid-auto-level", X86CPU, full_cpuid_auto_level, true),
     DEFINE_PROP_STRING("hv-vendor-id", X86CPU, hyperv_vendor),
-    DEFINE_PROP_BOOL("cpuid-0xb", X86CPU, enable_cpuid_0xb, true),
+    DEFINE_PROP_BOOL("cpuid-0xb", X86CPU, enable_cpuid_0xb, true,
+                     .flags = OBJ_PROP_FLAG_DEPRECATED),
     DEFINE_PROP_BOOL("x-vendor-cpuid-only", X86CPU, vendor_cpuid_only, true),
     DEFINE_PROP_BOOL("x-vendor-cpuid-only-v2", X86CPU, vendor_cpuid_only_v2, true),
     DEFINE_PROP_BOOL("x-amd-topoext-features-only", X86CPU, amd_topoext_features_only, true),
-- 
2.34.1



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

* [PATCH v2 17/21] hw/intc/ioapic: deprecate version property
  2026-02-10  3:23 [PATCH v2 00/21] qom: introduce property flags to track external user input Zhao Liu
                   ` (15 preceding siblings ...)
  2026-02-10  3:23 ` [PATCH v2 16/21] target/i386: deprecate cpuid-0xb property Zhao Liu
@ 2026-02-10  3:23 ` Zhao Liu
  2026-02-10  3:23 ` [PATCH v2 18/21] target/i386: mark x-consistent-cache property as internal-only Zhao Liu
                   ` (5 subsequent siblings)
  22 siblings, 0 replies; 68+ messages in thread
From: Zhao Liu @ 2026-02-10  3:23 UTC (permalink / raw)
  To: Paolo Bonzini, Daniel P . Berrangé, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé
  Cc: Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, Zhao Liu, qemu-devel, devel

"version" was previously set to "0x11" for v2.7 x86 machines, but v2.7
machines have been deprecated and will be removed.

And since v2.8, all x86 machines are using IOAPIC with "0x20" version.
So it should be not needed to configure the version back to "0x11"
again.

Considerring it may have external use, so deprecate it before removal.

Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
 docs/about/deprecated.rst | 13 +++++++++++++
 hw/intc/ioapic.c          |  3 ++-
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
index fed939b7f042..dac1940636a6 100644
--- a/docs/about/deprecated.rst
+++ b/docs/about/deprecated.rst
@@ -483,6 +483,19 @@ It was implemented as a no-op instruction in TCG up to QEMU 9.0, but
 only with ``-cpu max`` (which does not guarantee migration compatibility
 across versions).
 
+
+Global options
+--------------
+
+``-global ioapic.version=version_id`` (since 11.0)
+''''''''''''''''''''''''''''''''''''''''''''''''''
+
+The ``version`` configures IOAPIC version for x86 machines. It was previously
+set to ``0x11`` for v2.7 machines, and since v2.8, the default version is
+bumped up to ``0x20``. The v2.7 machines have been removed, and ``0x11``
+version should be not needed. Deprecate this property to stop external use.
+
+
 Backwards compatibility
 -----------------------
 
diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c
index 98de6ca8108f..3bf21f421a71 100644
--- a/hw/intc/ioapic.c
+++ b/hw/intc/ioapic.c
@@ -483,7 +483,8 @@ static void ioapic_unrealize(DeviceState *dev)
 }
 
 static const Property ioapic_properties[] = {
-    DEFINE_PROP_UINT8("version", IOAPICCommonState, version, IOAPIC_VER_DEF),
+    DEFINE_PROP_UINT8("version", IOAPICCommonState, version, IOAPIC_VER_DEF,
+                      .flags = OBJ_PROP_FLAG_DEPRECATED),
 };
 
 static void ioapic_class_init(ObjectClass *klass, const void *data)
-- 
2.34.1



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

* [PATCH v2 18/21] target/i386: mark x-consistent-cache property as internal-only
  2026-02-10  3:23 [PATCH v2 00/21] qom: introduce property flags to track external user input Zhao Liu
                   ` (16 preceding siblings ...)
  2026-02-10  3:23 ` [PATCH v2 17/21] hw/intc/ioapic: deprecate version property Zhao Liu
@ 2026-02-10  3:23 ` Zhao Liu
  2026-02-10  3:23 ` [PATCH v2 19/21] target/i386: remove redundant validation for lbr-fmt property Zhao Liu
                   ` (4 subsequent siblings)
  22 siblings, 0 replies; 68+ messages in thread
From: Zhao Liu @ 2026-02-10  3:23 UTC (permalink / raw)
  To: Paolo Bonzini, Daniel P . Berrangé, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé
  Cc: Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, Zhao Liu, qemu-devel, devel

x-consistent-cache property is a compatibility option that defaults to
"true". For old machines, it is set to "false" to maintain the (legacy)
inconsistent cache model for Intel CPUs.

In fact, such wrong and inconsistent cache model should be treated as
buggy "hardware", so that there is no valid use case for users to
manually disable this property.

Therefore, mark it as internal-only via OBJ_PROP_FLAG_INTERNAL flag,
and prohibit all external settings.

Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
 target/i386/cpu.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 3766d453157b..c2f99b98014a 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -10541,7 +10541,8 @@ static const Property x86_cpu_properties[] = {
      * own cache information (see x86_cpu_load_def()).
      */
     DEFINE_PROP_BOOL("legacy-cache", X86CPU, legacy_cache, true),
-    DEFINE_PROP_BOOL("x-consistent-cache", X86CPU, consistent_cache, true),
+    DEFINE_PROP_BOOL("x-consistent-cache", X86CPU, consistent_cache, true,
+                     .flags = OBJ_PROP_FLAG_INTERNAL),
     DEFINE_PROP_BOOL("legacy-multi-node", X86CPU, legacy_multi_node, false),
     DEFINE_PROP_BOOL("xen-vapic", X86CPU, xen_vapic, false),
 
-- 
2.34.1



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

* [PATCH v2 19/21] target/i386: remove redundant validation for lbr-fmt property
  2026-02-10  3:23 [PATCH v2 00/21] qom: introduce property flags to track external user input Zhao Liu
                   ` (17 preceding siblings ...)
  2026-02-10  3:23 ` [PATCH v2 18/21] target/i386: mark x-consistent-cache property as internal-only Zhao Liu
@ 2026-02-10  3:23 ` Zhao Liu
  2026-03-13 22:34   ` Chen, Zide
  2026-02-10  3:23 ` [PATCH v2 20/21] target/i386: detect user provided lbr-fmt via property flag Zhao Liu
                   ` (3 subsequent siblings)
  22 siblings, 1 reply; 68+ messages in thread
From: Zhao Liu @ 2026-02-10  3:23 UTC (permalink / raw)
  To: Paolo Bonzini, Daniel P . Berrangé, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé
  Cc: Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, Zhao Liu, qemu-devel, devel

The 'lbr-fmt' property is defined via DEFINE_PROP_UINT64_CHECKMASK,
utilizing PERF_CAP_LBR_FMT as the validation mask. This mechanism
ensures that the property setter rejects any value attempting to set
bits outside this mask.

So cpu->lbr_fmt is guaranteed to be valid by the time
x86_cpu_realizefn() executes. The manual validation inside the realize
function is therefore redundant.

Remove the unnecessary check.

Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
 target/i386/cpu.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index c2f99b98014a..a594747f0030 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -9816,10 +9816,6 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
      * with user-provided setting.
      */
     if (cpu->lbr_fmt != ~PERF_CAP_LBR_FMT) {
-        if ((cpu->lbr_fmt & PERF_CAP_LBR_FMT) != cpu->lbr_fmt) {
-            error_setg(errp, "invalid lbr-fmt");
-            return;
-        }
         env->features[FEAT_PERF_CAPABILITIES] &= ~PERF_CAP_LBR_FMT;
         env->features[FEAT_PERF_CAPABILITIES] |= cpu->lbr_fmt;
     }
-- 
2.34.1



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

* [PATCH v2 20/21] target/i386: detect user provided lbr-fmt via property flag
  2026-02-10  3:23 [PATCH v2 00/21] qom: introduce property flags to track external user input Zhao Liu
                   ` (18 preceding siblings ...)
  2026-02-10  3:23 ` [PATCH v2 19/21] target/i386: remove redundant validation for lbr-fmt property Zhao Liu
@ 2026-02-10  3:23 ` Zhao Liu
  2026-03-13 22:36   ` Chen, Zide
  2026-02-10  3:23 ` [PATCH v2 21/21] hw/core/qdev-properties: support valid default value for DEFINE_PROP_UINT64_CHECKMASK Zhao Liu
                   ` (2 subsequent siblings)
  22 siblings, 1 reply; 68+ messages in thread
From: Zhao Liu @ 2026-02-10  3:23 UTC (permalink / raw)
  To: Paolo Bonzini, Daniel P . Berrangé, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé
  Cc: Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, Zhao Liu, qemu-devel, devel

At present, QEMU determines if the user has set the "lbr-fmt" property
by checking if its value differs from a special value,
`~PERF_CAP_LBR_FMT` (`~0x3f`).

Relying on such a magic number to distinguish user input from the
default state is implicit and fragile. It also prevents the helper macro
`DEFINE_PROP_UINT64_CHECKMASK` from supporting a *valid* default value,
as initializing the property with a valid default would make it
impossible to distinguish from a user-provided value.

With the introduction of `OBJ_PROP_FLAG_USER_SET`, it's possible to
directly check this flag to determine whether the user has modified the
property, which can help get rid of invalid "sentinel" value.

Therefore, detect user-provided value by checking the USER_SET property
flag in x86_cpu_realizefn(). The invalid initialization value will be
dropped in subsequent work.

Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
 target/i386/cpu.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index a594747f0030..a6d943c53a3f 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -9779,6 +9779,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
     CPUX86State *env = &cpu->env;
     Error *local_err = NULL;
     unsigned requested_lbr_fmt;
+    int lbr_fmt_set;
 
 #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
     /* Use pc-relative instructions in system-mode */
@@ -9815,7 +9816,11 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
      * Override env->features[FEAT_PERF_CAPABILITIES].LBR_FMT
      * with user-provided setting.
      */
-    if (cpu->lbr_fmt != ~PERF_CAP_LBR_FMT) {
+    lbr_fmt_set = object_property_check_flags(OBJECT(dev), "lbr-fmt",
+                                              OBJ_PROP_FLAG_USER_SET, errp);
+    if (lbr_fmt_set < 0) {
+        return;
+    } else if (lbr_fmt_set > 0) {
         env->features[FEAT_PERF_CAPABILITIES] &= ~PERF_CAP_LBR_FMT;
         env->features[FEAT_PERF_CAPABILITIES] |= cpu->lbr_fmt;
     }
-- 
2.34.1



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

* [PATCH v2 21/21] hw/core/qdev-properties: support valid default value for DEFINE_PROP_UINT64_CHECKMASK
  2026-02-10  3:23 [PATCH v2 00/21] qom: introduce property flags to track external user input Zhao Liu
                   ` (19 preceding siblings ...)
  2026-02-10  3:23 ` [PATCH v2 20/21] target/i386: detect user provided lbr-fmt via property flag Zhao Liu
@ 2026-02-10  3:23 ` Zhao Liu
  2026-03-13 22:36   ` Chen, Zide
  2026-02-10 10:12 ` [PATCH v2 00/21] qom: introduce property flags to track external user input Daniel P. Berrangé
  2026-03-11 13:05 ` Markus Armbruster
  22 siblings, 1 reply; 68+ messages in thread
From: Zhao Liu @ 2026-02-10  3:23 UTC (permalink / raw)
  To: Paolo Bonzini, Daniel P . Berrangé, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé
  Cc: Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, Zhao Liu, qemu-devel, devel

DEFINE_PROP_UINT64_CHECKMASK is designed to detect and check user's
property setting:
 * checking: check property value against a bitmask.
 * detection: ask caller to provide an invalid value as the initial
     "sentinel" value, which is impossible to be set by users. However,
     this detection is not strict, since the property could be also
     set internally.

The entire mechanism is not easy to use.

Now there's USER_SET flag in place (and the current unique use case
"lbr-fmt" has been converted to checking USER_SET way), manual setting
of invalid initial values is no longer required.

Thus, extend DEFINE_PROP_UINT64_CHECKMASK to support *valid* default
value, and for "lbr-fmt" case, replace the invalid initialization value
`~PERF_CAP_LBR_FMT` with a valid value `0`.

In addition, considering DEFINE_PROP_UINT64_CHECKMASK itself actually
doesn't identify whether the property is set by the user or not, remove
"user-supplied" related description in its document.

Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
 hw/core/qdev-properties.c         |  1 +
 include/hw/core/qdev-properties.h | 14 +++++++-------
 target/i386/cpu.c                 |  4 +---
 3 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 91c4010e7dc9..b84214e60f19 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -507,6 +507,7 @@ const PropertyInfo qdev_prop_uint64_checkmask = {
     .type  = "uint64",
     .get   = get_uint64,
     .set   = set_uint64_checkmask,
+    .set_default_value = qdev_propinfo_set_default_value_uint,
 };
 
 /* --- pointer-size integer --- */
diff --git a/include/hw/core/qdev-properties.h b/include/hw/core/qdev-properties.h
index c06de37b1e9d..2ac784bb5e9c 100644
--- a/include/hw/core/qdev-properties.h
+++ b/include/hw/core/qdev-properties.h
@@ -128,14 +128,14 @@ extern const PropertyInfo qdev_prop_link;
                 ##__VA_ARGS__)
 
 /**
- * The DEFINE_PROP_UINT64_CHECKMASK macro checks a user-supplied value
- * against corresponding bitmask, rejects the value if it violates.
- * The default value is set in instance_init().
+ * The DEFINE_PROP_UINT64_CHECKMASK macro checks a value against corresponding
+ * bitmask, rejects the value if it violates.
  */
-#define DEFINE_PROP_UINT64_CHECKMASK(_name, _state, _field, _bitmask)   \
-    DEFINE_PROP(_name, _state, _field, qdev_prop_uint64_checkmask, uint64_t, \
-                .bitmask    = (_bitmask),                     \
-                .set_default = false)
+#define DEFINE_PROP_UINT64_CHECKMASK(_name, _state, _field, _bitmask, _defval) \
+    DEFINE_PROP(_name, _state, _field, qdev_prop_uint64_checkmask, uint64_t,   \
+                .bitmask    = (_bitmask),                                      \
+                .set_default = true,                                           \
+                .defval.u    = (_defval))
 
 /**
  * DEFINE_PROP_ARRAY:
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index a6d943c53a3f..56735570d66c 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -10265,9 +10265,7 @@ static void x86_cpu_initfn(Object *obj)
     object_property_add_alias(obj, "pause_filter", obj, "pause-filter");
     object_property_add_alias(obj, "sse4_1", obj, "sse4.1");
     object_property_add_alias(obj, "sse4_2", obj, "sse4.2");
-
     object_property_add_alias(obj, "hv-apicv", obj, "hv-avic");
-    cpu->lbr_fmt = ~PERF_CAP_LBR_FMT;
     object_property_add_alias(obj, "lbr_fmt", obj, "lbr-fmt");
 
     if (xcc->model) {
@@ -10439,7 +10437,7 @@ static const Property x86_cpu_properties[] = {
 #endif
     DEFINE_PROP_INT32("node-id", X86CPU, node_id, CPU_UNSET_NUMA_NODE_ID),
     DEFINE_PROP_BOOL("pmu", X86CPU, enable_pmu, false),
-    DEFINE_PROP_UINT64_CHECKMASK("lbr-fmt", X86CPU, lbr_fmt, PERF_CAP_LBR_FMT),
+    DEFINE_PROP_UINT64_CHECKMASK("lbr-fmt", X86CPU, lbr_fmt, PERF_CAP_LBR_FMT, 0),
 
     DEFINE_PROP_UINT32("hv-spinlocks", X86CPU, hyperv_spinlock_attempts,
                        HYPERV_SPINLOCK_NEVER_NOTIFY),
-- 
2.34.1



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

* Re: [PATCH v2 14/21] hw/core/qdev-properties: allow qdev properties accept flags
  2026-02-10  3:23 ` [PATCH v2 14/21] hw/core/qdev-properties: allow qdev properties accept flags Zhao Liu
@ 2026-02-10  9:41   ` Peter Krempa
  2026-02-11  7:10     ` Zhao Liu
  2026-02-10  9:56   ` Daniel P. Berrangé
  1 sibling, 1 reply; 68+ messages in thread
From: Peter Krempa @ 2026-02-10  9:41 UTC (permalink / raw)
  To: Zhao Liu
  Cc: Paolo Bonzini, Daniel P . Berrangé, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé, Richard Henderson, Peter Maydell,
	Michael S . Tsirkin, BALATON Zoltan, Mark Cave-Ayland,
	Pierrick Bouvier, Zide Chen, Dapeng Mi, qemu-devel, devel

On Tue, Feb 10, 2026 at 11:23:41 +0800, Zhao Liu wrote:
> Update qdev property interfaces (qdev_property_add_static() and
> qdev_class_add_property()) to accept and pass 'ObjectPropertyFlags'.
> This enables marking qdev properties with flags such as DEPRECATED or
> INTERNAL.
> 
> To facilitate this at the definition level, extend the boolean and
> uint8_t property macros (as the examples) to accept variable arguments
> (VA_ARGS). This allows callers to optionally specify flags in the
> property definition.
> 
> Example:
> 
> DEFINE_PROP_UINT8("version", IOAPICCommonState, version, IOAPIC_VER_DEF,
>                   .flags = OBJECT_PROPERTY_DEPRECATED),

Is there a plan to expose at least the _DEPRECATED property to be
introspectable (e.g. via qom-list-properties or device-list-properties)
?

In libvirt we try to stay proactive about adapting to deprecations and
this would allow our test-suite to detect deprecations programmaticaly
similarly to how we detect deprecations via query-qmp-schema. Although
with the current patchset there doesn't seem to be anything that libvirt
would need to adapt to.



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

* Re: [PATCH v2 07/21] qom/object: introduce user interaction flags for properties
  2026-02-10  3:23 ` [PATCH v2 07/21] qom/object: introduce user interaction flags for properties Zhao Liu
@ 2026-02-10  9:49   ` Daniel P. Berrangé
  2026-02-10  9:58     ` Daniel P. Berrangé
  2026-02-10 14:44   ` BALATON Zoltan
  1 sibling, 1 reply; 68+ messages in thread
From: Daniel P. Berrangé @ 2026-02-10  9:49 UTC (permalink / raw)
  To: Zhao Liu
  Cc: Paolo Bonzini, Eduardo Habkost, Markus Armbruster, Thomas Huth,
	Igor Mammedov, Philippe Mathieu-Daudé, Richard Henderson,
	Peter Maydell, Michael S . Tsirkin, BALATON Zoltan,
	Mark Cave-Ayland, Pierrick Bouvier, Zide Chen, Dapeng Mi,
	qemu-devel, devel

On Tue, Feb 10, 2026 at 11:23:34AM +0800, Zhao Liu wrote:
> Introduce three new flags to `ObjectPropertyFlags` to better manage
> property interactions with external users (CLI, QMP, HMP):
> 
> 1. OBJ_PROP_FLAG_USER_SET:
>    Marks a property as having been modified by an external user.
> 
>    This flag is designed to be "sticky": once set, it persists even if
>    the property value is subsequently overwritten by internal logic.
>    It allows the QEMU system to distinguish user intent.
> 
>    The advantage of this design is that it is not needed to manually
>    clear the USER_SET flag on every internal write. This simplifies the
>    logic and decouples flag management from the current property setting
>    path (object_property_set()).
> 
>    This is chosen over a strict "current origin" approach (where
>    internal writes would clear the flag) for a practical reason: QEMU
>    code often modifies underlying struct fields (which are defined as
>    properties) directly, bypassing the property API entirely. This makes
>    it impossible to "accurately" track whether the *current* value truly
>    comes from the user. Therefore, a sticky "user touched this" flag is
>    the only meaningful and robust solution.
> 
> 2. OBJ_PROP_FLAG_DEPRECATED:
>    Marks a property as deprecated.
> 
> 3. OBJ_PROP_FLAG_INTERNAL:
>    Marks a property as internal-only, disallowing external user access.
> 
> Additionally, update object_property_set_flags() to implement the
> enforcement logic. When a property is flagged with
> OBJ_PROP_FLAG_USER_SET:
>  - If the property is also marked OBJ_PROP_FLAG_DEPRECATED, report a
>    warning.
>  - If the property is also marked OBJ_PROP_FLAG_INTERNAL, raise an error
>    and stop the operation.
> 
> Suggested-by: Igor Mammedov <imammedo@redhat.com>
> Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
> ---
>  include/qom/object.h | 24 ++++++++++++++++++++++++
>  qom/object.c         | 15 +++++++++++++++
>  2 files changed, 39 insertions(+)
> 
> diff --git a/include/qom/object.h b/include/qom/object.h
> index 856b12e7289c..1b77429aa28b 100644
> --- a/include/qom/object.h
> +++ b/include/qom/object.h
> @@ -109,6 +109,30 @@ typedef enum {
>       * will automatically add a getter and a setter to this property.
>       */
>      OBJ_PROP_FLAG_READWRITE = (OBJ_PROP_FLAG_READ | OBJ_PROP_FLAG_WRITE),
> +    /*
> +     * The property was explicitly set by an external user.
> +     *
> +     * This flag is set whenever the property is modified via external interfaces
> +     * (CLI, QMP, HMP). It allows internal code to distinguish whether the
> +     * property has been modified by the user.
> +     *
> +     * Once set, this flag persists even if the property value is subsequently
> +     * overwritten by internal logic. It is NOT automatically cleared and must
> +     * be explicitly cleared using object_property_clear_flags().
> +     */
> +    OBJ_PROP_FLAG_USER_SET = BIT(2),
> +    /*
> +     * The property is deprecated and will be removed in the future version.
> +     *
> +     * Any setting to this property by the user will raise a deprecation warning.
> +     */
> +    OBJ_PROP_FLAG_DEPRECATED = BIT(3),
> +    /*
> +     * The property is internal only and cannot be set by the user.
> +     *
> +     * Any setting to this property by the user will raise an error.
> +     */
> +    OBJ_PROP_FLAG_INTERNAL = BIT(4),
>  } ObjectPropertyFlags;

I don't think this single enum design is very desirable, as it is mixing up
pieces of information with three distinct lifetimes / scopes.

The OBJ_PROP_FLAD_{READ,WRITE,READWRITE} values are scoped to the execution
of the property adder methods.

The OBJ_PROP_FLAG_{DEPRECATED,INTERNAL} values are scoped to the lifetime
of the class.

The OBJ_PROP_FLAG_USER_SET value is scoped to the lifetime of the instance.

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



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

* Re: [PATCH v2 14/21] hw/core/qdev-properties: allow qdev properties accept flags
  2026-02-10  3:23 ` [PATCH v2 14/21] hw/core/qdev-properties: allow qdev properties accept flags Zhao Liu
  2026-02-10  9:41   ` Peter Krempa
@ 2026-02-10  9:56   ` Daniel P. Berrangé
  2026-02-11  7:30     ` Zhao Liu
  1 sibling, 1 reply; 68+ messages in thread
From: Daniel P. Berrangé @ 2026-02-10  9:56 UTC (permalink / raw)
  To: Zhao Liu
  Cc: Paolo Bonzini, Eduardo Habkost, Markus Armbruster, Thomas Huth,
	Igor Mammedov, Philippe Mathieu-Daudé, Richard Henderson,
	Peter Maydell, Michael S . Tsirkin, BALATON Zoltan,
	Mark Cave-Ayland, Pierrick Bouvier, Zide Chen, Dapeng Mi,
	qemu-devel, devel

On Tue, Feb 10, 2026 at 11:23:41AM +0800, Zhao Liu wrote:
> Update qdev property interfaces (qdev_property_add_static() and
> qdev_class_add_property()) to accept and pass 'ObjectPropertyFlags'.
> This enables marking qdev properties with flags such as DEPRECATED or
> INTERNAL.
> 
> To facilitate this at the definition level, extend the boolean and
> uint8_t property macros (as the examples) to accept variable arguments
> (VA_ARGS). This allows callers to optionally specify flags in the
> property definition.
> 
> Example:
> 
> DEFINE_PROP_UINT8("version", IOAPICCommonState, version, IOAPIC_VER_DEF,
>                   .flags = OBJECT_PROPERTY_DEPRECATED),

In other places where we track deprecation in QEMU, we have not used
a boolean flag. Instead we have used a "const char *deprecation_note"
internally, which lets us provide a user facing message, to be printed
out in the warn_report, informing them what to do instead (either the
feature is entirely removed, or there is a better alternative). IMHO
we should be following the same pattern for properties, as it is much
more user friendly than just printing a totally generic message
"XXXX is deprecated, stop using it" 


With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



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

* Re: [PATCH v2 07/21] qom/object: introduce user interaction flags for properties
  2026-02-10  9:49   ` Daniel P. Berrangé
@ 2026-02-10  9:58     ` Daniel P. Berrangé
  2026-02-11  8:19       ` Zhao Liu
  0 siblings, 1 reply; 68+ messages in thread
From: Daniel P. Berrangé @ 2026-02-10  9:58 UTC (permalink / raw)
  To: Zhao Liu, Paolo Bonzini, Eduardo Habkost, Markus Armbruster,
	Thomas Huth, Igor Mammedov, Philippe Mathieu-Daudé,
	Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, qemu-devel, devel

On Tue, Feb 10, 2026 at 09:49:40AM +0000, Daniel P. Berrangé wrote:
> On Tue, Feb 10, 2026 at 11:23:34AM +0800, Zhao Liu wrote:
> > Introduce three new flags to `ObjectPropertyFlags` to better manage
> > property interactions with external users (CLI, QMP, HMP):
> > 
> > 1. OBJ_PROP_FLAG_USER_SET:
> >    Marks a property as having been modified by an external user.
> > 
> >    This flag is designed to be "sticky": once set, it persists even if
> >    the property value is subsequently overwritten by internal logic.
> >    It allows the QEMU system to distinguish user intent.
> > 
> >    The advantage of this design is that it is not needed to manually
> >    clear the USER_SET flag on every internal write. This simplifies the
> >    logic and decouples flag management from the current property setting
> >    path (object_property_set()).
> > 
> >    This is chosen over a strict "current origin" approach (where
> >    internal writes would clear the flag) for a practical reason: QEMU
> >    code often modifies underlying struct fields (which are defined as
> >    properties) directly, bypassing the property API entirely. This makes
> >    it impossible to "accurately" track whether the *current* value truly
> >    comes from the user. Therefore, a sticky "user touched this" flag is
> >    the only meaningful and robust solution.
> > 
> > 2. OBJ_PROP_FLAG_DEPRECATED:
> >    Marks a property as deprecated.
> > 
> > 3. OBJ_PROP_FLAG_INTERNAL:
> >    Marks a property as internal-only, disallowing external user access.
> > 
> > Additionally, update object_property_set_flags() to implement the
> > enforcement logic. When a property is flagged with
> > OBJ_PROP_FLAG_USER_SET:
> >  - If the property is also marked OBJ_PROP_FLAG_DEPRECATED, report a
> >    warning.
> >  - If the property is also marked OBJ_PROP_FLAG_INTERNAL, raise an error
> >    and stop the operation.
> > 
> > Suggested-by: Igor Mammedov <imammedo@redhat.com>
> > Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
> > ---
> >  include/qom/object.h | 24 ++++++++++++++++++++++++
> >  qom/object.c         | 15 +++++++++++++++
> >  2 files changed, 39 insertions(+)
> > 
> > diff --git a/include/qom/object.h b/include/qom/object.h
> > index 856b12e7289c..1b77429aa28b 100644
> > --- a/include/qom/object.h
> > +++ b/include/qom/object.h
> > @@ -109,6 +109,30 @@ typedef enum {
> >       * will automatically add a getter and a setter to this property.
> >       */
> >      OBJ_PROP_FLAG_READWRITE = (OBJ_PROP_FLAG_READ | OBJ_PROP_FLAG_WRITE),
> > +    /*
> > +     * The property was explicitly set by an external user.
> > +     *
> > +     * This flag is set whenever the property is modified via external interfaces
> > +     * (CLI, QMP, HMP). It allows internal code to distinguish whether the
> > +     * property has been modified by the user.
> > +     *
> > +     * Once set, this flag persists even if the property value is subsequently
> > +     * overwritten by internal logic. It is NOT automatically cleared and must
> > +     * be explicitly cleared using object_property_clear_flags().
> > +     */
> > +    OBJ_PROP_FLAG_USER_SET = BIT(2),
> > +    /*
> > +     * The property is deprecated and will be removed in the future version.
> > +     *
> > +     * Any setting to this property by the user will raise a deprecation warning.
> > +     */
> > +    OBJ_PROP_FLAG_DEPRECATED = BIT(3),
> > +    /*
> > +     * The property is internal only and cannot be set by the user.
> > +     *
> > +     * Any setting to this property by the user will raise an error.
> > +     */
> > +    OBJ_PROP_FLAG_INTERNAL = BIT(4),
> >  } ObjectPropertyFlags;
> 
> I don't think this single enum design is very desirable, as it is mixing up
> pieces of information with three distinct lifetimes / scopes.
> 
> The OBJ_PROP_FLAD_{READ,WRITE,READWRITE} values are scoped to the execution
> of the property adder methods.
> 
> The OBJ_PROP_FLAG_{DEPRECATED,INTERNAL} values are scoped to the lifetime
> of the class.
> 
> The OBJ_PROP_FLAG_USER_SET value is scoped to the lifetime of the instance.

In fact, with my comment on the later patch, OBJ_PROP_FLAG_DEPRECATED should
not be modelled as a boolean flag at all.  We need to record a const char*
deprecation_note internally, so that warn_report can provide useful info
to the user. We can turn that into a "bool deprecated" flag in the QAPI
command response for querying properties.


With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



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

* Re: [PATCH v2 00/21] qom: introduce property flags to track external user input
  2026-02-10  3:23 [PATCH v2 00/21] qom: introduce property flags to track external user input Zhao Liu
                   ` (20 preceding siblings ...)
  2026-02-10  3:23 ` [PATCH v2 21/21] hw/core/qdev-properties: support valid default value for DEFINE_PROP_UINT64_CHECKMASK Zhao Liu
@ 2026-02-10 10:12 ` Daniel P. Berrangé
  2026-02-10 10:44   ` Michael S. Tsirkin
  2026-02-10 15:28   ` Zhao Liu
  2026-03-11 13:05 ` Markus Armbruster
  22 siblings, 2 replies; 68+ messages in thread
From: Daniel P. Berrangé @ 2026-02-10 10:12 UTC (permalink / raw)
  To: Zhao Liu
  Cc: Paolo Bonzini, Eduardo Habkost, Markus Armbruster, Thomas Huth,
	Igor Mammedov, Philippe Mathieu-Daudé, Richard Henderson,
	Peter Maydell, Michael S . Tsirkin, BALATON Zoltan,
	Mark Cave-Ayland, Pierrick Bouvier, Zide Chen, Dapeng Mi,
	qemu-devel, devel

On Tue, Feb 10, 2026 at 11:23:27AM +0800, Zhao Liu wrote:
> Hi,
> 
> This is the v2 trying to introduce property flags to detect user's
> property setting (from CLI/QMP/HMP). I dropped RFC tag since previous
> RFC v1 [1].

This says what the series is proposing, but IMHO what is more important
here is explaining why this either desirable or appropriate to add as
general facility in QOM.

The idea that code should take different action for a given fixed value,
based on whether the value was set by the user, or left on the default,
makes me very uncomfortable.

There have been a number of situations where something that was initially 
a boolean flag, actually needed to be a tri-state instead, to provide
semantics like "On", "Off", "Auto".

This "user set" flag could support such behaviour indirectly, but since
"user set" is an internal concept we'd still be only exposing a boolean
externally, while using a tri-state internally. That does not give the
full flexibility of a tri-state, because internally if we wanted to
have the default to be "yes", it offers no way for the mgmt app to
put it back to "auto".

For properties that are not booleans, it is much less obvious to me
whether we actually need a distinct "not set" concept at all.


So overall, at a conceptual level, I don't think that QOM should care
about /how/ a value came to be set. It should have no direct awareness
of the "user input", rather it just represents the configuration of the
system at a given point in time,  however that came to pass.


With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



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

* Re: [PATCH v2 00/21] qom: introduce property flags to track external user input
  2026-02-10 10:12 ` [PATCH v2 00/21] qom: introduce property flags to track external user input Daniel P. Berrangé
@ 2026-02-10 10:44   ` Michael S. Tsirkin
  2026-02-10 11:00     ` Daniel P. Berrangé
  2026-02-10 15:28   ` Zhao Liu
  1 sibling, 1 reply; 68+ messages in thread
From: Michael S. Tsirkin @ 2026-02-10 10:44 UTC (permalink / raw)
  To: Daniel P. Berrangé
  Cc: Zhao Liu, Paolo Bonzini, Eduardo Habkost, Markus Armbruster,
	Thomas Huth, Igor Mammedov, Philippe Mathieu-Daudé,
	Richard Henderson, Peter Maydell, BALATON Zoltan,
	Mark Cave-Ayland, Pierrick Bouvier, Zide Chen, Dapeng Mi,
	qemu-devel, devel

On Tue, Feb 10, 2026 at 10:12:38AM +0000, Daniel P. Berrangé wrote:
> On Tue, Feb 10, 2026 at 11:23:27AM +0800, Zhao Liu wrote:
> > Hi,
> > 
> > This is the v2 trying to introduce property flags to detect user's
> > property setting (from CLI/QMP/HMP). I dropped RFC tag since previous
> > RFC v1 [1].
> 
> This says what the series is proposing, but IMHO what is more important
> here is explaining why this either desirable or appropriate to add as
> general facility in QOM.
> 
> The idea that code should take different action for a given fixed value,
> based on whether the value was set by the user, or left on the default,
> makes me very uncomfortable.
> 
> There have been a number of situations where something that was initially 
> a boolean flag, actually needed to be a tri-state instead, to provide
> semantics like "On", "Off", "Auto".

But "auto" is exactly a property specific way to work around this.
With this, we could allow "auto" for any property (except strings I
guess) without per property code.


> This "user set" flag could support such behaviour indirectly, but since
> "user set" is an internal concept we'd still be only exposing a boolean
> externally, while using a tri-state internally. That does not give the
> full flexibility of a tri-state, because internally if we wanted to
> have the default to be "yes", it offers no way for the mgmt app to
> put it back to "auto".

I do not get it. Of course user set is an external concept.
It is user controllable!


> For properties that are not booleans, it is much less obvious to me
> whether we actually need a distinct "not set" concept at all.
> 
> 
> So overall, at a conceptual level, I don't think that QOM should care
> about /how/ a value came to be set. It should have no direct awareness
> of the "user input", rather it just represents the configuration of the
> system at a given point in time,  however that came to pass.
> 
> 
> With regards,
> Daniel
> -- 
> |: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
> |: https://libvirt.org         -o-            https://fstop138.berrange.com :|
> |: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



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

* Re: [PATCH v2 00/21] qom: introduce property flags to track external user input
  2026-02-10 10:44   ` Michael S. Tsirkin
@ 2026-02-10 11:00     ` Daniel P. Berrangé
  2026-02-10 15:00       ` BALATON Zoltan
  0 siblings, 1 reply; 68+ messages in thread
From: Daniel P. Berrangé @ 2026-02-10 11:00 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Zhao Liu, Paolo Bonzini, Eduardo Habkost, Markus Armbruster,
	Thomas Huth, Igor Mammedov, Philippe Mathieu-Daudé,
	Richard Henderson, Peter Maydell, BALATON Zoltan,
	Mark Cave-Ayland, Pierrick Bouvier, Zide Chen, Dapeng Mi,
	qemu-devel, devel

On Tue, Feb 10, 2026 at 05:44:50AM -0500, Michael S. Tsirkin wrote:
> On Tue, Feb 10, 2026 at 10:12:38AM +0000, Daniel P. Berrangé wrote:
> > On Tue, Feb 10, 2026 at 11:23:27AM +0800, Zhao Liu wrote:
> > > Hi,
> > > 
> > > This is the v2 trying to introduce property flags to detect user's
> > > property setting (from CLI/QMP/HMP). I dropped RFC tag since previous
> > > RFC v1 [1].
> > 
> > This says what the series is proposing, but IMHO what is more important
> > here is explaining why this either desirable or appropriate to add as
> > general facility in QOM.
> > 
> > The idea that code should take different action for a given fixed value,
> > based on whether the value was set by the user, or left on the default,
> > makes me very uncomfortable.
> > 
> > There have been a number of situations where something that was initially 
> > a boolean flag, actually needed to be a tri-state instead, to provide
> > semantics like "On", "Off", "Auto".
> 
> But "auto" is exactly a property specific way to work around this.
> With this, we could allow "auto" for any property (except strings I
> guess) without per property code.
> 
> 
> > This "user set" flag could support such behaviour indirectly, but since
> > "user set" is an internal concept we'd still be only exposing a boolean
> > externally, while using a tri-state internally. That does not give the
> > full flexibility of a tri-state, because internally if we wanted to
> > have the default to be "yes", it offers no way for the mgmt app to
> > put it back to "auto".
> 
> I do not get it. Of course user set is an external concept.
> It is user controllable!

If a property is modelled as a tri-state today the user can explicitly
request any of the three values

  -object  foo,prop=on
  -object  foo,prop=off
  -object  foo,prop=auto

If a property is modelled as a boolean, and we have this new internal
"user set" flag to represent the "auto" scenario, the user can only
do

  -object  foo,prop=on
  -object  foo,prop=off

we're missing the ability to explicitly request the "auto" value,
which could be needed if we decide the internal default should be
either "on" or "off".

This "user default" flag concept is special casing support for
tri-states in a way that is worse than what we can already do in
QAPI. That feels like a mistake / bad path to go down to me.

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



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

* Re: [PATCH v2 03/21] qom/object: factor out object_class_property_try_add()
  2026-02-10  3:23 ` [PATCH v2 03/21] qom/object: factor out object_class_property_try_add() Zhao Liu
@ 2026-02-10 14:41   ` BALATON Zoltan
  2026-02-11  7:14     ` Zhao Liu
  0 siblings, 1 reply; 68+ messages in thread
From: BALATON Zoltan @ 2026-02-10 14:41 UTC (permalink / raw)
  To: Zhao Liu
  Cc: Paolo Bonzini, Daniel P . Berrangé, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé, Richard Henderson, Peter Maydell,
	Michael S . Tsirkin, Mark Cave-Ayland, Pierrick Bouvier,
	Zide Chen, Dapeng Mi, qemu-devel, devel

On Tue, 10 Feb 2026, Zhao Liu wrote:
> Similar to object_property_try_add(), factor out
> object_class_property_try_add().
>
> This allows adding more arguments to the core implementation without
> changing the signature of object_class_property_add(), avoiding the
> need to modify the extensive number of callers distributed throughout
> the code tree.
>
> While at it, add documentation for these functions.
>
> Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
> ---
> include/qom/object.h | 56 ++++++++++++++++++++++++++++++++++++++++++++
> qom/object.c         | 34 ++++++++++++++++++++-------
> 2 files changed, 82 insertions(+), 8 deletions(-)
>
> diff --git a/include/qom/object.h b/include/qom/object.h
> index 05706d4d7e3a..060db136988b 100644
> --- a/include/qom/object.h
> +++ b/include/qom/object.h
> @@ -1147,6 +1147,62 @@ ObjectProperty *object_property_add(Object *obj, const char *name,
>
> void object_property_del(Object *obj, const char *name);
>
> +/**
> + * object_class_property_try_add:

This is renamed two patches later so maybe should be named like that here 
and drop the renaming patch.

Regards,
BALATON Zoltan


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

* Re: [PATCH v2 07/21] qom/object: introduce user interaction flags for properties
  2026-02-10  3:23 ` [PATCH v2 07/21] qom/object: introduce user interaction flags for properties Zhao Liu
  2026-02-10  9:49   ` Daniel P. Berrangé
@ 2026-02-10 14:44   ` BALATON Zoltan
  2026-02-11  7:22     ` Zhao Liu
  1 sibling, 1 reply; 68+ messages in thread
From: BALATON Zoltan @ 2026-02-10 14:44 UTC (permalink / raw)
  To: Zhao Liu
  Cc: Paolo Bonzini, Daniel P . Berrangé, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé, Richard Henderson, Peter Maydell,
	Michael S . Tsirkin, Mark Cave-Ayland, Pierrick Bouvier,
	Zide Chen, Dapeng Mi, qemu-devel, devel

On Tue, 10 Feb 2026, Zhao Liu wrote:
> Introduce three new flags to `ObjectPropertyFlags` to better manage
> property interactions with external users (CLI, QMP, HMP):
>
> 1. OBJ_PROP_FLAG_USER_SET:
>   Marks a property as having been modified by an external user.
>
>   This flag is designed to be "sticky": once set, it persists even if
>   the property value is subsequently overwritten by internal logic.
>   It allows the QEMU system to distinguish user intent.
>
>   The advantage of this design is that it is not needed to manually
>   clear the USER_SET flag on every internal write. This simplifies the
>   logic and decouples flag management from the current property setting
>   path (object_property_set()).
>
>   This is chosen over a strict "current origin" approach (where
>   internal writes would clear the flag) for a practical reason: QEMU
>   code often modifies underlying struct fields (which are defined as
>   properties) directly, bypassing the property API entirely. This makes
>   it impossible to "accurately" track whether the *current* value truly
>   comes from the user. Therefore, a sticky "user touched this" flag is
>   the only meaningful and robust solution.
>
> 2. OBJ_PROP_FLAG_DEPRECATED:
>   Marks a property as deprecated.
>
> 3. OBJ_PROP_FLAG_INTERNAL:
>   Marks a property as internal-only, disallowing external user access.
>
> Additionally, update object_property_set_flags() to implement the
> enforcement logic. When a property is flagged with
> OBJ_PROP_FLAG_USER_SET:
> - If the property is also marked OBJ_PROP_FLAG_DEPRECATED, report a
>   warning.
> - If the property is also marked OBJ_PROP_FLAG_INTERNAL, raise an error
>   and stop the operation.
>
> Suggested-by: Igor Mammedov <imammedo@redhat.com>
> Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
> ---
> include/qom/object.h | 24 ++++++++++++++++++++++++
> qom/object.c         | 15 +++++++++++++++
> 2 files changed, 39 insertions(+)
>
> diff --git a/include/qom/object.h b/include/qom/object.h
> index 856b12e7289c..1b77429aa28b 100644
> --- a/include/qom/object.h
> +++ b/include/qom/object.h
> @@ -109,6 +109,30 @@ typedef enum {
>      * will automatically add a getter and a setter to this property.
>      */
>     OBJ_PROP_FLAG_READWRITE = (OBJ_PROP_FLAG_READ | OBJ_PROP_FLAG_WRITE),
> +    /*
> +     * The property was explicitly set by an external user.
> +     *
> +     * This flag is set whenever the property is modified via external interfaces
> +     * (CLI, QMP, HMP). It allows internal code to distinguish whether the
> +     * property has been modified by the user.
> +     *
> +     * Once set, this flag persists even if the property value is subsequently
> +     * overwritten by internal logic. It is NOT automatically cleared and must
> +     * be explicitly cleared using object_property_clear_flags().
> +     */
> +    OBJ_PROP_FLAG_USER_SET = BIT(2),

As this isn't strictly for user set maybe jusr call it 
OBJ_PROP_FLAG_EXTERNAL? (Can be set by external management application or 
global compat prop in later patches so user set is not quite right name,)


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

* Re: [PATCH v2 00/21] qom: introduce property flags to track external user input
  2026-02-10 11:00     ` Daniel P. Berrangé
@ 2026-02-10 15:00       ` BALATON Zoltan
  0 siblings, 0 replies; 68+ messages in thread
From: BALATON Zoltan @ 2026-02-10 15:00 UTC (permalink / raw)
  To: Daniel P. Berrangé
  Cc: Michael S. Tsirkin, Zhao Liu, Paolo Bonzini, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé, Richard Henderson, Peter Maydell,
	Mark Cave-Ayland, Pierrick Bouvier, Zide Chen, Dapeng Mi,
	qemu-devel, devel

[-- Attachment #1: Type: text/plain, Size: 3078 bytes --]

On Tue, 10 Feb 2026, Daniel P. Berrangé wrote:
> On Tue, Feb 10, 2026 at 05:44:50AM -0500, Michael S. Tsirkin wrote:
>> On Tue, Feb 10, 2026 at 10:12:38AM +0000, Daniel P. Berrangé wrote:
>>> On Tue, Feb 10, 2026 at 11:23:27AM +0800, Zhao Liu wrote:
>>>> Hi,
>>>>
>>>> This is the v2 trying to introduce property flags to detect user's
>>>> property setting (from CLI/QMP/HMP). I dropped RFC tag since previous
>>>> RFC v1 [1].
>>>
>>> This says what the series is proposing, but IMHO what is more important
>>> here is explaining why this either desirable or appropriate to add as
>>> general facility in QOM.
>>>
>>> The idea that code should take different action for a given fixed value,
>>> based on whether the value was set by the user, or left on the default,
>>> makes me very uncomfortable.
>>>
>>> There have been a number of situations where something that was initially
>>> a boolean flag, actually needed to be a tri-state instead, to provide
>>> semantics like "On", "Off", "Auto".
>>
>> But "auto" is exactly a property specific way to work around this.
>> With this, we could allow "auto" for any property (except strings I
>> guess) without per property code.
>>
>>
>>> This "user set" flag could support such behaviour indirectly, but since
>>> "user set" is an internal concept we'd still be only exposing a boolean
>>> externally, while using a tri-state internally. That does not give the
>>> full flexibility of a tri-state, because internally if we wanted to
>>> have the default to be "yes", it offers no way for the mgmt app to
>>> put it back to "auto".
>>
>> I do not get it. Of course user set is an external concept.
>> It is user controllable!
>
> If a property is modelled as a tri-state today the user can explicitly
> request any of the three values
>
>  -object  foo,prop=on
>  -object  foo,prop=off
>  -object  foo,prop=auto
>
> If a property is modelled as a boolean, and we have this new internal
> "user set" flag to represent the "auto" scenario, the user can only
> do
>
>  -object  foo,prop=on
>  -object  foo,prop=off
>
> we're missing the ability to explicitly request the "auto" value,
> which could be needed if we decide the internal default should be
> either "on" or "off".

In this case the auto setting would be not setting the property at all to 
any value by the user.

> This "user default" flag concept is special casing support for
> tri-states in a way that is worse than what we can already do in
> QAPI. That feels like a mistake / bad path to go down to me.

I also don't really like the USER_SET name so commented to rename to 
EXTERNAL but thinking more do we need both EXTERNAL/USER_SET and INTERNAL? 
One of the two would be the default behaviour for untagged properties so 
maybe we only need to flag INTERNAL to omit them from introspection and 
user setting but don't need to touch normal user settable properties 
(apart from adding deprecarion_message that also replaces DEPRECATED flag. 
But I don't have clear idea or opinion on this so these are more questions 
than suggestions.

Regards,
BALATON Zoltan

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

* Re: [PATCH v2 00/21] qom: introduce property flags to track external user input
  2026-02-10 15:28   ` Zhao Liu
@ 2026-02-10 15:16     ` BALATON Zoltan
  2026-02-11  7:24       ` Zhao Liu
  2026-02-10 15:41     ` Daniel P. Berrangé
  1 sibling, 1 reply; 68+ messages in thread
From: BALATON Zoltan @ 2026-02-10 15:16 UTC (permalink / raw)
  To: Zhao Liu
  Cc: Daniel P. Berrangé, Paolo Bonzini, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé, Richard Henderson, Peter Maydell,
	Michael S . Tsirkin, Mark Cave-Ayland, Pierrick Bouvier,
	Zide Chen, Dapeng Mi, qemu-devel, devel

[-- Attachment #1: Type: text/plain, Size: 4417 bytes --]

On Tue, 10 Feb 2026, Zhao Liu wrote:
> On Tue, Feb 10, 2026 at 10:12:38AM +0000, Daniel P. Berrangé wrote:
>> Date: Tue, 10 Feb 2026 10:12:38 +0000
>> From: "Daniel P. Berrangé" <berrange@redhat.com>
>> Subject: Re: [PATCH v2 00/21] qom: introduce property flags to track
>>  external user input
>>
>> On Tue, Feb 10, 2026 at 11:23:27AM +0800, Zhao Liu wrote:
>>> Hi,
>>>
>>> This is the v2 trying to introduce property flags to detect user's
>>> property setting (from CLI/QMP/HMP). I dropped RFC tag since previous
>>> RFC v1 [1].
>>
>> This says what the series is proposing, but IMHO what is more important
>> here is explaining why this either desirable or appropriate to add as
>> general facility in QOM.
>
> Yes, sorry this cover letter I wrote is overly simplified.
>
> This series tries to control the property access against external user.
> USER_SET is the base to track external user's behavior, and DEPRECATED &
> INTERNAL flags provide different levels of access control.
>
> Though the DEPRECATED flag does not inherently restrict access, I think
> such a warning also serves as a form of control.
>
> The idea of restricting external access to properties is from previous
> discussions [*] about internal properties.
>
> [*]: How to mark internal properties:
>     https://lore.kernel.org/qemu-devel/2f526570-7ab0-479c-967c-b3f95f9f19e3@redhat.com/
>
> Since that disscussion, currently all properties expected to be
> "internal" have an “x-” prefix — while this approach can work, it clearly
> confuses the original meaning of “x-”, which actually means "unstable".
>
> Therefore, I think the optimal approach is to provide the capability to
> restrict external access to the property — that is, to implement the
> "true" internal property.
>
> Based on this, it seems impossible to implement an internal property
> without tracking user input in the QOM?
>
>> The idea that code should take different action for a given fixed value,
>> based on whether the value was set by the user, or left on the default,
>> makes me very uncomfortable.
>>
>> There have been a number of situations where something that was initially
>> a boolean flag, actually needed to be a tri-state instead, to provide
>> semantics like "On", "Off", "Auto".
>>
>> This "user set" flag could support such behaviour indirectly, but since
>> "user set" is an internal concept we'd still be only exposing a boolean
>> externally, while using a tri-state internally. That does not give the
>> full flexibility of a tri-state, because internally if we wanted to
>> have the default to be "yes", it offers no way for the mgmt app to
>> put it back to "auto".
>>
>> For properties that are not booleans, it is much less obvious to me
>> whether we actually need a distinct "not set" concept at all.
>
> USER_SET primarily serves the INTERNAL and DEPRECATED flags. However,
> its another function is to indicates whether the external user has
> touched the property.
>
> But, Hmm, I think "auto" and USER_SET don't have conflict?
>
> IIUC, "auto" means the user requests that QEMU make the decision itself.
> However, just like my patch 19 cleanup of “lbr-fmt”, that property
> explicitly requires users to provide a valid value. Even we have "auto"
> for uint64, "auto" can't address this case.
>
> Similarly, the x86 CPU's topology IDs (used for hotplug) - "thread-id"/
> "core-id"/"module-id"..., also require the user to set valid and accurate
> values; they cannot be replaced with "auto".
>
> These existing cases all check user input for magic numbers. I hope to
> simplify these existing logic using USER_SET.
>
>> So overall, at a conceptual level, I don't think that QOM should care
>> about /how/ a value came to be set. It should have no direct awareness
>> of the "user input", rather it just represents the configuration of the
>> system at a given point in time,  however that came to pass.
>
> I also think the ideal situation is not to distinguish between external
> and internal - however, exposing properties to external users makes code
> evolution painful...

So another way could be to not use properties for internal settings but 
add another set of internal properties for those. These could be set the 
same way but stored in a different hash table and not get mixed with 
introspectable and user changable properties. But maybe that would be too 
much refactoring.

Regards,
BALATON Zoltan

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

* Re: [PATCH v2 00/21] qom: introduce property flags to track external user input
  2026-02-10 10:12 ` [PATCH v2 00/21] qom: introduce property flags to track external user input Daniel P. Berrangé
  2026-02-10 10:44   ` Michael S. Tsirkin
@ 2026-02-10 15:28   ` Zhao Liu
  2026-02-10 15:16     ` BALATON Zoltan
  2026-02-10 15:41     ` Daniel P. Berrangé
  1 sibling, 2 replies; 68+ messages in thread
From: Zhao Liu @ 2026-02-10 15:28 UTC (permalink / raw)
  To: Daniel P. Berrangé
  Cc: Paolo Bonzini, Eduardo Habkost, Markus Armbruster, Thomas Huth,
	Igor Mammedov, Philippe Mathieu-Daudé, Richard Henderson,
	Peter Maydell, Michael S . Tsirkin, BALATON Zoltan,
	Mark Cave-Ayland, Pierrick Bouvier, Zide Chen, Dapeng Mi,
	qemu-devel, devel, Zhao Liu

Hi Daniel,

On Tue, Feb 10, 2026 at 10:12:38AM +0000, Daniel P. Berrangé wrote:
> Date: Tue, 10 Feb 2026 10:12:38 +0000
> From: "Daniel P. Berrangé" <berrange@redhat.com>
> Subject: Re: [PATCH v2 00/21] qom: introduce property flags to track
>  external user input
> 
> On Tue, Feb 10, 2026 at 11:23:27AM +0800, Zhao Liu wrote:
> > Hi,
> > 
> > This is the v2 trying to introduce property flags to detect user's
> > property setting (from CLI/QMP/HMP). I dropped RFC tag since previous
> > RFC v1 [1].
> 
> This says what the series is proposing, but IMHO what is more important
> here is explaining why this either desirable or appropriate to add as
> general facility in QOM.

Yes, sorry this cover letter I wrote is overly simplified.

This series tries to control the property access against external user.
USER_SET is the base to track external user's behavior, and DEPRECATED &
INTERNAL flags provide different levels of access control.

Though the DEPRECATED flag does not inherently restrict access, I think
such a warning also serves as a form of control.

The idea of restricting external access to properties is from previous
discussions [*] about internal properties.

[*]: How to mark internal properties:
     https://lore.kernel.org/qemu-devel/2f526570-7ab0-479c-967c-b3f95f9f19e3@redhat.com/

Since that disscussion, currently all properties expected to be
"internal" have an “x-” prefix — while this approach can work, it clearly
confuses the original meaning of “x-”, which actually means "unstable".

Therefore, I think the optimal approach is to provide the capability to
restrict external access to the property — that is, to implement the
"true" internal property.

Based on this, it seems impossible to implement an internal property
without tracking user input in the QOM?

> The idea that code should take different action for a given fixed value,
> based on whether the value was set by the user, or left on the default,
> makes me very uncomfortable.
> 
> There have been a number of situations where something that was initially 
> a boolean flag, actually needed to be a tri-state instead, to provide
> semantics like "On", "Off", "Auto".
> 
> This "user set" flag could support such behaviour indirectly, but since
> "user set" is an internal concept we'd still be only exposing a boolean
> externally, while using a tri-state internally. That does not give the
> full flexibility of a tri-state, because internally if we wanted to
> have the default to be "yes", it offers no way for the mgmt app to
> put it back to "auto".
> 
> For properties that are not booleans, it is much less obvious to me
> whether we actually need a distinct "not set" concept at all.

USER_SET primarily serves the INTERNAL and DEPRECATED flags. However,
its another function is to indicates whether the external user has
touched the property.

But, Hmm, I think "auto" and USER_SET don't have conflict?

IIUC, "auto" means the user requests that QEMU make the decision itself.
However, just like my patch 19 cleanup of “lbr-fmt”, that property
explicitly requires users to provide a valid value. Even we have "auto"
for uint64, "auto" can't address this case.

Similarly, the x86 CPU's topology IDs (used for hotplug) - "thread-id"/
"core-id"/"module-id"..., also require the user to set valid and accurate
values; they cannot be replaced with "auto".

These existing cases all check user input for magic numbers. I hope to
simplify these existing logic using USER_SET.

> So overall, at a conceptual level, I don't think that QOM should care
> about /how/ a value came to be set. It should have no direct awareness
> of the "user input", rather it just represents the configuration of the
> system at a given point in time,  however that came to pass.

I also think the ideal situation is not to distinguish between external
and internal - however, exposing properties to external users makes code
evolution painful...

Thanks,
Zhao



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

* Re: [PATCH v2 00/21] qom: introduce property flags to track external user input
  2026-02-10 15:28   ` Zhao Liu
  2026-02-10 15:16     ` BALATON Zoltan
@ 2026-02-10 15:41     ` Daniel P. Berrangé
  2026-02-11  7:06       ` Zhao Liu
  1 sibling, 1 reply; 68+ messages in thread
From: Daniel P. Berrangé @ 2026-02-10 15:41 UTC (permalink / raw)
  To: Zhao Liu
  Cc: Paolo Bonzini, Eduardo Habkost, Markus Armbruster, Thomas Huth,
	Igor Mammedov, Philippe Mathieu-Daudé, Richard Henderson,
	Peter Maydell, Michael S . Tsirkin, BALATON Zoltan,
	Mark Cave-Ayland, Pierrick Bouvier, Zide Chen, Dapeng Mi,
	qemu-devel, devel

On Tue, Feb 10, 2026 at 11:28:07PM +0800, Zhao Liu wrote:
> Hi Daniel,
> 
> On Tue, Feb 10, 2026 at 10:12:38AM +0000, Daniel P. Berrangé wrote:
> > Date: Tue, 10 Feb 2026 10:12:38 +0000
> > From: "Daniel P. Berrangé" <berrange@redhat.com>
> > Subject: Re: [PATCH v2 00/21] qom: introduce property flags to track
> >  external user input
> > 
> > On Tue, Feb 10, 2026 at 11:23:27AM +0800, Zhao Liu wrote:
> > > Hi,
> > > 
> > > This is the v2 trying to introduce property flags to detect user's
> > > property setting (from CLI/QMP/HMP). I dropped RFC tag since previous
> > > RFC v1 [1].
> > 
> > This says what the series is proposing, but IMHO what is more important
> > here is explaining why this either desirable or appropriate to add as
> > general facility in QOM.
> 
> Yes, sorry this cover letter I wrote is overly simplified.
> 
> This series tries to control the property access against external user.
> USER_SET is the base to track external user's behavior, and DEPRECATED &
> INTERNAL flags provide different levels of access control.
> 
> Though the DEPRECATED flag does not inherently restrict access, I think
> such a warning also serves as a form of control.
> 
> The idea of restricting external access to properties is from previous
> discussions [*] about internal properties.
> 
> [*]: How to mark internal properties:
>      https://lore.kernel.org/qemu-devel/2f526570-7ab0-479c-967c-b3f95f9f19e3@redhat.com/
> 
> Since that disscussion, currently all properties expected to be
> "internal" have an “x-” prefix — while this approach can work, it clearly
> confuses the original meaning of “x-”, which actually means "unstable".
> 
> Therefore, I think the optimal approach is to provide the capability to
> restrict external access to the property — that is, to implement the
> "true" internal property.
> 
> Based on this, it seems impossible to implement an internal property
> without tracking user input in the QOM?

So the main thing that pushes us into using QOM for internal properties
is the machine type compatibility code. eg where we bulk set stuff using

    compat_props_add(m->compat_props, hw_compat_7_0, hw_compat_7_0_len);
    compat_props_add(m->compat_props, pc_compat_7_0, pc_compat_7_0_len);

That logic is all QOM based. Using QOM isn't our exclusive approach, as
we have machine types sometimes setting object fields directly. eg

  static void pc_i440fx_machine_7_0_options(MachineClass *m)
  {
    PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
    pc_i440fx_machine_7_1_options(m);
    pcmc->enforce_amd_1tb_hole = false;
    compat_props_add(m->compat_props, hw_compat_7_0, hw_compat_7_0_len);
    compat_props_add(m->compat_props, pc_compat_7_0, pc_compat_7_0_len);
  }

but that only works for properties against the machine type, not compat
properties against devices, since we have no direct access to the other
classes/instances.


If we want to be able to control hardware compat, without exposing
something as a user facing tunable, then internal-only QOM props seems
inescapable.

I do still wonder if we genuinely need internal-only QOM props for
machine type compat ?

Whether using a public 'x-' prefixed property or an internal only
property, we're constrained by the need to retain the behaviour
semantics for as long as the machine type exists. I don't see an
internal only property giving us significantly more freedom here.
We can already rename a 'x-' property however we want with no
notice, as long as the machine type doesn't change behaviour.




> > The idea that code should take different action for a given fixed value,
> > based on whether the value was set by the user, or left on the default,
> > makes me very uncomfortable.
> > 
> > There have been a number of situations where something that was initially 
> > a boolean flag, actually needed to be a tri-state instead, to provide
> > semantics like "On", "Off", "Auto".
> > 
> > This "user set" flag could support such behaviour indirectly, but since
> > "user set" is an internal concept we'd still be only exposing a boolean
> > externally, while using a tri-state internally. That does not give the
> > full flexibility of a tri-state, because internally if we wanted to
> > have the default to be "yes", it offers no way for the mgmt app to
> > put it back to "auto".
> > 
> > For properties that are not booleans, it is much less obvious to me
> > whether we actually need a distinct "not set" concept at all.
> 
> USER_SET primarily serves the INTERNAL and DEPRECATED flags. However,
> its another function is to indicates whether the external user has
> touched the property.
> 
> But, Hmm, I think "auto" and USER_SET don't have conflict?
> 
> IIUC, "auto" means the user requests that QEMU make the decision itself.
> However, just like my patch 19 cleanup of “lbr-fmt”, that property
> explicitly requires users to provide a valid value. Even we have "auto"
> for uint64, "auto" can't address this case.

I just meant "auto" as one possible "default" behaviour where a traditional
boolean was in use, not for all possible types. The right answer for a
default is  contextually dependent.

For a uint64, a default value would involve some  sentinal value, or it
could involve a pair of related properties. For example, we have

  host-phys-bits=on
  phys-bits=NNN

as a pair that work together, so you don't need a magic phys-bits value
to represent "use host value".

> Similarly, the x86 CPU's topology IDs (used for hotplug) - "thread-id"/
> "core-id"/"module-id"..., also require the user to set valid and accurate
> values; they cannot be replaced with "auto".

Again I wasn't suggestnig an "auto" value for every scenario, that was
just an example in a "bool" context. An ID value of "0" is a traditional
default for numeric values, which is fine assuming you don't need to
dinstinguish 0 as a valid value, from 0 as an invalid value needing user
input.

> I also think the ideal situation is not to distinguish between external
> and internal - however, exposing properties to external users makes code
> evolution painful...

I don't think it does. Code evolution is painful as long as the machine
type using the prop needs to exist with fixed semantics, whether it is
internal or public with x- prefix.

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



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

* Re: [PATCH v2 00/21] qom: introduce property flags to track external user input
  2026-02-10 15:41     ` Daniel P. Berrangé
@ 2026-02-11  7:06       ` Zhao Liu
  2026-02-11 11:18         ` Daniel P. Berrangé
  0 siblings, 1 reply; 68+ messages in thread
From: Zhao Liu @ 2026-02-11  7:06 UTC (permalink / raw)
  To: Daniel P. Berrangé
  Cc: Paolo Bonzini, Eduardo Habkost, Markus Armbruster, Thomas Huth,
	Igor Mammedov, Philippe Mathieu-Daudé, Richard Henderson,
	Peter Maydell, Michael S . Tsirkin, BALATON Zoltan,
	Mark Cave-Ayland, Pierrick Bouvier, Zide Chen, Dapeng Mi,
	qemu-devel, devel, Zhao Liu

> So the main thing that pushes us into using QOM for internal properties
> is the machine type compatibility code. eg where we bulk set stuff using
> 
>     compat_props_add(m->compat_props, hw_compat_7_0, hw_compat_7_0_len);
>     compat_props_add(m->compat_props, pc_compat_7_0, pc_compat_7_0_len);
> 
> That logic is all QOM based. Using QOM isn't our exclusive approach, as
> we have machine types sometimes setting object fields directly. eg
> 
>   static void pc_i440fx_machine_7_0_options(MachineClass *m)
>   {
>     PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
>     pc_i440fx_machine_7_1_options(m);
>     pcmc->enforce_amd_1tb_hole = false;
>     compat_props_add(m->compat_props, hw_compat_7_0, hw_compat_7_0_len);
>     compat_props_add(m->compat_props, pc_compat_7_0, pc_compat_7_0_len);
>   }
> 
> but that only works for properties against the machine type, not compat
> properties against devices, since we have no direct access to the other
> classes/instances.

Right, and setting fields directly is only possible for machine-level
state, not for device properties created dynamically during
realize/init. So QOM-based compat properties are indeed inescapable
for devices.

> If we want to be able to control hardware compat, without exposing
> something as a user facing tunable, then internal-only QOM props seems
> inescapable.

Agreed.

> I do still wonder if we genuinely need internal-only QOM props for
> machine type compat ?
> 
> Whether using a public 'x-' prefixed property or an internal only
> property, we're constrained by the need to retain the behaviour
> semantics for as long as the machine type exists. I don't see an
> internal only property giving us significantly more freedom here.
> We can already rename a 'x-' property however we want with no
> notice, as long as the machine type doesn't change behaviour.

Hmm, I think x- prefix is already semantically overloaded. Looking at
the current codebase, x- carries two very different meanings:

 - "unstable but user-facing feature" - e.g. x-vga, x-igd-opregion
   (documented in docs/igd-assign.rst with user-facing examples),
   x-migration-multifd-transfer (documented in
   docs/devel/vfio-migration.rst).

 - "internal compat switch to fix bug" - e.g. x-buggy-eim,
   x-pci-express-writeable-slt-bug.

These two categories have fundamentally different contracts - the
former should be settable by users, the latter should not. But today,
nothing prevents a user from writing something like:

"-device intel-iommu,x-buggy-eim=false"

QEMU will happily accept it.

An INTERNAL flag can reject this at property set time with a clear
error.

And management tools use qom-list-properties to discover settable
properties (though this series hasn't covered this but it's
possible) - they currently have no way to distinguish "x-vga"
(user-facing) from "x-pci-express-writeable-slt-bug" (internal
bug-compat). An INTERNAL flag could give a clean boundary for
introspection.

> I don't think it does. Code evolution is painful as long as the machine
> type using the prop needs to exist with fixed semantics, whether it is
> internal or public with x- prefix.

I agree the machine type lifetime constraint doesn't change.

But experimental x- or normal (external) properties are by default
exposed to users, allowing them to set values via -device or other
entry points. This effectively treats the property as an API.

Once it becomes an API, any modification to the property must consider
whether there are external dependencies. Just as with the series
(removing v2.6 & v2.7 PC machines) I referenced in cover letter,
justifying whether a property can be directly removed becomes very
complicated and unpredictable - some are definitely in use, while some
are merely "potentially" in use.

Let me take the recently added compatibility properties as another
example - they are all x86 CPU properties:
 * x-l1-cache-per-thread: it's useful for external user to tune L1
   cache topology (though now we have smp-cache, before smp-cache,
   it was useful).
 * x-consistent-cache: this actually is a fix and should be
   internal-only.

While both are compatibility properties and share the x- prefix,
their purposes differ, reflecting the confusion around x- prefix I
mentioned earlier. It's also expected that distinct strategies will
be required when genuinely considering the removal of these two
categories of properties in the future. :-(

So the advantage of distinguishing between internal and external
properties is that modifications or even removal of internal
properties can be done directly without worrying about external
consumers. External properties, as potential API objects, require
explicit deprecation before they can be dropped.

Although it doesn't directly help with modifying existing properties,
any newly added internal property won't increase such API concerns
going forward.

So I'm not positioning INTERNAL as a replacement for x- prefix -
rather, it complements x- by providing runtime enforcement, clean
introspection, and preventing accidental ABI commitment that a naming
convention alone cannot. x- remains appropriate for
unstable-but-user-facing features.

Thanks,
Zhao



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

* Re: [PATCH v2 14/21] hw/core/qdev-properties: allow qdev properties accept flags
  2026-02-10  9:41   ` Peter Krempa
@ 2026-02-11  7:10     ` Zhao Liu
  0 siblings, 0 replies; 68+ messages in thread
From: Zhao Liu @ 2026-02-11  7:10 UTC (permalink / raw)
  To: Peter Krempa
  Cc: Paolo Bonzini, Daniel P . Berrang�, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daud�, Richard Henderson, Peter Maydell,
	Michael S . Tsirkin, BALATON Zoltan, Mark Cave-Ayland,
	Pierrick Bouvier, Zide Chen, Dapeng Mi, qemu-devel, devel,
	Zhao Liu

On Tue, Feb 10, 2026 at 10:41:50AM +0100, Peter Krempa wrote:
> Date: Tue, 10 Feb 2026 10:41:50 +0100
> From: Peter Krempa <pkrempa@redhat.com>
> Subject: Re: [PATCH v2 14/21] hw/core/qdev-properties: allow qdev
>  properties accept flags
> 
> On Tue, Feb 10, 2026 at 11:23:41 +0800, Zhao Liu wrote:
> > Update qdev property interfaces (qdev_property_add_static() and
> > qdev_class_add_property()) to accept and pass 'ObjectPropertyFlags'.
> > This enables marking qdev properties with flags such as DEPRECATED or
> > INTERNAL.
> > 
> > To facilitate this at the definition level, extend the boolean and
> > uint8_t property macros (as the examples) to accept variable arguments
> > (VA_ARGS). This allows callers to optionally specify flags in the
> > property definition.
> > 
> > Example:
> > 
> > DEFINE_PROP_UINT8("version", IOAPICCommonState, version, IOAPIC_VER_DEF,
> >                   .flags = OBJECT_PROPERTY_DEPRECATED),
> 
> Is there a plan to expose at least the _DEPRECATED property to be
> introspectable (e.g. via qom-list-properties or device-list-properties)
> ?
> 
> In libvirt we try to stay proactive about adapting to deprecations and
> this would allow our test-suite to detect deprecations programmaticaly
> similarly to how we detect deprecations via query-qmp-schema. Although
> with the current patchset there doesn't seem to be anything that libvirt
> would need to adapt to.

Yes, this is the thing not yet covered by the current Series. I think
the ultimate goal is to use the INTERNAL flag to filter properties that
should not be exposed to libvirt, and to check against the DEPRECATED
flag to make it possible to alert libvirt of their deprecated status.

Thanks,
Zhao



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

* Re: [PATCH v2 03/21] qom/object: factor out object_class_property_try_add()
  2026-02-10 14:41   ` BALATON Zoltan
@ 2026-02-11  7:14     ` Zhao Liu
  0 siblings, 0 replies; 68+ messages in thread
From: Zhao Liu @ 2026-02-11  7:14 UTC (permalink / raw)
  To: BALATON Zoltan
  Cc: Paolo Bonzini, Daniel P . Berrang�, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daud�, Richard Henderson, Peter Maydell,
	Michael S . Tsirkin, Mark Cave-Ayland, Pierrick Bouvier,
	Zide Chen, Dapeng Mi, qemu-devel, devel, Zhao Liu

On Tue, Feb 10, 2026 at 03:41:48PM +0100, BALATON Zoltan wrote:
> Date: Tue, 10 Feb 2026 15:41:48 +0100
> From: BALATON Zoltan <balaton@eik.bme.hu>
> Subject: Re: [PATCH v2 03/21] qom/object: factor out
>  object_class_property_try_add()
> 
> On Tue, 10 Feb 2026, Zhao Liu wrote:
> > Similar to object_property_try_add(), factor out
> > object_class_property_try_add().
> > 
> > This allows adding more arguments to the core implementation without
> > changing the signature of object_class_property_add(), avoiding the
> > need to modify the extensive number of callers distributed throughout
> > the code tree.
> > 
> > While at it, add documentation for these functions.
> > 
> > Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
> > ---
> > include/qom/object.h | 56 ++++++++++++++++++++++++++++++++++++++++++++
> > qom/object.c         | 34 ++++++++++++++++++++-------
> > 2 files changed, 82 insertions(+), 8 deletions(-)
> > 
> > diff --git a/include/qom/object.h b/include/qom/object.h
> > index 05706d4d7e3a..060db136988b 100644
> > --- a/include/qom/object.h
> > +++ b/include/qom/object.h
> > @@ -1147,6 +1147,62 @@ ObjectProperty *object_property_add(Object *obj, const char *name,
> > 
> > void object_property_del(Object *obj, const char *name);
> > 
> > +/**
> > + * object_class_property_try_add:
> 
> This is renamed two patches later so maybe should be named like that here
> and drop the renaming patch.

Indeed, these two patches seem trivial, but I still prefer to separate the
renaming patch. Reviewing patches related to renaming is always
straightforward and maybe relaxing. :)

Thanks,
Zhao



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

* Re: [PATCH v2 07/21] qom/object: introduce user interaction flags for properties
  2026-02-10 14:44   ` BALATON Zoltan
@ 2026-02-11  7:22     ` Zhao Liu
  0 siblings, 0 replies; 68+ messages in thread
From: Zhao Liu @ 2026-02-11  7:22 UTC (permalink / raw)
  To: BALATON Zoltan
  Cc: Paolo Bonzini, Daniel P . Berrang�, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daud�, Richard Henderson, Peter Maydell,
	Michael S . Tsirkin, Mark Cave-Ayland, Pierrick Bouvier,
	Zide Chen, Dapeng Mi, qemu-devel, devel, Zhao Liu

Hi BALATON,

> > diff --git a/include/qom/object.h b/include/qom/object.h
> > index 856b12e7289c..1b77429aa28b 100644
> > --- a/include/qom/object.h
> > +++ b/include/qom/object.h
> > @@ -109,6 +109,30 @@ typedef enum {
> >      * will automatically add a getter and a setter to this property.
> >      */
> >     OBJ_PROP_FLAG_READWRITE = (OBJ_PROP_FLAG_READ | OBJ_PROP_FLAG_WRITE),
> > +    /*
> > +     * The property was explicitly set by an external user.
> > +     *
> > +     * This flag is set whenever the property is modified via external interfaces
> > +     * (CLI, QMP, HMP). It allows internal code to distinguish whether the
> > +     * property has been modified by the user.
> > +     *
> > +     * Once set, this flag persists even if the property value is subsequently
> > +     * overwritten by internal logic. It is NOT automatically cleared and must
> > +     * be explicitly cleared using object_property_clear_flags().
> > +     */
> > +    OBJ_PROP_FLAG_USER_SET = BIT(2),
> 
> As this isn't strictly for user set maybe jusr call it
> OBJ_PROP_FLAG_EXTERNAL? (Can be set by external management application or
> global compat prop in later patches so user set is not quite right name,)

This flag is dynamic - when external user touched a property via
CLI/HMP/QMP, then this flag will be set.

Even though later some QEMU internal logic re-set the property, this
flag is still there.

So, this flag means external user *has touched/set* the property.

Thanks,
Zhao




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

* Re: [PATCH v2 00/21] qom: introduce property flags to track external user input
  2026-02-10 15:16     ` BALATON Zoltan
@ 2026-02-11  7:24       ` Zhao Liu
  2026-02-11 11:28         ` BALATON Zoltan
  0 siblings, 1 reply; 68+ messages in thread
From: Zhao Liu @ 2026-02-11  7:24 UTC (permalink / raw)
  To: BALATON Zoltan
  Cc: Daniel P. Berrang�, Paolo Bonzini, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daud�, Richard Henderson, Peter Maydell,
	Michael S . Tsirkin, Mark Cave-Ayland, Pierrick Bouvier,
	Zide Chen, Dapeng Mi, qemu-devel, devel, Zhao Liu

> So another way could be to not use properties for internal settings but add
> another set of internal properties for those. These could be set the same
> way but stored in a different hash table and not get mixed with
> introspectable and user changable properties. But maybe that would be too
> much refactoring.

Yes, it may require adding interfaces similar to object_property_add/get/
set, which would need significant changes.

Thanks,
Zhao



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

* Re: [PATCH v2 14/21] hw/core/qdev-properties: allow qdev properties accept flags
  2026-02-10  9:56   ` Daniel P. Berrangé
@ 2026-02-11  7:30     ` Zhao Liu
  2026-02-11 16:58       ` Daniel P. Berrangé
  0 siblings, 1 reply; 68+ messages in thread
From: Zhao Liu @ 2026-02-11  7:30 UTC (permalink / raw)
  To: Daniel P. Berrangé
  Cc: Paolo Bonzini, Eduardo Habkost, Markus Armbruster, Thomas Huth,
	Igor Mammedov, Philippe Mathieu-Daudé, Richard Henderson,
	Peter Maydell, Michael S . Tsirkin, BALATON Zoltan,
	Mark Cave-Ayland, Pierrick Bouvier, Zide Chen, Dapeng Mi,
	qemu-devel, devel, Zhao Liu

On Tue, Feb 10, 2026 at 09:56:08AM +0000, Daniel P. Berrangé wrote:
> Date: Tue, 10 Feb 2026 09:56:08 +0000
> From: "Daniel P. Berrangé" <berrange@redhat.com>
> Subject: Re: [PATCH v2 14/21] hw/core/qdev-properties: allow qdev
>  properties accept flags
> 
> On Tue, Feb 10, 2026 at 11:23:41AM +0800, Zhao Liu wrote:
> > Update qdev property interfaces (qdev_property_add_static() and
> > qdev_class_add_property()) to accept and pass 'ObjectPropertyFlags'.
> > This enables marking qdev properties with flags such as DEPRECATED or
> > INTERNAL.
> > 
> > To facilitate this at the definition level, extend the boolean and
> > uint8_t property macros (as the examples) to accept variable arguments
> > (VA_ARGS). This allows callers to optionally specify flags in the
> > property definition.
> > 
> > Example:
> > 
> > DEFINE_PROP_UINT8("version", IOAPICCommonState, version, IOAPIC_VER_DEF,
> >                   .flags = OBJECT_PROPERTY_DEPRECATED),
> 
> In other places where we track deprecation in QEMU, we have not used
> a boolean flag. Instead we have used a "const char *deprecation_note"
> internally, which lets us provide a user facing message, to be printed
> out in the warn_report, informing them what to do instead (either the
> feature is entirely removed, or there is a better alternative). IMHO
> we should be following the same pattern for properties, as it is much
> more user friendly than just printing a totally generic message
> "XXXX is deprecated, stop using it" 

Yes, rich deprecation hint is better. I think this still depends on
USER_SET - distinguish internal/external or not :-(.

Since when we mark a property as deprecated, its code remains in the
code tree, and internal calls should not trigger warnings. Deprecation
hints are intended to reminder external users.

Thanks,
Zhao



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

* Re: [PATCH v2 07/21] qom/object: introduce user interaction flags for properties
  2026-02-10  9:58     ` Daniel P. Berrangé
@ 2026-02-11  8:19       ` Zhao Liu
  0 siblings, 0 replies; 68+ messages in thread
From: Zhao Liu @ 2026-02-11  8:19 UTC (permalink / raw)
  To: Daniel P. Berrangé
  Cc: Paolo Bonzini, Eduardo Habkost, Markus Armbruster, Thomas Huth,
	Igor Mammedov, Philippe Mathieu-Daudé, Richard Henderson,
	Peter Maydell, Michael S . Tsirkin, BALATON Zoltan,
	Mark Cave-Ayland, Pierrick Bouvier, Zide Chen, Dapeng Mi,
	qemu-devel, devel, Zhao Liu

> > > diff --git a/include/qom/object.h b/include/qom/object.h
> > > index 856b12e7289c..1b77429aa28b 100644
> > > --- a/include/qom/object.h
> > > +++ b/include/qom/object.h
> > > @@ -109,6 +109,30 @@ typedef enum {
> > >       * will automatically add a getter and a setter to this property.
> > >       */
> > >      OBJ_PROP_FLAG_READWRITE = (OBJ_PROP_FLAG_READ | OBJ_PROP_FLAG_WRITE),
> > > +    /*
> > > +     * The property was explicitly set by an external user.
> > > +     *
> > > +     * This flag is set whenever the property is modified via external interfaces
> > > +     * (CLI, QMP, HMP). It allows internal code to distinguish whether the
> > > +     * property has been modified by the user.
> > > +     *
> > > +     * Once set, this flag persists even if the property value is subsequently
> > > +     * overwritten by internal logic. It is NOT automatically cleared and must
> > > +     * be explicitly cleared using object_property_clear_flags().
> > > +     */
> > > +    OBJ_PROP_FLAG_USER_SET = BIT(2),
> > > +    /*
> > > +     * The property is deprecated and will be removed in the future version.
> > > +     *
> > > +     * Any setting to this property by the user will raise a deprecation warning.
> > > +     */
> > > +    OBJ_PROP_FLAG_DEPRECATED = BIT(3),
> > > +    /*
> > > +     * The property is internal only and cannot be set by the user.
> > > +     *
> > > +     * Any setting to this property by the user will raise an error.
> > > +     */
> > > +    OBJ_PROP_FLAG_INTERNAL = BIT(4),
> > >  } ObjectPropertyFlags;
> > 
> > I don't think this single enum design is very desirable, as it is mixing up
> > pieces of information with three distinct lifetimes / scopes.

In general, I treat all these flags as access control.
* OBJ_PROP_FLAD_{READ,WRITE,READWRITE} control read/write access -
  though I haven't done anything else, and I don't recheck against these
  flags when executing set/get accessors.

* OBJ_PROP_FLAG_{DEPRECATED,INTERNAL} are access restrictions for
  external users, from warning to error.

The above flags are initialized at property initialization stage.

* OBJ_PROP_FLAG_USER_SET - is a dynamic flag, which is set only when
  external user sets the property. It is used to check against
  OBJ_PROP_FLAG_{DEPRECATED,INTERNAL}.

In previous RFC [*], I split OBJ_PROP_FLAD_{READ,WRITE,READWRITE} from
other flags. But I think since they're all property flags, splitting
them up would just make things more fragmented.

[*]: https://lore.kernel.org/qemu-devel/20251202170502.3228625-2-zhao1.liu@intel.com/

> > The OBJ_PROP_FLAD_{READ,WRITE,READWRITE} values are scoped to the execution
> > of the property adder methods.
> > 
> > The OBJ_PROP_FLAG_{DEPRECATED,INTERNAL} values are scoped to the lifetime
> > of the class.
> >
> > The OBJ_PROP_FLAG_USER_SET value is scoped to the lifetime of the instance.

Hmm, I'm not sure about class/instance lifetime. All these flags are
attached to property and don't distinguish object class or object
instance.

 * Both object_class_property_add_full() and object_property_add_full
   could set flags.
 * But there're only object_property_{get,check,set,clear}_flags, w/o
   object_class level variants, since object_property_find() could
   search property of both class & instance.

> In fact, with my comment on the later patch, OBJ_PROP_FLAG_DEPRECATED should
> not be modelled as a boolean flag at all.  We need to record a const char*
> deprecation_note internally, so that warn_report can provide useful info
> to the user. We can turn that into a "bool deprecated" flag in the QAPI
> command response for querying properties.

Yes, I think that's good. If we could reach agreement on USER_SET at
least, I'll explore whether hints can be converted into QAPI flags,
since all of this ultimately relies on detecting user input.

In another point, the USER_SET detecting mechanism could be extended to
support several internal/deprecated mechanisms or features, so I think
it's useful...

Thanks,
Zhao



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

* Re: [PATCH v2 00/21] qom: introduce property flags to track external user input
  2026-02-11  7:06       ` Zhao Liu
@ 2026-02-11 11:18         ` Daniel P. Berrangé
  0 siblings, 0 replies; 68+ messages in thread
From: Daniel P. Berrangé @ 2026-02-11 11:18 UTC (permalink / raw)
  To: Zhao Liu
  Cc: Paolo Bonzini, Eduardo Habkost, Markus Armbruster, Thomas Huth,
	Igor Mammedov, Philippe Mathieu-Daudé, Richard Henderson,
	Peter Maydell, Michael S . Tsirkin, BALATON Zoltan,
	Mark Cave-Ayland, Pierrick Bouvier, Zide Chen, Dapeng Mi,
	qemu-devel, devel

On Wed, Feb 11, 2026 at 03:06:23PM +0800, Zhao Liu wrote:
> > So the main thing that pushes us into using QOM for internal properties
> > is the machine type compatibility code. eg where we bulk set stuff using
> > 
> >     compat_props_add(m->compat_props, hw_compat_7_0, hw_compat_7_0_len);
> >     compat_props_add(m->compat_props, pc_compat_7_0, pc_compat_7_0_len);
> > 
> > That logic is all QOM based. Using QOM isn't our exclusive approach, as
> > we have machine types sometimes setting object fields directly. eg
> > 
> >   static void pc_i440fx_machine_7_0_options(MachineClass *m)
> >   {
> >     PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
> >     pc_i440fx_machine_7_1_options(m);
> >     pcmc->enforce_amd_1tb_hole = false;
> >     compat_props_add(m->compat_props, hw_compat_7_0, hw_compat_7_0_len);
> >     compat_props_add(m->compat_props, pc_compat_7_0, pc_compat_7_0_len);
> >   }
> > 
> > but that only works for properties against the machine type, not compat
> > properties against devices, since we have no direct access to the other
> > classes/instances.
> 
> Right, and setting fields directly is only possible for machine-level
> state, not for device properties created dynamically during
> realize/init. So QOM-based compat properties are indeed inescapable
> for devices.
> 
> > If we want to be able to control hardware compat, without exposing
> > something as a user facing tunable, then internal-only QOM props seems
> > inescapable.
> 
> Agreed.
> 
> > I do still wonder if we genuinely need internal-only QOM props for
> > machine type compat ?
> > 
> > Whether using a public 'x-' prefixed property or an internal only
> > property, we're constrained by the need to retain the behaviour
> > semantics for as long as the machine type exists. I don't see an
> > internal only property giving us significantly more freedom here.
> > We can already rename a 'x-' property however we want with no
> > notice, as long as the machine type doesn't change behaviour.
> 
> Hmm, I think x- prefix is already semantically overloaded. Looking at
> the current codebase, x- carries two very different meanings:
> 
>  - "unstable but user-facing feature" - e.g. x-vga, x-igd-opregion
>    (documented in docs/igd-assign.rst with user-facing examples),
>    x-migration-multifd-transfer (documented in
>    docs/devel/vfio-migration.rst).
> 
>  - "internal compat switch to fix bug" - e.g. x-buggy-eim,
>    x-pci-express-writeable-slt-bug.
> 
> These two categories have fundamentally different contracts - the
> former should be settable by users, the latter should not. But today,
> nothing prevents a user from writing something like:
> 
> "-device intel-iommu,x-buggy-eim=false"
> 
> QEMU will happily accept it.

I don't see that as a bug neccessarily, but rather a feature. It
has let users enable bug fixes, without changing their machine
type. It has been useful when users report that a guest OS is
broken after a given machine type version, to be able to toggle
fixes individually.


> > I don't think it does. Code evolution is painful as long as the machine
> > type using the prop needs to exist with fixed semantics, whether it is
> > internal or public with x- prefix.
> 
> I agree the machine type lifetime constraint doesn't change.
> 
> But experimental x- or normal (external) properties are by default
> exposed to users, allowing them to set values via -device or other
> entry points. This effectively treats the property as an API.
> 
> Once it becomes an API, any modification to the property must consider
> whether there are external dependencies.

When a property is exposed with a "x-" prefix, that is saying we
do *NOT*  need to consider external dependencies.  We can remove
it at all any time, if QEMU has no internal usage left. We might
*choose* to consider external usage, but that is not requird.

Our only hard constraint is that the machine type version must
remain with the fixed behaviour.

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



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

* Re: [PATCH v2 00/21] qom: introduce property flags to track external user input
  2026-02-11  7:24       ` Zhao Liu
@ 2026-02-11 11:28         ` BALATON Zoltan
  2026-02-12 15:31           ` Zhao Liu
  0 siblings, 1 reply; 68+ messages in thread
From: BALATON Zoltan @ 2026-02-11 11:28 UTC (permalink / raw)
  To: Zhao Liu
  Cc: Daniel P. Berrang�, Paolo Bonzini, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daud�, Richard Henderson, Peter Maydell,
	Michael S . Tsirkin, Mark Cave-Ayland, Pierrick Bouvier,
	Zide Chen, Dapeng Mi, qemu-devel, devel

On Wed, 11 Feb 2026, Zhao Liu wrote:
>> So another way could be to not use properties for internal settings but add
>> another set of internal properties for those. These could be set the same
>> way but stored in a different hash table and not get mixed with
>> introspectable and user changable properties. But maybe that would be too
>> much refactoring.
>
> Yes, it may require adding interfaces similar to object_property_add/get/
> set, which would need significant changes.

Maybe not that part needs significant changes as you could still use a 
flag the same way adding a parameter to object_property_add/get/set to 
tell it should put the propery in the internal hash but then you need to 
add the other hash and maybe related changes. I don't know how much would 
those be but no new interface is needed just extending existing one as you 
did already.

Regards,
BALATON Zoltan


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

* Re: [PATCH v2 14/21] hw/core/qdev-properties: allow qdev properties accept flags
  2026-02-11  7:30     ` Zhao Liu
@ 2026-02-11 16:58       ` Daniel P. Berrangé
  2026-02-12 15:25         ` Zhao Liu
                           ` (2 more replies)
  0 siblings, 3 replies; 68+ messages in thread
From: Daniel P. Berrangé @ 2026-02-11 16:58 UTC (permalink / raw)
  To: Zhao Liu
  Cc: Paolo Bonzini, Eduardo Habkost, Markus Armbruster, Thomas Huth,
	Igor Mammedov, Philippe Mathieu-Daudé, Richard Henderson,
	Peter Maydell, Michael S . Tsirkin, BALATON Zoltan,
	Mark Cave-Ayland, Pierrick Bouvier, Zide Chen, Dapeng Mi,
	qemu-devel, devel

On Wed, Feb 11, 2026 at 03:30:06PM +0800, Zhao Liu wrote:
> On Tue, Feb 10, 2026 at 09:56:08AM +0000, Daniel P. Berrangé wrote:
> > Date: Tue, 10 Feb 2026 09:56:08 +0000
> > From: "Daniel P. Berrangé" <berrange@redhat.com>
> > Subject: Re: [PATCH v2 14/21] hw/core/qdev-properties: allow qdev
> >  properties accept flags
> > 
> > On Tue, Feb 10, 2026 at 11:23:41AM +0800, Zhao Liu wrote:
> > > Update qdev property interfaces (qdev_property_add_static() and
> > > qdev_class_add_property()) to accept and pass 'ObjectPropertyFlags'.
> > > This enables marking qdev properties with flags such as DEPRECATED or
> > > INTERNAL.
> > > 
> > > To facilitate this at the definition level, extend the boolean and
> > > uint8_t property macros (as the examples) to accept variable arguments
> > > (VA_ARGS). This allows callers to optionally specify flags in the
> > > property definition.
> > > 
> > > Example:
> > > 
> > > DEFINE_PROP_UINT8("version", IOAPICCommonState, version, IOAPIC_VER_DEF,
> > >                   .flags = OBJECT_PROPERTY_DEPRECATED),
> > 
> > In other places where we track deprecation in QEMU, we have not used
> > a boolean flag. Instead we have used a "const char *deprecation_note"
> > internally, which lets us provide a user facing message, to be printed
> > out in the warn_report, informing them what to do instead (either the
> > feature is entirely removed, or there is a better alternative). IMHO
> > we should be following the same pattern for properties, as it is much
> > more user friendly than just printing a totally generic message
> > "XXXX is deprecated, stop using it" 
> 
> Yes, rich deprecation hint is better. I think this still depends on
> USER_SET - distinguish internal/external or not :-(.
> 
> Since when we mark a property as deprecated, its code remains in the
> code tree, and internal calls should not trigger warnings. Deprecation
> hints are intended to reminder external users.

This depends on where you put the deprecation check. IIUC, all the user
facing codepaths for setting properties end up calling through
object_set_properties_from_qdict, but internal codepaths don't use that.

That method can check & emit the deprecation warnings, without us needing
any explicit tracking of "user set" - the use context is derived from the
codepath


With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



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

* Re: [PATCH v2 14/21] hw/core/qdev-properties: allow qdev properties accept flags
  2026-02-11 16:58       ` Daniel P. Berrangé
@ 2026-02-12 15:25         ` Zhao Liu
  2026-02-12 15:42           ` Daniel P. Berrangé
  2026-02-18  9:51         ` Igor Mammedov
  2026-03-06  9:30         ` Markus Armbruster
  2 siblings, 1 reply; 68+ messages in thread
From: Zhao Liu @ 2026-02-12 15:25 UTC (permalink / raw)
  To: Daniel P. Berrangé
  Cc: Paolo Bonzini, Eduardo Habkost, Markus Armbruster, Thomas Huth,
	Igor Mammedov, Philippe Mathieu-Daudé, Richard Henderson,
	Peter Maydell, Michael S . Tsirkin, BALATON Zoltan,
	Mark Cave-Ayland, Pierrick Bouvier, Zide Chen, Dapeng Mi,
	qemu-devel, devel, Zhao Liu

On Wed, Feb 11, 2026 at 04:58:47PM +0000, Daniel P. Berrangé wrote:
> Date: Wed, 11 Feb 2026 16:58:47 +0000
> From: "Daniel P. Berrangé" <berrange@redhat.com>
> Subject: Re: [PATCH v2 14/21] hw/core/qdev-properties: allow qdev
>  properties accept flags
> 
> On Wed, Feb 11, 2026 at 03:30:06PM +0800, Zhao Liu wrote:
> > On Tue, Feb 10, 2026 at 09:56:08AM +0000, Daniel P. Berrangé wrote:
> > > Date: Tue, 10 Feb 2026 09:56:08 +0000
> > > From: "Daniel P. Berrangé" <berrange@redhat.com>
> > > Subject: Re: [PATCH v2 14/21] hw/core/qdev-properties: allow qdev
> > >  properties accept flags
> > > 
> > > On Tue, Feb 10, 2026 at 11:23:41AM +0800, Zhao Liu wrote:
> > > > Update qdev property interfaces (qdev_property_add_static() and
> > > > qdev_class_add_property()) to accept and pass 'ObjectPropertyFlags'.
> > > > This enables marking qdev properties with flags such as DEPRECATED or
> > > > INTERNAL.
> > > > 
> > > > To facilitate this at the definition level, extend the boolean and
> > > > uint8_t property macros (as the examples) to accept variable arguments
> > > > (VA_ARGS). This allows callers to optionally specify flags in the
> > > > property definition.
> > > > 
> > > > Example:
> > > > 
> > > > DEFINE_PROP_UINT8("version", IOAPICCommonState, version, IOAPIC_VER_DEF,
> > > >                   .flags = OBJECT_PROPERTY_DEPRECATED),
> > > 
> > > In other places where we track deprecation in QEMU, we have not used
> > > a boolean flag. Instead we have used a "const char *deprecation_note"
> > > internally, which lets us provide a user facing message, to be printed
> > > out in the warn_report, informing them what to do instead (either the
> > > feature is entirely removed, or there is a better alternative). IMHO
> > > we should be following the same pattern for properties, as it is much
> > > more user friendly than just printing a totally generic message
> > > "XXXX is deprecated, stop using it" 
> > 
> > Yes, rich deprecation hint is better. I think this still depends on
> > USER_SET - distinguish internal/external or not :-(.
> > 
> > Since when we mark a property as deprecated, its code remains in the
> > code tree, and internal calls should not trigger warnings. Deprecation
> > hints are intended to reminder external users.
> 
> This depends on where you put the deprecation check. IIUC, all the user
> facing codepaths for setting properties end up calling through
> object_set_properties_from_qdict, but internal codepaths don't use that.
>
> That method can check & emit the deprecation warnings, without us needing
> any explicit tracking of "user set" - the use context is derived from the
> codepath

Yeah, most property setting paths are covered by
object_set_properties_from_qdict() (I listes these cases in patch 12,
including the most common ones: -object/-device and their related HMP/QMP
commands).

But there're some corner cases which don't go through
object_set_properties_from_qdict(), e.g., -global/-accel/"qom-set", etc,
those were considerred in patch 9/11/13 (and sorry I should list all
cases affected in cover letter :(). These cases are where I find
things to be both trivial and tricky, so I manually check them and mark
them using USER_SET.

Therefore, I think the unified entry point for externally setting
properties resides at a lower level—specifically, is object_property_set(),
then we need to dientify when object_property_set() is called by
external user or not - that's how USER_SET works...(I feel like I'm back
where I started).

Thanks,
Zhao



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

* Re: [PATCH v2 00/21] qom: introduce property flags to track external user input
  2026-02-11 11:28         ` BALATON Zoltan
@ 2026-02-12 15:31           ` Zhao Liu
  2026-02-12 15:56             ` BALATON Zoltan
  0 siblings, 1 reply; 68+ messages in thread
From: Zhao Liu @ 2026-02-12 15:31 UTC (permalink / raw)
  To: BALATON Zoltan
  Cc: Daniel P. Berrang�, Paolo Bonzini, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daud�, Richard Henderson, Peter Maydell,
	Michael S . Tsirkin, Mark Cave-Ayland, Pierrick Bouvier,
	Zide Chen, Dapeng Mi, qemu-devel, devel, Zhao Liu

On Wed, Feb 11, 2026 at 12:28:13PM +0100, BALATON Zoltan wrote:
> Date: Wed, 11 Feb 2026 12:28:13 +0100
> From: BALATON Zoltan <balaton@eik.bme.hu>
> Subject: Re: [PATCH v2 00/21] qom: introduce property flags to track
>  external user input
> 
> On Wed, 11 Feb 2026, Zhao Liu wrote:
> > > So another way could be to not use properties for internal settings but add
> > > another set of internal properties for those. These could be set the same
> > > way but stored in a different hash table and not get mixed with
> > > introspectable and user changable properties. But maybe that would be too
> > > much refactoring.
> > 
> > Yes, it may require adding interfaces similar to object_property_add/get/
> > set, which would need significant changes.
> 
> Maybe not that part needs significant changes as you could still use a flag
> the same way adding a parameter to object_property_add/get/set to tell it
> should put the propery in the internal hash but then you need to add the
> other hash and maybe related changes. I don't know how much would those be
> but no new interface is needed just extending existing one as you did
> already.

Yes, you're right, the flag-related interfaces in this series provide
enough support. But I haven't quite figured out what the advantages of
using an independent hash table would be, or what problems it could
address... I feel like I need to think about it more :).

Thanks,
Zhao



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

* Re: [PATCH v2 14/21] hw/core/qdev-properties: allow qdev properties accept flags
  2026-02-12 15:25         ` Zhao Liu
@ 2026-02-12 15:42           ` Daniel P. Berrangé
  2026-03-09 13:34             ` Zhao Liu
  0 siblings, 1 reply; 68+ messages in thread
From: Daniel P. Berrangé @ 2026-02-12 15:42 UTC (permalink / raw)
  To: Zhao Liu
  Cc: Paolo Bonzini, Eduardo Habkost, Markus Armbruster, Thomas Huth,
	Igor Mammedov, Philippe Mathieu-Daudé, Richard Henderson,
	Peter Maydell, Michael S . Tsirkin, BALATON Zoltan,
	Mark Cave-Ayland, Pierrick Bouvier, Zide Chen, Dapeng Mi,
	qemu-devel, devel

On Thu, Feb 12, 2026 at 11:25:17PM +0800, Zhao Liu wrote:
> On Wed, Feb 11, 2026 at 04:58:47PM +0000, Daniel P. Berrangé wrote:
> > Date: Wed, 11 Feb 2026 16:58:47 +0000
> > From: "Daniel P. Berrangé" <berrange@redhat.com>
> > Subject: Re: [PATCH v2 14/21] hw/core/qdev-properties: allow qdev
> >  properties accept flags
> > 
> > On Wed, Feb 11, 2026 at 03:30:06PM +0800, Zhao Liu wrote:
> > > On Tue, Feb 10, 2026 at 09:56:08AM +0000, Daniel P. Berrangé wrote:
> > > > Date: Tue, 10 Feb 2026 09:56:08 +0000
> > > > From: "Daniel P. Berrangé" <berrange@redhat.com>
> > > > Subject: Re: [PATCH v2 14/21] hw/core/qdev-properties: allow qdev
> > > >  properties accept flags
> > > > 
> > > > On Tue, Feb 10, 2026 at 11:23:41AM +0800, Zhao Liu wrote:
> > > > > Update qdev property interfaces (qdev_property_add_static() and
> > > > > qdev_class_add_property()) to accept and pass 'ObjectPropertyFlags'.
> > > > > This enables marking qdev properties with flags such as DEPRECATED or
> > > > > INTERNAL.
> > > > > 
> > > > > To facilitate this at the definition level, extend the boolean and
> > > > > uint8_t property macros (as the examples) to accept variable arguments
> > > > > (VA_ARGS). This allows callers to optionally specify flags in the
> > > > > property definition.
> > > > > 
> > > > > Example:
> > > > > 
> > > > > DEFINE_PROP_UINT8("version", IOAPICCommonState, version, IOAPIC_VER_DEF,
> > > > >                   .flags = OBJECT_PROPERTY_DEPRECATED),
> > > > 
> > > > In other places where we track deprecation in QEMU, we have not used
> > > > a boolean flag. Instead we have used a "const char *deprecation_note"
> > > > internally, which lets us provide a user facing message, to be printed
> > > > out in the warn_report, informing them what to do instead (either the
> > > > feature is entirely removed, or there is a better alternative). IMHO
> > > > we should be following the same pattern for properties, as it is much
> > > > more user friendly than just printing a totally generic message
> > > > "XXXX is deprecated, stop using it" 
> > > 
> > > Yes, rich deprecation hint is better. I think this still depends on
> > > USER_SET - distinguish internal/external or not :-(.
> > > 
> > > Since when we mark a property as deprecated, its code remains in the
> > > code tree, and internal calls should not trigger warnings. Deprecation
> > > hints are intended to reminder external users.
> > 
> > This depends on where you put the deprecation check. IIUC, all the user
> > facing codepaths for setting properties end up calling through
> > object_set_properties_from_qdict, but internal codepaths don't use that.
> >
> > That method can check & emit the deprecation warnings, without us needing
> > any explicit tracking of "user set" - the use context is derived from the
> > codepath
> 
> Yeah, most property setting paths are covered by
> object_set_properties_from_qdict() (I listes these cases in patch 12,
> including the most common ones: -object/-device and their related HMP/QMP
> commands).
> 
> But there're some corner cases which don't go through
> object_set_properties_from_qdict(), e.g., -global/-accel/"qom-set", etc,
> those were considerred in patch 9/11/13 (and sorry I should list all
> cases affected in cover letter :(). These cases are where I find
> things to be both trivial and tricky, so I manually check them and mark
> them using USER_SET.
> 
> Therefore, I think the unified entry point for externally setting
> properties resides at a lower level—specifically, is object_property_set(),
> then we need to dientify when object_property_set() is called by
> external user or not - that's how USER_SET works...(I feel like I'm back
> where I started).

There's a significant different there.  Emitting deprecation messages
in the API entry points tied to user data is a clear purpose, not
open to abuse. Recording the difference between user set & internally
set against the object instance persistently is an open ended purpose
and based on what we've seen in QEMU in the past, that is highly likely
to be mis-used.

The idea of supporting deprecations on properties is definitely
something we should do, but I really dn't want to see that expressed
via the 'user set' mechanism from this series.

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] 68+ messages in thread

* Re: [PATCH v2 00/21] qom: introduce property flags to track external user input
  2026-02-12 15:31           ` Zhao Liu
@ 2026-02-12 15:56             ` BALATON Zoltan
  0 siblings, 0 replies; 68+ messages in thread
From: BALATON Zoltan @ 2026-02-12 15:56 UTC (permalink / raw)
  To: Zhao Liu
  Cc: Daniel P. Berrang�, Paolo Bonzini, Eduardo Habkost,
	Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daud�, Richard Henderson, Peter Maydell,
	Michael S . Tsirkin, Mark Cave-Ayland, Pierrick Bouvier,
	Zide Chen, Dapeng Mi, qemu-devel, devel

On Thu, 12 Feb 2026, Zhao Liu wrote:
> On Wed, Feb 11, 2026 at 12:28:13PM +0100, BALATON Zoltan wrote:
>> Date: Wed, 11 Feb 2026 12:28:13 +0100
>> From: BALATON Zoltan <balaton@eik.bme.hu>
>> Subject: Re: [PATCH v2 00/21] qom: introduce property flags to track
>>  external user input
>>
>> On Wed, 11 Feb 2026, Zhao Liu wrote:
>>>> So another way could be to not use properties for internal settings but add
>>>> another set of internal properties for those. These could be set the same
>>>> way but stored in a different hash table and not get mixed with
>>>> introspectable and user changable properties. But maybe that would be too
>>>> much refactoring.
>>>
>>> Yes, it may require adding interfaces similar to object_property_add/get/
>>> set, which would need significant changes.
>>
>> Maybe not that part needs significant changes as you could still use a flag
>> the same way adding a parameter to object_property_add/get/set to tell it
>> should put the propery in the internal hash but then you need to add the
>> other hash and maybe related changes. I don't know how much would those be
>> but no new interface is needed just extending existing one as you did
>> already.
>
> Yes, you're right, the flag-related interfaces in this series provide
> enough support. But I haven't quite figured out what the advantages of
> using an independent hash table would be, or what problems it could
> address... I feel like I need to think about it more :).

Storing internal properties in another hash could avoid needing INTERNAL 
and USER_SET flags as then there would be no way to set internal 
properties other than from code and may save some checks as then you would 
not need to special case internal properties in the user 
inspectable/settable properties handling. But I don't know how much other 
infrastructure it would need and if that would end up simpler than your 
approach or not. I think it may be simpler by avoiding the special cases 
and flags and clearly separating properties but as you say that would need 
more thinking and I did not try to think further just throwing the idea at 
you :-). The part creating, setting and storing internal properties should 
be simple but I don't know if the usage of these would have a problem when 
getting properties use the same interface for both external and internal 
properties. But if all these internal properties just set device state 
fields then all that's needed might be changing the property definition to 
use internal property and the compat props to set such properties (but 
compat may use some user settable properties too so this may make those a 
bit more complex).

Regards,
BALATON Zoltan


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

* Re: [PATCH v2 14/21] hw/core/qdev-properties: allow qdev properties accept flags
  2026-02-11 16:58       ` Daniel P. Berrangé
  2026-02-12 15:25         ` Zhao Liu
@ 2026-02-18  9:51         ` Igor Mammedov
  2026-03-06  9:14           ` Markus Armbruster
  2026-03-06  9:30         ` Markus Armbruster
  2 siblings, 1 reply; 68+ messages in thread
From: Igor Mammedov @ 2026-02-18  9:51 UTC (permalink / raw)
  To: Daniel P. Berrangé
  Cc: Zhao Liu, Paolo Bonzini, Eduardo Habkost, Markus Armbruster,
	Thomas Huth, Philippe Mathieu-Daudé, Richard Henderson,
	Peter Maydell, Michael S . Tsirkin, BALATON Zoltan,
	Mark Cave-Ayland, Pierrick Bouvier, Zide Chen, Dapeng Mi,
	qemu-devel, devel

On Wed, 11 Feb 2026 16:58:47 +0000
Daniel P. Berrangé <berrange@redhat.com> wrote:

> On Wed, Feb 11, 2026 at 03:30:06PM +0800, Zhao Liu wrote:
> > On Tue, Feb 10, 2026 at 09:56:08AM +0000, Daniel P. Berrangé wrote:  
> > > Date: Tue, 10 Feb 2026 09:56:08 +0000
> > > From: "Daniel P. Berrangé" <berrange@redhat.com>
> > > Subject: Re: [PATCH v2 14/21] hw/core/qdev-properties: allow qdev
> > >  properties accept flags
> > > 
> > > On Tue, Feb 10, 2026 at 11:23:41AM +0800, Zhao Liu wrote:  
> > > > Update qdev property interfaces (qdev_property_add_static() and
> > > > qdev_class_add_property()) to accept and pass 'ObjectPropertyFlags'.
> > > > This enables marking qdev properties with flags such as DEPRECATED or
> > > > INTERNAL.
> > > > 
> > > > To facilitate this at the definition level, extend the boolean and
> > > > uint8_t property macros (as the examples) to accept variable arguments
> > > > (VA_ARGS). This allows callers to optionally specify flags in the
> > > > property definition.
> > > > 
> > > > Example:
> > > > 
> > > > DEFINE_PROP_UINT8("version", IOAPICCommonState, version, IOAPIC_VER_DEF,
> > > >                   .flags = OBJECT_PROPERTY_DEPRECATED),  
> > > 
> > > In other places where we track deprecation in QEMU, we have not used
> > > a boolean flag. Instead we have used a "const char *deprecation_note"
> > > internally, which lets us provide a user facing message, to be printed
> > > out in the warn_report, informing them what to do instead (either the
> > > feature is entirely removed, or there is a better alternative). IMHO
> > > we should be following the same pattern for properties, as it is much
> > > more user friendly than just printing a totally generic message
> > > "XXXX is deprecated, stop using it"   
> > 
> > Yes, rich deprecation hint is better. I think this still depends on
> > USER_SET - distinguish internal/external or not :-(.
> > 
> > Since when we mark a property as deprecated, its code remains in the
> > code tree, and internal calls should not trigger warnings. Deprecation
> > hints are intended to reminder external users.  
> 
> This depends on where you put the deprecation check. IIUC, all the user
> facing codepaths for setting properties end up calling through
> object_set_properties_from_qdict, but internal codepaths don't use that.

I might be totally wrong, but occasionally I've considered using
object_set_properties_from_qdict() internally as much more compact form
compared to 'object_new()/set_this_property and set that one too' noodle.

> 
> That method can check & emit the deprecation warnings, without us needing
> any explicit tracking of "user set" - the use context is derived from the
> codepath
> 
> 
> With regards,
> Daniel



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

* Re: [PATCH v2 14/21] hw/core/qdev-properties: allow qdev properties accept flags
  2026-02-18  9:51         ` Igor Mammedov
@ 2026-03-06  9:14           ` Markus Armbruster
  2026-03-06  9:19             ` Daniel P. Berrangé
  0 siblings, 1 reply; 68+ messages in thread
From: Markus Armbruster @ 2026-03-06  9:14 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: Daniel P. Berrangé, Zhao Liu, Paolo Bonzini, Eduardo Habkost,
	Thomas Huth, Philippe Mathieu-Daudé, Richard Henderson,
	Peter Maydell, Michael S . Tsirkin, BALATON Zoltan,
	Mark Cave-Ayland, Pierrick Bouvier, Zide Chen, Dapeng Mi,
	qemu-devel, devel

Igor Mammedov <imammedo@redhat.com> writes:

> I might be totally wrong, but occasionally I've considered using
> object_set_properties_from_qdict() internally as much more compact form
> compared to 'object_new()/set_this_property and set that one too' noodle.

Clear signal our C interface to QOM object configuration is lacking.

Going through a QDict is disgusting, though.  There has to be a more
direct way.  One that doesn't involve building temporary trees just so
we can use existing visitors.

What if we could pass the entire configuration as a struct?  Instead of
setting properties one by one, pass a struct literal and be done.



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

* Re: [PATCH v2 14/21] hw/core/qdev-properties: allow qdev properties accept flags
  2026-03-06  9:14           ` Markus Armbruster
@ 2026-03-06  9:19             ` Daniel P. Berrangé
  0 siblings, 0 replies; 68+ messages in thread
From: Daniel P. Berrangé @ 2026-03-06  9:19 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: Igor Mammedov, Zhao Liu, Paolo Bonzini, Eduardo Habkost,
	Thomas Huth, Philippe Mathieu-Daudé, Richard Henderson,
	Peter Maydell, Michael S . Tsirkin, BALATON Zoltan,
	Mark Cave-Ayland, Pierrick Bouvier, Zide Chen, Dapeng Mi,
	qemu-devel, devel

On Fri, Mar 06, 2026 at 10:14:23AM +0100, Markus Armbruster wrote:
> Igor Mammedov <imammedo@redhat.com> writes:
> 
> > I might be totally wrong, but occasionally I've considered using
> > object_set_properties_from_qdict() internally as much more compact form
> > compared to 'object_new()/set_this_property and set that one too' noodle.
> 
> Clear signal our C interface to QOM object configuration is lacking.
> 
> Going through a QDict is disgusting, though.  There has to be a more
> direct way.  One that doesn't involve building temporary trees just so
> we can use existing visitors.
> 
> What if we could pass the entire configuration as a struct?  Instead of
> setting properties one by one, pass a struct literal and be done.

Or we pass things as typed variadic args.

  object_new_args(TYPE_NAME,
                  "foo": someval,
		  "bar: otherval,
		  NULL);

we know the QAPI type for each named property, so we know how to
interpret type-correct values for each property in the var-args.

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] 68+ messages in thread

* Re: [PATCH v2 14/21] hw/core/qdev-properties: allow qdev properties accept flags
  2026-02-11 16:58       ` Daniel P. Berrangé
  2026-02-12 15:25         ` Zhao Liu
  2026-02-18  9:51         ` Igor Mammedov
@ 2026-03-06  9:30         ` Markus Armbruster
  2026-03-09 13:52           ` Zhao Liu
  2 siblings, 1 reply; 68+ messages in thread
From: Markus Armbruster @ 2026-03-06  9:30 UTC (permalink / raw)
  To: Daniel P. Berrangé
  Cc: Zhao Liu, Paolo Bonzini, Eduardo Habkost, Thomas Huth,
	Igor Mammedov, Philippe Mathieu-Daudé, Richard Henderson,
	Peter Maydell, Michael S . Tsirkin, BALATON Zoltan,
	Mark Cave-Ayland, Pierrick Bouvier, Zide Chen, Dapeng Mi,
	qemu-devel, devel

Daniel P. Berrangé <berrange@redhat.com> writes:

> On Wed, Feb 11, 2026 at 03:30:06PM +0800, Zhao Liu wrote:
>> On Tue, Feb 10, 2026 at 09:56:08AM +0000, Daniel P. Berrangé wrote:
>> > Date: Tue, 10 Feb 2026 09:56:08 +0000
>> > From: "Daniel P. Berrangé" <berrange@redhat.com>
>> > Subject: Re: [PATCH v2 14/21] hw/core/qdev-properties: allow qdev
>> >  properties accept flags
>> > 
>> > On Tue, Feb 10, 2026 at 11:23:41AM +0800, Zhao Liu wrote:
>> > > Update qdev property interfaces (qdev_property_add_static() and
>> > > qdev_class_add_property()) to accept and pass 'ObjectPropertyFlags'.
>> > > This enables marking qdev properties with flags such as DEPRECATED or
>> > > INTERNAL.
>> > > 
>> > > To facilitate this at the definition level, extend the boolean and
>> > > uint8_t property macros (as the examples) to accept variable arguments
>> > > (VA_ARGS). This allows callers to optionally specify flags in the
>> > > property definition.
>> > > 
>> > > Example:
>> > > 
>> > > DEFINE_PROP_UINT8("version", IOAPICCommonState, version, IOAPIC_VER_DEF,
>> > >                   .flags = OBJECT_PROPERTY_DEPRECATED),
>> > 
>> > In other places where we track deprecation in QEMU, we have not used
>> > a boolean flag. Instead we have used a "const char *deprecation_note"
>> > internally, which lets us provide a user facing message, to be printed
>> > out in the warn_report, informing them what to do instead (either the
>> > feature is entirely removed, or there is a better alternative). IMHO
>> > we should be following the same pattern for properties, as it is much
>> > more user friendly than just printing a totally generic message
>> > "XXXX is deprecated, stop using it" 

Not entirely true.

QAPI/QMP uses special feature flag @deprecated, i.e. a boolean.

We cannot emit a "user facing message": QMP cannot transport warnings.
We could at best log one, in the hope that the user finds it.  But we
don't.

Instead the deprecation note is in the documentation.

The deprecation flag is visible in QAPI/QMP introspection.  Management
application developers need this; see Peter Krempa's reply.

QEMU can be configured to reject input that makes use of deprecated
stuff, and to hide deprecated stuff in output.  This is intended for
"testing the future".

>> Yes, rich deprecation hint is better. I think this still depends on
>> USER_SET - distinguish internal/external or not :-(.
>> 
>> Since when we mark a property as deprecated, its code remains in the
>> code tree, and internal calls should not trigger warnings. Deprecation
>> hints are intended to reminder external users.
>
> This depends on where you put the deprecation check. IIUC, all the user
> facing codepaths for setting properties end up calling through
> object_set_properties_from_qdict, but internal codepaths don't use that.

This may well be true (I didn't check), but how can we ensure it remains
true?

> That method can check & emit the deprecation warnings, without us needing
> any explicit tracking of "user set" - the use context is derived from the
> codepath
>
>
> With regards,
> Daniel



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

* Re: [PATCH v2 14/21] hw/core/qdev-properties: allow qdev properties accept flags
  2026-02-12 15:42           ` Daniel P. Berrangé
@ 2026-03-09 13:34             ` Zhao Liu
  0 siblings, 0 replies; 68+ messages in thread
From: Zhao Liu @ 2026-03-09 13:34 UTC (permalink / raw)
  To: Daniel P. Berrangé
  Cc: Paolo Bonzini, Eduardo Habkost, Markus Armbruster, Thomas Huth,
	Igor Mammedov, Philippe Mathieu-Daudé, Richard Henderson,
	Peter Maydell, Michael S . Tsirkin, BALATON Zoltan,
	Mark Cave-Ayland, Pierrick Bouvier, Zide Chen, Dapeng Mi,
	qemu-devel, devel, Zhao Liu

(Sorry for the long silence — just returned from vacation.)

> > Yeah, most property setting paths are covered by
> > object_set_properties_from_qdict() (I listes these cases in patch 12,
> > including the most common ones: -object/-device and their related HMP/QMP
> > commands).
> > 
> > But there're some corner cases which don't go through
> > object_set_properties_from_qdict(), e.g., -global/-accel/"qom-set", etc,
> > those were considerred in patch 9/11/13 (and sorry I should list all
> > cases affected in cover letter :(). These cases are where I find
> > things to be both trivial and tricky, so I manually check them and mark
> > them using USER_SET.
> > 
> > Therefore, I think the unified entry point for externally setting
> > properties resides at a lower level—specifically, is object_property_set(),
> > then we need to dientify when object_property_set() is called by
> > external user or not - that's how USER_SET works...(I feel like I'm back
> > where I started).
> 
> There's a significant different there.  Emitting deprecation messages
> in the API entry points tied to user data is a clear purpose, not
> open to abuse. Recording the difference between user set & internally
> set against the object instance persistently is an open ended purpose
> and based on what we've seen in QEMU in the past, that is highly likely
> to be mis-used.
>
> The idea of supporting deprecations on properties is definitely
> something we should do, but I really dn't want to see that expressed
> via the 'user set' mechanism from this series.

Thank you for your explanation. In practice, as the alternative to
USER_SET, I understand we identify the specific API entry points (including
object_set_properties_from_qdict and others) and trigger the warning
directly within those functions / code path, may I ask if this
understanding is right?

The current API entry points are somewhat fragmented; perhaps we should
consider whether further unification is possible.

Regards,
Zhao



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

* Re: [PATCH v2 14/21] hw/core/qdev-properties: allow qdev properties accept flags
  2026-03-06  9:30         ` Markus Armbruster
@ 2026-03-09 13:52           ` Zhao Liu
  0 siblings, 0 replies; 68+ messages in thread
From: Zhao Liu @ 2026-03-09 13:52 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: Daniel P. Berrangé, Paolo Bonzini, Eduardo Habkost,
	Thomas Huth, Igor Mammedov, Philippe Mathieu-Daudé,
	Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, qemu-devel, devel, Zhao Liu

> Not entirely true.
> 
> QAPI/QMP uses special feature flag @deprecated, i.e. a boolean.
> 
> We cannot emit a "user facing message": QMP cannot transport warnings.
> We could at best log one, in the hope that the user finds it.  But we
> don't.
> 
> Instead the deprecation note is in the documentation.
> 
> The deprecation flag is visible in QAPI/QMP introspection.  Management
> application developers need this; see Peter Krempa's reply.
> 
> QEMU can be configured to reject input that makes use of deprecated
> stuff, and to hide deprecated stuff in output.  This is intended for
> "testing the future".

I think a way is to add 'deprecated' flag (bool) in ObjectPropertyInfo,
just like CpuDefinitionInfo did. Then only when property has a
deprecation_note string, the 'deprecated' flag will be set for QAPI/QMP
query.

> >> Yes, rich deprecation hint is better. I think this still depends on
> >> USER_SET - distinguish internal/external or not :-(.
> >> 
> >> Since when we mark a property as deprecated, its code remains in the
> >> code tree, and internal calls should not trigger warnings. Deprecation
> >> hints are intended to reminder external users.
> >
> > This depends on where you put the deprecation check. IIUC, all the user
> > facing codepaths for setting properties end up calling through
> > object_set_properties_from_qdict, but internal codepaths don't use that.
> 
> This may well be true (I didn't check), but how can we ensure it remains
> true?

Perhaps this interface requires documentation - and strongly caution that
it *should not* be used for internal calls. Might this help prevent
potential misuse?

Thanks,
Zhao



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

* Re: [PATCH v2 00/21] qom: introduce property flags to track external user input
  2026-02-10  3:23 [PATCH v2 00/21] qom: introduce property flags to track external user input Zhao Liu
                   ` (21 preceding siblings ...)
  2026-02-10 10:12 ` [PATCH v2 00/21] qom: introduce property flags to track external user input Daniel P. Berrangé
@ 2026-03-11 13:05 ` Markus Armbruster
  2026-03-11 13:14   ` Daniel P. Berrangé
  22 siblings, 1 reply; 68+ messages in thread
From: Markus Armbruster @ 2026-03-11 13:05 UTC (permalink / raw)
  To: Zhao Liu
  Cc: Paolo Bonzini, Daniel P . Berrangé, Eduardo Habkost,
	Thomas Huth, Igor Mammedov, Philippe Mathieu-Daudé,
	Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, qemu-devel, devel

I can't find a good spot in the existing discussion where the following
would fit neatly as a reply, so I'm starting at the top again.

Fact: a huge part of our external interface is *accidental* and
virtually undocumented.

The sane way to do an external interface is to layer it on top of more
powerful internal interfaces.  The external interface exposes just the
functionality that's wanted there.  The internal interfaces can evolve
without affecting the external one.

QMP works that way.  QEMU code uses internal C interfaces.  QEMU doesn't
send QMP commands to itself.  If we need something internally, we add it
to a suitable internal interface.  There's no need to add it to the
external interface just for that.

QOM does not work that way.  The internal and the external object
configuration interface is one and the same.  So, if we add a property
for internal use, we can't *not* add it to the external interface.

This has led to an external interface that is frickin' huge: I count
~1000 device types with ~16000 properties in qemu-system-aarch64 alone.
The vast majority is undocumented.

Time and again we've found ourselves unsure whether certain properties
have external uses, or are even meant for external use.

We have been unable / unwilling to isolate the external interface from
internal detail.  This is madness.

As long as we persist in this madness, a sane, properly documented
external interface will remain impossible.

Do we care?  If yes, we should discuss how to isolate external and
internal interfaces.

This series attempts to create a bit of infrastructure for such
isolation: means to mark properties as internal.  Is it the right
infrastructure?  Is it enough to be a useful step?  Maybe not, but then
I'd like to hear better ideas.




Prior discussion in this thread:

    Subject: How to mark internal properties (was: Re: [PATCH v4 12/27]
        target/i386/cpu:  Remove CPUX86State::enable_cpuid_0xb field)
    Date: Fri, 9 May 2025 12:04:19 +0200
    Message-ID: <2f526570-7ab0-479c-967c-b3f95f9f19e3@redhat.com>
    https://lore.kernel.org/qemu-devel/2f526570-7ab0-479c-967c-b3f95f9f19e3@redhat.com



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

* Re: [PATCH v2 00/21] qom: introduce property flags to track external user input
  2026-03-11 13:05 ` Markus Armbruster
@ 2026-03-11 13:14   ` Daniel P. Berrangé
  2026-03-11 13:38     ` Peter Krempa
  2026-03-16 15:43     ` Markus Armbruster
  0 siblings, 2 replies; 68+ messages in thread
From: Daniel P. Berrangé @ 2026-03-11 13:14 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: Zhao Liu, Paolo Bonzini, Eduardo Habkost, Thomas Huth,
	Igor Mammedov, Philippe Mathieu-Daudé, Richard Henderson,
	Peter Maydell, Michael S . Tsirkin, BALATON Zoltan,
	Mark Cave-Ayland, Pierrick Bouvier, Zide Chen, Dapeng Mi,
	qemu-devel, devel

On Wed, Mar 11, 2026 at 02:05:24PM +0100, Markus Armbruster wrote:
> I can't find a good spot in the existing discussion where the following
> would fit neatly as a reply, so I'm starting at the top again.
> 
> Fact: a huge part of our external interface is *accidental* and
> virtually undocumented.
> 
> The sane way to do an external interface is to layer it on top of more
> powerful internal interfaces.  The external interface exposes just the
> functionality that's wanted there.  The internal interfaces can evolve
> without affecting the external one.
> 
> QMP works that way.  QEMU code uses internal C interfaces.  QEMU doesn't
> send QMP commands to itself.  If we need something internally, we add it
> to a suitable internal interface.  There's no need to add it to the
> external interface just for that.
> 
> QOM does not work that way.  The internal and the external object
> configuration interface is one and the same.  So, if we add a property
> for internal use, we can't *not* add it to the external interface.
> 
> This has led to an external interface that is frickin' huge: I count
> ~1000 device types with ~16000 properties in qemu-system-aarch64 alone.
> The vast majority is undocumented.
> 
> Time and again we've found ourselves unsure whether certain properties
> have external uses, or are even meant for external use.
> 
> We have been unable / unwilling to isolate the external interface from
> internal detail.  This is madness.
> 
> As long as we persist in this madness, a sane, properly documented
> external interface will remain impossible.
> 
> Do we care?  If yes, we should discuss how to isolate external and
> internal interfaces.
> 
> This series attempts to create a bit of infrastructure for such
> isolation: means to mark properties as internal.  Is it the right
> infrastructure?  Is it enough to be a useful step?  Maybe not, but then
> I'd like to hear better ideas.

For -object / object_add  we introduced formal QAPI modelling of
all Object subclasses which implement the UserCreatable interface.
IIUC, that gives us the desired separation between internal and
external views, as only properties declared in qapi/qom.json are
publically settable.

This work did not apply to the Device classes because the historical
baggage with qdev being grafted onto qom, means we don't have that
working via the UserCreatable inteface or -object/object_add.

Can we bring Device into the same world though ?

Adding 1000 device types to QAPI is a huge job, so it would need to
be a long incremental job, unless perhaps we auto-generate QAPI
descriptions for everything that already exists ?

More generally anything we can do to bring qdev & qom closer together
feels desirable. I dream of a future where -device/device_add are
obsolete....

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] 68+ messages in thread

* Re: [PATCH v2 00/21] qom: introduce property flags to track external user input
  2026-03-11 13:14   ` Daniel P. Berrangé
@ 2026-03-11 13:38     ` Peter Krempa
  2026-03-16 15:43     ` Markus Armbruster
  1 sibling, 0 replies; 68+ messages in thread
From: Peter Krempa @ 2026-03-11 13:38 UTC (permalink / raw)
  To: Daniel P. Berrangé
  Cc: Markus Armbruster, Zhao Liu, Paolo Bonzini, Eduardo Habkost,
	Thomas Huth, Igor Mammedov, Philippe Mathieu-Daudé,
	Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, qemu-devel, devel

On Wed, Mar 11, 2026 at 13:14:41 +0000, Daniel P. Berrangé via Devel wrote:
> On Wed, Mar 11, 2026 at 02:05:24PM +0100, Markus Armbruster wrote:

[...]

> For -object / object_add  we introduced formal QAPI modelling of
> all Object subclasses which implement the UserCreatable interface.
> IIUC, that gives us the desired separation between internal and
> external views, as only properties declared in qapi/qom.json are
> publically settable.
> 
> This work did not apply to the Device classes because the historical
> baggage with qdev being grafted onto qom, means we don't have that
> working via the UserCreatable inteface or -object/object_add.
> 
> Can we bring Device into the same world though ?
> 
> Adding 1000 device types to QAPI is a huge job, so it would need to
> be a long incremental job, unless perhaps we auto-generate QAPI
> descriptions for everything that already exists ?

When I was converting libvirt to use the JSON syntax for -device I've
used the output of -device DEVTYPE,? to figure out the required types.
From what I've observed, in the vast majority of casesthe type that
qemu wants is already reported, thus generating the schema for it should
be feasible.

Obviously majority of the options lack any form of description so
documentation would be a much bigger problem, but there would be already
an starting point.

Anyways for anyone wanting to actually do this libvirt's qemuxmlconftest
suite could be useful here as it contains a sizable portion of options
libvirt supports (I'ts extremely likely that we don't cover some corner
cases though). In addition the testsuite can actually perform
validation of any of the commands taking JSON against the monitor schema,

To validate that everything that libvirt covers by tests is present in
the schema for 'device_add' one would need to just change 1 boolean (to
force full schema validation for device_add) and add a schema dump.



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

* Re: [PATCH v2 19/21] target/i386: remove redundant validation for lbr-fmt property
  2026-02-10  3:23 ` [PATCH v2 19/21] target/i386: remove redundant validation for lbr-fmt property Zhao Liu
@ 2026-03-13 22:34   ` Chen, Zide
  0 siblings, 0 replies; 68+ messages in thread
From: Chen, Zide @ 2026-03-13 22:34 UTC (permalink / raw)
  To: Zhao Liu, Paolo Bonzini, Daniel P . Berrangé,
	Eduardo Habkost, Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé
  Cc: Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Dapeng Mi,
	qemu-devel, devel



On 2/9/2026 7:23 PM, Zhao Liu wrote:
> The 'lbr-fmt' property is defined via DEFINE_PROP_UINT64_CHECKMASK,
> utilizing PERF_CAP_LBR_FMT as the validation mask. This mechanism
> ensures that the property setter rejects any value attempting to set
> bits outside this mask.
> 
> So cpu->lbr_fmt is guaranteed to be valid by the time
> x86_cpu_realizefn() executes. The manual validation inside the realize
> function is therefore redundant.
> 
> Remove the unnecessary check.
> 
> Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
> ---

Reviewed-by: Zide Chen <zide.chen@intel.com>


>  target/i386/cpu.c | 4 ----
>  1 file changed, 4 deletions(-)
> 
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index c2f99b98014a..a594747f0030 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -9816,10 +9816,6 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
>       * with user-provided setting.
>       */
>      if (cpu->lbr_fmt != ~PERF_CAP_LBR_FMT) {
> -        if ((cpu->lbr_fmt & PERF_CAP_LBR_FMT) != cpu->lbr_fmt) {
> -            error_setg(errp, "invalid lbr-fmt");
> -            return;
> -        }
>          env->features[FEAT_PERF_CAPABILITIES] &= ~PERF_CAP_LBR_FMT;
>          env->features[FEAT_PERF_CAPABILITIES] |= cpu->lbr_fmt;
>      }



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

* Re: [PATCH v2 20/21] target/i386: detect user provided lbr-fmt via property flag
  2026-02-10  3:23 ` [PATCH v2 20/21] target/i386: detect user provided lbr-fmt via property flag Zhao Liu
@ 2026-03-13 22:36   ` Chen, Zide
  0 siblings, 0 replies; 68+ messages in thread
From: Chen, Zide @ 2026-03-13 22:36 UTC (permalink / raw)
  To: Zhao Liu, Paolo Bonzini, Daniel P . Berrangé,
	Eduardo Habkost, Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé
  Cc: Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Dapeng Mi,
	qemu-devel, devel



On 2/9/2026 7:23 PM, Zhao Liu wrote:
> At present, QEMU determines if the user has set the "lbr-fmt" property
> by checking if its value differs from a special value,
> `~PERF_CAP_LBR_FMT` (`~0x3f`).
> 
> Relying on such a magic number to distinguish user input from the
> default state is implicit and fragile. It also prevents the helper macro
> `DEFINE_PROP_UINT64_CHECKMASK` from supporting a *valid* default value,
> as initializing the property with a valid default would make it
> impossible to distinguish from a user-provided value.
> 
> With the introduction of `OBJ_PROP_FLAG_USER_SET`, it's possible to
> directly check this flag to determine whether the user has modified the
> property, which can help get rid of invalid "sentinel" value.
> 
> Therefore, detect user-provided value by checking the USER_SET property
> flag in x86_cpu_realizefn(). The invalid initialization value will be
> dropped in subsequent work.
> 
> Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
> ---
>  target/i386/cpu.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index a594747f0030..a6d943c53a3f 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -9779,6 +9779,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
>      CPUX86State *env = &cpu->env;
>      Error *local_err = NULL;
>      unsigned requested_lbr_fmt;
> +    int lbr_fmt_set;
>  
>  #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
>      /* Use pc-relative instructions in system-mode */
> @@ -9815,7 +9816,11 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
>       * Override env->features[FEAT_PERF_CAPABILITIES].LBR_FMT
>       * with user-provided setting.
>       */
> -    if (cpu->lbr_fmt != ~PERF_CAP_LBR_FMT) {
> +    lbr_fmt_set = object_property_check_flags(OBJECT(dev), "lbr-fmt",
> +                                              OBJ_PROP_FLAG_USER_SET, errp);
> +    if (lbr_fmt_set < 0) {

lbr_fmt_set will never be -1.  How about remove the "< 0" case and hence
the variable lbr_fmt_set can be removed. Simpler code.

> +        return;
> +    } else if (lbr_fmt_set > 0) {
>          env->features[FEAT_PERF_CAPABILITIES] &= ~PERF_CAP_LBR_FMT;
>          env->features[FEAT_PERF_CAPABILITIES] |= cpu->lbr_fmt;
>      }



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

* Re: [PATCH v2 21/21] hw/core/qdev-properties: support valid default value for DEFINE_PROP_UINT64_CHECKMASK
  2026-02-10  3:23 ` [PATCH v2 21/21] hw/core/qdev-properties: support valid default value for DEFINE_PROP_UINT64_CHECKMASK Zhao Liu
@ 2026-03-13 22:36   ` Chen, Zide
  0 siblings, 0 replies; 68+ messages in thread
From: Chen, Zide @ 2026-03-13 22:36 UTC (permalink / raw)
  To: Zhao Liu, Paolo Bonzini, Daniel P . Berrangé,
	Eduardo Habkost, Markus Armbruster, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé
  Cc: Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Dapeng Mi,
	qemu-devel, devel



On 2/9/2026 7:23 PM, Zhao Liu wrote:
> DEFINE_PROP_UINT64_CHECKMASK is designed to detect and check user's
> property setting:
>  * checking: check property value against a bitmask.
>  * detection: ask caller to provide an invalid value as the initial
>      "sentinel" value, which is impossible to be set by users. However,
>      this detection is not strict, since the property could be also
>      set internally.
> 
> The entire mechanism is not easy to use.
> 
> Now there's USER_SET flag in place (and the current unique use case
> "lbr-fmt" has been converted to checking USER_SET way), manual setting
> of invalid initial values is no longer required.
> 
> Thus, extend DEFINE_PROP_UINT64_CHECKMASK to support *valid* default
> value, and for "lbr-fmt" case, replace the invalid initialization value
> `~PERF_CAP_LBR_FMT` with a valid value `0`.
> 
> In addition, considering DEFINE_PROP_UINT64_CHECKMASK itself actually
> doesn't identify whether the property is set by the user or not, remove
> "user-supplied" related description in its document.
> 
> Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
> ---

Nice to see "cpu->lbr_fmt = ~PERF_CAP_LBR_FMT" is gone.

Reviewed-by: Zide Chen <zide.chen@intel.com>

>  hw/core/qdev-properties.c         |  1 +
>  include/hw/core/qdev-properties.h | 14 +++++++-------
>  target/i386/cpu.c                 |  4 +---
>  3 files changed, 9 insertions(+), 10 deletions(-)
> 
> diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
> index 91c4010e7dc9..b84214e60f19 100644
> --- a/hw/core/qdev-properties.c
> +++ b/hw/core/qdev-properties.c
> @@ -507,6 +507,7 @@ const PropertyInfo qdev_prop_uint64_checkmask = {
>      .type  = "uint64",
>      .get   = get_uint64,
>      .set   = set_uint64_checkmask,
> +    .set_default_value = qdev_propinfo_set_default_value_uint,
>  };
>  
>  /* --- pointer-size integer --- */
> diff --git a/include/hw/core/qdev-properties.h b/include/hw/core/qdev-properties.h
> index c06de37b1e9d..2ac784bb5e9c 100644
> --- a/include/hw/core/qdev-properties.h
> +++ b/include/hw/core/qdev-properties.h
> @@ -128,14 +128,14 @@ extern const PropertyInfo qdev_prop_link;
>                  ##__VA_ARGS__)
>  
>  /**
> - * The DEFINE_PROP_UINT64_CHECKMASK macro checks a user-supplied value
> - * against corresponding bitmask, rejects the value if it violates.
> - * The default value is set in instance_init().
> + * The DEFINE_PROP_UINT64_CHECKMASK macro checks a value against corresponding
> + * bitmask, rejects the value if it violates.
>   */
> -#define DEFINE_PROP_UINT64_CHECKMASK(_name, _state, _field, _bitmask)   \
> -    DEFINE_PROP(_name, _state, _field, qdev_prop_uint64_checkmask, uint64_t, \
> -                .bitmask    = (_bitmask),                     \
> -                .set_default = false)
> +#define DEFINE_PROP_UINT64_CHECKMASK(_name, _state, _field, _bitmask, _defval) \
> +    DEFINE_PROP(_name, _state, _field, qdev_prop_uint64_checkmask, uint64_t,   \
> +                .bitmask    = (_bitmask),                                      \
> +                .set_default = true,                                           \
> +                .defval.u    = (_defval))
>  
>  /**
>   * DEFINE_PROP_ARRAY:
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index a6d943c53a3f..56735570d66c 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -10265,9 +10265,7 @@ static void x86_cpu_initfn(Object *obj)
>      object_property_add_alias(obj, "pause_filter", obj, "pause-filter");
>      object_property_add_alias(obj, "sse4_1", obj, "sse4.1");
>      object_property_add_alias(obj, "sse4_2", obj, "sse4.2");
> -
>      object_property_add_alias(obj, "hv-apicv", obj, "hv-avic");
> -    cpu->lbr_fmt = ~PERF_CAP_LBR_FMT;
>      object_property_add_alias(obj, "lbr_fmt", obj, "lbr-fmt");
>  
>      if (xcc->model) {
> @@ -10439,7 +10437,7 @@ static const Property x86_cpu_properties[] = {
>  #endif
>      DEFINE_PROP_INT32("node-id", X86CPU, node_id, CPU_UNSET_NUMA_NODE_ID),
>      DEFINE_PROP_BOOL("pmu", X86CPU, enable_pmu, false),
> -    DEFINE_PROP_UINT64_CHECKMASK("lbr-fmt", X86CPU, lbr_fmt, PERF_CAP_LBR_FMT),
> +    DEFINE_PROP_UINT64_CHECKMASK("lbr-fmt", X86CPU, lbr_fmt, PERF_CAP_LBR_FMT, 0),
>  
>      DEFINE_PROP_UINT32("hv-spinlocks", X86CPU, hyperv_spinlock_attempts,
>                         HYPERV_SPINLOCK_NEVER_NOTIFY),



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

* Re: [PATCH v2 00/21] qom: introduce property flags to track external user input
  2026-03-11 13:14   ` Daniel P. Berrangé
  2026-03-11 13:38     ` Peter Krempa
@ 2026-03-16 15:43     ` Markus Armbruster
  2026-03-16 16:05       ` BALATON Zoltan
                         ` (2 more replies)
  1 sibling, 3 replies; 68+ messages in thread
From: Markus Armbruster @ 2026-03-16 15:43 UTC (permalink / raw)
  To: Daniel P. Berrangé
  Cc: Zhao Liu, Paolo Bonzini, Eduardo Habkost, Thomas Huth,
	Igor Mammedov, Philippe Mathieu-Daudé, Richard Henderson,
	Peter Maydell, Michael S . Tsirkin, BALATON Zoltan,
	Mark Cave-Ayland, Pierrick Bouvier, Zide Chen, Dapeng Mi,
	qemu-devel, devel, Kevin Wolf

Daniel P. Berrangé <berrange@redhat.com> writes:

> On Wed, Mar 11, 2026 at 02:05:24PM +0100, Markus Armbruster wrote:
>> I can't find a good spot in the existing discussion where the following
>> would fit neatly as a reply, so I'm starting at the top again.
>> 
>> Fact: a huge part of our external interface is *accidental* and
>> virtually undocumented.
>> 
>> The sane way to do an external interface is to layer it on top of more
>> powerful internal interfaces.  The external interface exposes just the
>> functionality that's wanted there.  The internal interfaces can evolve
>> without affecting the external one.
>> 
>> QMP works that way.  QEMU code uses internal C interfaces.  QEMU doesn't
>> send QMP commands to itself.  If we need something internally, we add it
>> to a suitable internal interface.  There's no need to add it to the
>> external interface just for that.
>> 
>> QOM does not work that way.  The internal and the external object
>> configuration interface is one and the same.  So, if we add a property
>> for internal use, we can't *not* add it to the external interface.
>> 
>> This has led to an external interface that is frickin' huge: I count
>> ~1000 device types with ~16000 properties in qemu-system-aarch64 alone.
>> The vast majority is undocumented.
>> 
>> Time and again we've found ourselves unsure whether certain properties
>> have external uses, or are even meant for external use.
>> 
>> We have been unable / unwilling to isolate the external interface from
>> internal detail.  This is madness.
>> 
>> As long as we persist in this madness, a sane, properly documented
>> external interface will remain impossible.
>> 
>> Do we care?  If yes, we should discuss how to isolate external and
>> internal interfaces.
>> 
>> This series attempts to create a bit of infrastructure for such
>> isolation: means to mark properties as internal.  Is it the right
>> infrastructure?  Is it enough to be a useful step?  Maybe not, but then
>> I'd like to hear better ideas.
>
> For -object / object_add  we introduced formal QAPI modelling of
> all Object subclasses which implement the UserCreatable interface.
> IIUC, that gives us the desired separation between internal and
> external views, as only properties declared in qapi/qom.json are
> publically settable.

Correct.  Kevin Wolf's work.

> This work did not apply to the Device classes because the historical
> baggage with qdev being grafted onto qom, means we don't have that
> working via the UserCreatable inteface or -object/object_add.
>
> Can we bring Device into the same world though ?

Kevin Wolf took a stab at it.  I had a hard time understanding it back
then.  Various pennies finally dropped when he patiently explained it to
me in person.  I disliked certain aspects of its design, and wanted to
explore a bit more.  Never found the time.  Perhaps we should just take
it despite my design misgivings.

> Adding 1000 device types to QAPI is a huge job, so it would need to
> be a long incremental job, unless perhaps we auto-generate QAPI
> descriptions for everything that already exists ?

Interesting idea.

QAPI is declarative: types and their properties are declared in a
schema.

QOM is imperative: we execute C code to create types and their
properties.

Extracting a QAPI schema from the C code is impossible in the completely
general case (halting problem), and merely impractical (I believe) in
the special cases we have.

We could start with QOM introspection instead: qom-list-types and
qom-list-properties.  These are only mostly complete, but should be good
enough.

Mapping QOM types to QAPI types would involve guesswork, because QOM
doesn't have a type system, it has strings and bailing wire.

Schema documentation would be placeholders at best.  We could try to
extract documentation from -device T,help.  Most properties have nothing
there, and the remainder likely needs to be rewritten completely to be
fit for purpose.

> More generally anything we can do to bring qdev & qom closer together
> feels desirable. I dream of a future where -device/device_add are
> obsolete....

That would be lovely.



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

* Re: [PATCH v2 00/21] qom: introduce property flags to track external user input
  2026-03-16 15:43     ` Markus Armbruster
@ 2026-03-16 16:05       ` BALATON Zoltan
  2026-03-16 18:00         ` Markus Armbruster
  2026-03-20 10:09       ` Daniel P. Berrangé
  2026-03-23 15:37       ` Kevin Wolf
  2 siblings, 1 reply; 68+ messages in thread
From: BALATON Zoltan @ 2026-03-16 16:05 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: Daniel P. Berrangé, Zhao Liu, Paolo Bonzini, Eduardo Habkost,
	Thomas Huth, Igor Mammedov, Philippe Mathieu-Daudé,
	Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	Mark Cave-Ayland, Pierrick Bouvier, Zide Chen, Dapeng Mi,
	qemu-devel, devel, Kevin Wolf

On Mon, 16 Mar 2026, Markus Armbruster wrote:
>> More generally anything we can do to bring qdev & qom closer together
>> feels desirable. I dream of a future where -device/device_add are
>> obsolete....
>
> That would be lovely.

How would normal people add devices from the command line then? Do you 
expect us to use -object or something like that with JSON instead? That's 
very impractical so some command line UI should remain. Also is it 
practical to force people to learn some QEMU specific language to be able 
to write device models? Otherwise what advantage this gives over doing it 
in C? I think these are questions to answer before getting into the 
design.

Regards,
BALATON Zoltan


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

* Re: [PATCH v2 00/21] qom: introduce property flags to track external user input
  2026-03-16 16:05       ` BALATON Zoltan
@ 2026-03-16 18:00         ` Markus Armbruster
  0 siblings, 0 replies; 68+ messages in thread
From: Markus Armbruster @ 2026-03-16 18:00 UTC (permalink / raw)
  To: BALATON Zoltan
  Cc: Markus Armbruster, Daniel P. Berrangé, Zhao Liu,
	Paolo Bonzini, Eduardo Habkost, Thomas Huth, Igor Mammedov,
	Philippe Mathieu-Daudé, Richard Henderson, Peter Maydell,
	Michael S . Tsirkin, Mark Cave-Ayland, Pierrick Bouvier,
	Zide Chen, Dapeng Mi, qemu-devel, devel, Kevin Wolf

BALATON Zoltan <balaton@eik.bme.hu> writes:

> On Mon, 16 Mar 2026, Markus Armbruster wrote:
>>> More generally anything we can do to bring qdev & qom closer together
>>> feels desirable. I dream of a future where -device/device_add are
>>> obsolete....
>>
>> That would be lovely.
>
> How would normal people add devices from the command line then? Do you expect us to use -object or something like that with JSON instead? That's very impractical so some command line UI should remain.

-object and HMP object-add support key=value,... syntax.

I don't want to get rid of the command line.  It's good for doing simple
things, and many things should be (made) simple.

> Also is it practical to force people to learn some QEMU specific language to be able to write device models? Otherwise what advantage this gives over doing it in C? I think these are questions to answer before getting into the design.

That boat sailed long ago.

I wasn't a fan of QAPI when it was added to QEMU.  But it has become an
integral part, with tentacles almost everywhere.  Moreover, what's worse
than a less than ideal way to define an interface?  Two less than ideal
ways: QAPI and QOM.

People already have to learn basic QAPI to do lots of things in QEMU,
including device models once they have complex properties.

QAPI basics are easy enough to pick up: find something similar and
imitate.  I doubt it's any harder than learning the C interfaces for
QOM.  It is harder to screw up than in C.



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

* Re: [PATCH v2 01/21] qom/object: use BIT macro for ObjectPropertyFlags
  2026-02-10  3:23 ` [PATCH v2 01/21] qom/object: use BIT macro for ObjectPropertyFlags Zhao Liu
@ 2026-03-20  9:53   ` Thomas Huth
  0 siblings, 0 replies; 68+ messages in thread
From: Thomas Huth @ 2026-03-20  9:53 UTC (permalink / raw)
  To: Zhao Liu, Paolo Bonzini, Daniel P . Berrangé,
	Eduardo Habkost, Markus Armbruster, Igor Mammedov,
	Philippe Mathieu-Daudé
  Cc: Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, qemu-devel, devel

On 10/02/2026 04.23, Zhao Liu wrote:
> Standardize the definition of ObjectPropertyFlags by using the BIT()
> macro instead of manual bit shifts to improve readability.
> 
> Suggested-by: Igor Mammedov <imammedo@redhat.com>
> Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
> ---
>   include/qom/object.h | 5 +++--
>   1 file changed, 3 insertions(+), 2 deletions(-)

Reviewed-by: Thomas Huth <thuth@redhat.com>



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

* Re: [PATCH v2 02/21] qom/object: cache ObjectPropertyFlags in ObjectProperty
  2026-02-10  3:23 ` [PATCH v2 02/21] qom/object: cache ObjectPropertyFlags in ObjectProperty Zhao Liu
@ 2026-03-20  9:53   ` Thomas Huth
  0 siblings, 0 replies; 68+ messages in thread
From: Thomas Huth @ 2026-03-20  9:53 UTC (permalink / raw)
  To: Zhao Liu, Paolo Bonzini, Daniel P . Berrangé,
	Eduardo Habkost, Markus Armbruster, Igor Mammedov,
	Philippe Mathieu-Daudé
  Cc: Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, qemu-devel, devel

On 10/02/2026 04.23, Zhao Liu wrote:
> Introduce a 'flags' field in the ObjectProperty structure to store
> property-specific behavior modifiers.
> 
> Currently, ObjectPropertyFlags (READ/WRITE) are only used for property
> creation (e.g., initialize accessors for pointer properties).
> 
> By caching these flags directly in ObjectProperty, we can:
> 1. Preserve the initial access intent (read/write) of the property.
>     * the READ/WRITE flags cached in ObjectProperty have no effect for
>       now, but they may be useful for cases need write-once, if needed.
> 
> 2. Reuse existing ObjectPropertyFlags and provide a foundation for
>     future flags (e.g., to track if a property was explicitly set by
>     external user).
> 
> To avoid "incomplete type" error, move ObjectPropertyFlags before
> ObjectProperty definition, and polish the comment of ObjectPropertyFlags
> to clarify how READ/WRITE flags work for general properties.
> 
> Suggested-by: Igor Mammedov <imammedo@redhat.com>
> Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
> ---
>   include/qom/object.h | 34 +++++++++++++++++++++++++---------
>   qom/object.c         | 16 +++++++++++++++-
>   2 files changed, 40 insertions(+), 10 deletions(-)

Reviewed-by: Thomas Huth <thuth@redhat.com>



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

* Re: [PATCH v2 00/21] qom: introduce property flags to track external user input
  2026-03-16 15:43     ` Markus Armbruster
  2026-03-16 16:05       ` BALATON Zoltan
@ 2026-03-20 10:09       ` Daniel P. Berrangé
  2026-03-23 15:37       ` Kevin Wolf
  2 siblings, 0 replies; 68+ messages in thread
From: Daniel P. Berrangé @ 2026-03-20 10:09 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: Zhao Liu, Paolo Bonzini, Eduardo Habkost, Thomas Huth,
	Igor Mammedov, Philippe Mathieu-Daudé, Richard Henderson,
	Peter Maydell, Michael S . Tsirkin, BALATON Zoltan,
	Mark Cave-Ayland, Pierrick Bouvier, Zide Chen, Dapeng Mi,
	qemu-devel, devel, Kevin Wolf

On Mon, Mar 16, 2026 at 04:43:54PM +0100, Markus Armbruster wrote:
> Daniel P. Berrangé <berrange@redhat.com> writes:
> 
> > On Wed, Mar 11, 2026 at 02:05:24PM +0100, Markus Armbruster wrote:
> >> I can't find a good spot in the existing discussion where the following
> >> would fit neatly as a reply, so I'm starting at the top again.
> >> 
> >> Fact: a huge part of our external interface is *accidental* and
> >> virtually undocumented.
> >> 
> >> The sane way to do an external interface is to layer it on top of more
> >> powerful internal interfaces.  The external interface exposes just the
> >> functionality that's wanted there.  The internal interfaces can evolve
> >> without affecting the external one.
> >> 
> >> QMP works that way.  QEMU code uses internal C interfaces.  QEMU doesn't
> >> send QMP commands to itself.  If we need something internally, we add it
> >> to a suitable internal interface.  There's no need to add it to the
> >> external interface just for that.
> >> 
> >> QOM does not work that way.  The internal and the external object
> >> configuration interface is one and the same.  So, if we add a property
> >> for internal use, we can't *not* add it to the external interface.
> >> 
> >> This has led to an external interface that is frickin' huge: I count
> >> ~1000 device types with ~16000 properties in qemu-system-aarch64 alone.
> >> The vast majority is undocumented.
> >> 
> >> Time and again we've found ourselves unsure whether certain properties
> >> have external uses, or are even meant for external use.
> >> 
> >> We have been unable / unwilling to isolate the external interface from
> >> internal detail.  This is madness.
> >> 
> >> As long as we persist in this madness, a sane, properly documented
> >> external interface will remain impossible.
> >> 
> >> Do we care?  If yes, we should discuss how to isolate external and
> >> internal interfaces.
> >> 
> >> This series attempts to create a bit of infrastructure for such
> >> isolation: means to mark properties as internal.  Is it the right
> >> infrastructure?  Is it enough to be a useful step?  Maybe not, but then
> >> I'd like to hear better ideas.
> >
> > For -object / object_add  we introduced formal QAPI modelling of
> > all Object subclasses which implement the UserCreatable interface.
> > IIUC, that gives us the desired separation between internal and
> > external views, as only properties declared in qapi/qom.json are
> > publically settable.
> 
> Correct.  Kevin Wolf's work.
>
> > This work did not apply to the Device classes because the historical
> > baggage with qdev being grafted onto qom, means we don't have that
> > working via the UserCreatable inteface or -object/object_add.
> >
> > Can we bring Device into the same world though ?
> 
> Kevin Wolf took a stab at it.  I had a hard time understanding it back
> then.  Various pennies finally dropped when he patiently explained it to
> me in person.  I disliked certain aspects of its design, and wanted to
> explore a bit more.  Never found the time.  Perhaps we should just take
> it despite my design misgivings.

Yep, I vaguely recall that, but never had a chance to look at it
at the time.

> 
> > Adding 1000 device types to QAPI is a huge job, so it would need to
> > be a long incremental job, unless perhaps we auto-generate QAPI
> > descriptions for everything that already exists ?
> 
> Interesting idea.
> 
> QAPI is declarative: types and their properties are declared in a
> schema.
> 
> QOM is imperative: we execute C code to create types and their
> properties.
> 
> Extracting a QAPI schema from the C code is impossible in the completely
> general case (halting problem), and merely impractical (I believe) in
> the special cases we have.
> 
> We could start with QOM introspection instead: qom-list-types and
> qom-list-properties.  These are only mostly complete, but should be good
> enough.
> 
> Mapping QOM types to QAPI types would involve guesswork, because QOM
> doesn't have a type system, it has strings and bailing wire.
> 
> Schema documentation would be placeholders at best.  We could try to
> extract documentation from -device T,help.  Most properties have nothing
> there, and the remainder likely needs to be rewritten completely to be
> fit for purpose.

Yep, in case it wasn't obvious, when I said "auto-generate QAPI
descriptions", I meant generate the skeleton of the QAPI json
structure with whatever partial data we have, and a human would
then have to fill in the blanks to bring it upto par with QAPI
expectations. The docs descriptions do seem like a big part
of the manual work that would be involved here.


Perhaps another oddity is the distinction between devices which
can actually be created with -device, vs devices that are only
internally created but can none the less be set via -global.
I presume we would need to expose all devices in QAPI, regardless
of being user creatable or not.

> 
> > More generally anything we can do to bring qdev & qom closer together
> > feels desirable. I dream of a future where -device/device_add are
> > obsolete....
> 
> That would be lovely.
> 

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] 68+ messages in thread

* Re: [PATCH v2 00/21] qom: introduce property flags to track external user input
  2026-03-16 15:43     ` Markus Armbruster
  2026-03-16 16:05       ` BALATON Zoltan
  2026-03-20 10:09       ` Daniel P. Berrangé
@ 2026-03-23 15:37       ` Kevin Wolf
  2 siblings, 0 replies; 68+ messages in thread
From: Kevin Wolf @ 2026-03-23 15:37 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: Daniel P. Berrangé, Zhao Liu, Paolo Bonzini, Eduardo Habkost,
	Thomas Huth, Igor Mammedov, Philippe Mathieu-Daudé,
	Richard Henderson, Peter Maydell, Michael S . Tsirkin,
	BALATON Zoltan, Mark Cave-Ayland, Pierrick Bouvier, Zide Chen,
	Dapeng Mi, qemu-devel, devel

Am 16.03.2026 um 16:43 hat Markus Armbruster geschrieben:
> Daniel P. Berrangé <berrange@redhat.com> writes:
> > For -object / object_add  we introduced formal QAPI modelling of
> > all Object subclasses which implement the UserCreatable interface.
> > IIUC, that gives us the desired separation between internal and
> > external views, as only properties declared in qapi/qom.json are
> > publically settable.
> 
> Correct.  Kevin Wolf's work.
> 
> > This work did not apply to the Device classes because the historical
> > baggage with qdev being grafted onto qom, means we don't have that
> > working via the UserCreatable inteface or -object/object_add.
> >
> > Can we bring Device into the same world though ?
> 
> Kevin Wolf took a stab at it.  I had a hard time understanding it back
> then.  Various pennies finally dropped when he patiently explained it to
> me in person.  I disliked certain aspects of its design, and wanted to
> explore a bit more.  Never found the time.  Perhaps we should just take
> it despite my design misgivings.
> 
> > Adding 1000 device types to QAPI is a huge job, so it would need to
> > be a long incremental job, unless perhaps we auto-generate QAPI
> > descriptions for everything that already exists ?

Doing things incrementally was my idea when I did the patch series to
prepare it (which really only completed the converstion for -object,
getting rid of some of the duplication between QOM and QAPI definitions
that we currently have - but the same things would probably also be the
prerequisite for starting to convert devices).

Even if you could automate the conversion, doing thousands of devices
with different maintainers in a single series seems completely
unmanageable.

> Interesting idea.
> 
> QAPI is declarative: types and their properties are declared in a
> schema.
> 
> QOM is imperative: we execute C code to create types and their
> properties.
> 
> Extracting a QAPI schema from the C code is impossible in the completely
> general case (halting problem), and merely impractical (I believe) in
> the special cases we have.
> 
> We could start with QOM introspection instead: qom-list-types and
> qom-list-properties.  These are only mostly complete, but should be good
> enough.
> 
> Mapping QOM types to QAPI types would involve guesswork, because QOM
> doesn't have a type system, it has strings and bailing wire.

QOM itself is typed, only the QemuOpts it normally takes as input isn't.
You just have to find the right visitor call in the code and then you
can pretty much copy the type into the QAPI schema (sometimes it's more
complex than that because visitor calls are made conditionally or in a
loop or whatever, but it's not guesswork anyway).

> Schema documentation would be placeholders at best.  We could try to
> extract documentation from -device T,help.  Most properties have
> nothing there, and the remainder likely needs to be rewritten
> completely to be fit for purpose.

FWIW, writing documentation was the real work in converting -object.
Automating everything else can possibly be a minor convenience
improvement, but in comparison to documenting stuff it's trivial enough
anyway.

> > More generally anything we can do to bring qdev & qom closer together
> > feels desirable. I dream of a future where -device/device_add are
> > obsolete....
> 
> That would be lovely.

If you decide to finally stop blocking it, let me know. Maybe I can find
some time to resurrect something, though having to rebase after four(?)
years doesn't sound like fun.

Kevin



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

end of thread, other threads:[~2026-03-23 15:37 UTC | newest]

Thread overview: 68+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-10  3:23 [PATCH v2 00/21] qom: introduce property flags to track external user input Zhao Liu
2026-02-10  3:23 ` [PATCH v2 01/21] qom/object: use BIT macro for ObjectPropertyFlags Zhao Liu
2026-03-20  9:53   ` Thomas Huth
2026-02-10  3:23 ` [PATCH v2 02/21] qom/object: cache ObjectPropertyFlags in ObjectProperty Zhao Liu
2026-03-20  9:53   ` Thomas Huth
2026-02-10  3:23 ` [PATCH v2 03/21] qom/object: factor out object_class_property_try_add() Zhao Liu
2026-02-10 14:41   ` BALATON Zoltan
2026-02-11  7:14     ` Zhao Liu
2026-02-10  3:23 ` [PATCH v2 04/21] qom/object: add flags argument in object_{class_}property_try_add() Zhao Liu
2026-02-10  3:23 ` [PATCH v2 05/21] qom/object: rename object_{class_}property_try_add() to object_{class_}property_add_full() Zhao Liu
2026-02-10  3:23 ` [PATCH v2 06/21] qom/object: add helpers to set/get/clear property flags Zhao Liu
2026-02-10  3:23 ` [PATCH v2 07/21] qom/object: introduce user interaction flags for properties Zhao Liu
2026-02-10  9:49   ` Daniel P. Berrangé
2026-02-10  9:58     ` Daniel P. Berrangé
2026-02-11  8:19       ` Zhao Liu
2026-02-10 14:44   ` BALATON Zoltan
2026-02-11  7:22     ` Zhao Liu
2026-02-10  3:23 ` [PATCH v2 08/21] qom/object: add from_user argument in object_property_parse() Zhao Liu
2026-02-10  3:23 ` [PATCH v2 09/21] qom/object: mark global property set from CLI as USER_SET Zhao Liu
2026-02-10  3:23 ` [PATCH v2 10/21] qom/qom-hmp-cmd: mark properties set from HMP (non-JSON) "qom-set" " Zhao Liu
2026-02-10  3:23 ` [PATCH v2 11/21] qom/qom-qmp-cmd: mark properties set from QMP/HMP (JSON) " Zhao Liu
2026-02-10  3:23 ` [PATCH v2 12/21] qom/object_interfaces: mark properties set from qdict & keyval " Zhao Liu
2026-02-10  3:23 ` [PATCH v2 13/21] system/vl: mark property set in object_parse_property_opt() " Zhao Liu
2026-02-10  3:23 ` [PATCH v2 14/21] hw/core/qdev-properties: allow qdev properties accept flags Zhao Liu
2026-02-10  9:41   ` Peter Krempa
2026-02-11  7:10     ` Zhao Liu
2026-02-10  9:56   ` Daniel P. Berrangé
2026-02-11  7:30     ` Zhao Liu
2026-02-11 16:58       ` Daniel P. Berrangé
2026-02-12 15:25         ` Zhao Liu
2026-02-12 15:42           ` Daniel P. Berrangé
2026-03-09 13:34             ` Zhao Liu
2026-02-18  9:51         ` Igor Mammedov
2026-03-06  9:14           ` Markus Armbruster
2026-03-06  9:19             ` Daniel P. Berrangé
2026-03-06  9:30         ` Markus Armbruster
2026-03-09 13:52           ` Zhao Liu
2026-02-10  3:23 ` [PATCH v2 15/21] target/i386: deprecate fill-mtrr-mask property Zhao Liu
2026-02-10  3:23 ` [PATCH v2 16/21] target/i386: deprecate cpuid-0xb property Zhao Liu
2026-02-10  3:23 ` [PATCH v2 17/21] hw/intc/ioapic: deprecate version property Zhao Liu
2026-02-10  3:23 ` [PATCH v2 18/21] target/i386: mark x-consistent-cache property as internal-only Zhao Liu
2026-02-10  3:23 ` [PATCH v2 19/21] target/i386: remove redundant validation for lbr-fmt property Zhao Liu
2026-03-13 22:34   ` Chen, Zide
2026-02-10  3:23 ` [PATCH v2 20/21] target/i386: detect user provided lbr-fmt via property flag Zhao Liu
2026-03-13 22:36   ` Chen, Zide
2026-02-10  3:23 ` [PATCH v2 21/21] hw/core/qdev-properties: support valid default value for DEFINE_PROP_UINT64_CHECKMASK Zhao Liu
2026-03-13 22:36   ` Chen, Zide
2026-02-10 10:12 ` [PATCH v2 00/21] qom: introduce property flags to track external user input Daniel P. Berrangé
2026-02-10 10:44   ` Michael S. Tsirkin
2026-02-10 11:00     ` Daniel P. Berrangé
2026-02-10 15:00       ` BALATON Zoltan
2026-02-10 15:28   ` Zhao Liu
2026-02-10 15:16     ` BALATON Zoltan
2026-02-11  7:24       ` Zhao Liu
2026-02-11 11:28         ` BALATON Zoltan
2026-02-12 15:31           ` Zhao Liu
2026-02-12 15:56             ` BALATON Zoltan
2026-02-10 15:41     ` Daniel P. Berrangé
2026-02-11  7:06       ` Zhao Liu
2026-02-11 11:18         ` Daniel P. Berrangé
2026-03-11 13:05 ` Markus Armbruster
2026-03-11 13:14   ` Daniel P. Berrangé
2026-03-11 13:38     ` Peter Krempa
2026-03-16 15:43     ` Markus Armbruster
2026-03-16 16:05       ` BALATON Zoltan
2026-03-16 18:00         ` Markus Armbruster
2026-03-20 10:09       ` Daniel P. Berrangé
2026-03-23 15:37       ` Kevin Wolf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox