* [PATCH 0/5] qom: prepare a TypeBucket for same-name target variants
@ 2026-11-05 19:03 Yonggang Luo
2026-11-05 19:03 ` [PATCH 1/5] qom: store registration targets on TypeImpl Yonggang Luo
` (5 more replies)
0 siblings, 6 replies; 14+ messages in thread
From: Yonggang Luo @ 2026-11-05 19:03 UTC (permalink / raw)
To: qemu-devel
Cc: Pierrick Bouvier, Philippe Mathieu-Daudé, Paolo Bonzini,
Daniel P. Berrangé, Philippe Mathieu-Daude
This series prepares QOM to hold more than one TypeImpl under the same name, one
per target, so a multi-target binary can register same-name types without
renaming them. Nothing uses it yet.
type_table maps each name to a TypeBucket, which holds the variants and the
union of their QEMU_ARCH_* masks. Registration still aborts when masks overlap,
and a name lookup returns the one variant left for the selected target.
type_register_targets() registers a variant for a target mask.
type_register_static() is unchanged, so binaries keep one TypeImpl per name.
The change stays in qom and target-info and does not conflict with the virt QOM
name or is_available series.
Daniel asked what a TypeBucket means. This is that prototype, based on the
bucket idea from Pierrick.
Daniel: what a TypeBucket means:
Link: https://lore.kernel.org/qemu-devel/auyP09mbwuefulBL@redhat.com/
Pierrick: register types per target bucket:
Link: https://lore.kernel.org/qemu-devel/d754acaa-0811-4185-a78f-1a352ec8bbab@oss.qualcomm.com/
Pierrick: the bucket work can proceed in parallel:
Link: https://lore.kernel.org/qemu-devel/CAE2XoE-iOCdGxPtg7MqydmahpnOTFM_15dR0eJKGMrQKxrgeQQ@mail.gmail.com/
Yonggang Luo (5):
qom: store registration targets on TypeImpl
target-info: add target_mask_selected()
qom: add target_mask_filter()
qom: filter type lookup with TypeBucket
qom: add type_register_targets()
include/qemu/target-info-init.h | 15 ++-
include/qemu/target-info.h | 9 ++
include/qom/object.h | 12 +++
qom/object.c | 168 ++++++++++++++++++++++++++------
stubs/meson.build | 1 +
stubs/target-mask-selected.c | 13 +++
target-info-def.c | 3 +
target-info-qom.c | 10 ++
8 files changed, 197 insertions(+), 34 deletions(-)
create mode 100644 stubs/target-mask-selected.c
--
2.55.0.windows.3
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/5] qom: store registration targets on TypeImpl
2026-11-05 19:03 [PATCH 0/5] qom: prepare a TypeBucket for same-name target variants Yonggang Luo
@ 2026-11-05 19:03 ` Yonggang Luo
2026-11-05 19:03 ` [PATCH 2/5] target-info: add target_mask_selected() Yonggang Luo
` (4 subsequent siblings)
5 siblings, 0 replies; 14+ messages in thread
From: Yonggang Luo @ 2026-11-05 19:03 UTC (permalink / raw)
To: qemu-devel
Cc: Pierrick Bouvier, Philippe Mathieu-Daudé, Paolo Bonzini,
Daniel P. Berrangé, Philippe Mathieu-Daude
type_new() and type_register_internal() take a QEMU_ARCH_* mask and
save it on the new TypeImpl. type_register_static() and the built-in
object and interface types pass QEMU_ARCH_ALL. An interface type
copies the mask from the concrete type that implements it.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
qom/object.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/qom/object.c b/qom/object.c
index cd0590c3fd..b7e1924e81 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -71,6 +71,8 @@ struct TypeImpl
bool abstract;
bool secure;
+ uint64_t targets;
+
const char *parent;
TypeImpl *parent_type;
@@ -97,7 +99,7 @@ static TypeImpl *type_table_lookup(const char *name)
return g_hash_table_lookup(type_table, name);
}
-static TypeImpl *type_new(const TypeInfo *info)
+static TypeImpl *type_new(const TypeInfo *info, uint64_t targets)
{
TypeImpl *ti = g_malloc0(sizeof(*ti));
int i;
@@ -126,6 +128,7 @@ static TypeImpl *type_new(const TypeInfo *info)
ti->abstract = info->abstract;
ti->secure = info->secure;
+ ti->targets = targets;
for (i = 0; info->interfaces && info->interfaces[i].type; i++) {
ti->interfaces[i].typename = g_strdup(info->interfaces[i].type);
@@ -158,7 +161,7 @@ static bool type_name_is_valid(const char *name)
return plen == slen;
}
-static TypeImpl *type_register_internal(const TypeInfo *info)
+static TypeImpl *type_register_internal(const TypeInfo *info, uint64_t targets)
{
TypeImpl *ti;
@@ -171,7 +174,7 @@ static TypeImpl *type_register_internal(const TypeInfo *info)
return NULL;
}
- ti = type_new(info);
+ ti = type_new(info, targets);
type_table_add(ti);
return ti;
@@ -180,7 +183,7 @@ static TypeImpl *type_register_internal(const TypeInfo *info)
TypeImpl *type_register_static(const TypeInfo *info)
{
assert(info->parent);
- return type_register_internal(info);
+ return type_register_internal(info, QEMU_ARCH_ALL);
}
void type_register_static_array(const TypeInfo *infos, int nr_infos)
@@ -310,7 +313,7 @@ static void type_initialize_interface(TypeImpl *ti, TypeImpl *interface_type,
info.name = g_strdup_printf("%s::%s", ti->name, interface_type->name);
info.abstract = true;
- iface_impl = type_new(&info);
+ iface_impl = type_new(&info, ti->targets);
iface_impl->parent_type = parent_type;
type_initialize(iface_impl);
g_free((char *)info.name);
@@ -3239,6 +3242,6 @@ static void __attribute__((constructor)) register_types(void)
};
type_table = g_hash_table_new(g_str_hash, g_str_equal);
- type_interface = type_register_internal(&interface_info);
- type_register_internal(&object_info);
+ type_interface = type_register_internal(&interface_info, QEMU_ARCH_ALL);
+ type_register_internal(&object_info, QEMU_ARCH_ALL);
}
--
2.55.0.windows.3
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 2/5] target-info: add target_mask_selected()
2026-11-05 19:03 [PATCH 0/5] qom: prepare a TypeBucket for same-name target variants Yonggang Luo
2026-11-05 19:03 ` [PATCH 1/5] qom: store registration targets on TypeImpl Yonggang Luo
@ 2026-11-05 19:03 ` Yonggang Luo
2026-11-06 15:45 ` Daniel P. Berrangé
2026-11-06 17:44 ` Pierrick Bouvier
2026-11-05 19:03 ` [PATCH 3/5] qom: add target_mask_filter() Yonggang Luo
` (3 subsequent siblings)
5 siblings, 2 replies; 14+ messages in thread
From: Yonggang Luo @ 2026-11-05 19:03 UTC (permalink / raw)
To: qemu-devel
Cc: Pierrick Bouvier, Philippe Mathieu-Daudé, Paolo Bonzini,
Daniel P. Berrangé, Philippe Mathieu-Daude
Return the QEMU_ARCH_* mask of the selected target. System mode
returns QEMU_ARCH_ALL until a target is selected. User mode returns
that target's bit. Tools return 0.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
include/qemu/target-info-init.h | 15 ++++++++++-----
include/qemu/target-info.h | 9 +++++++++
stubs/meson.build | 1 +
stubs/target-mask-selected.c | 13 +++++++++++++
target-info-def.c | 3 +++
target-info-qom.c | 10 ++++++++++
6 files changed, 46 insertions(+), 5 deletions(-)
create mode 100644 stubs/target-mask-selected.c
diff --git a/include/qemu/target-info-init.h b/include/qemu/target-info-init.h
index b7024c9fae..8492986832 100644
--- a/include/qemu/target-info-init.h
+++ b/include/qemu/target-info-init.h
@@ -24,12 +24,17 @@ module_init(do_qemu_init_target_info, MODULE_INIT_TARGET_INFO)
/*
* User mode does not support multiple targets in the same binary, so just
- * define target_info().
+ * define target_info() and target_mask_selected(). The target is always
+ * selected.
*/
-#define target_info_init(ti_var) \
-const TargetInfo *target_info(void) \
-{ \
- return &ti_var; \
+#define target_info_init(ti_var) \
+const TargetInfo *target_info(void) \
+{ \
+ return &ti_var; \
+} \
+uint64_t target_mask_selected(void) \
+{ \
+ return QEMU_ARCH_BIT((ti_var).target_arch); \
}
#else /* CONFIG_USER_ONLY */
diff --git a/include/qemu/target-info.h b/include/qemu/target-info.h
index 2cd4cc5671..5673d10eba 100644
--- a/include/qemu/target-info.h
+++ b/include/qemu/target-info.h
@@ -134,4 +134,13 @@ bool target_base_riscv(void);
*/
bool target_riscv64(void);
+/**
+ * target_mask_selected:
+ *
+ * Returns the QEMU_ARCH_* mask of the selected target. System mode
+ * returns QEMU_ARCH_ALL until a target is selected. User mode returns
+ * that target's bit. Tools return 0.
+ */
+uint64_t target_mask_selected(void);
+
#endif
diff --git a/stubs/meson.build b/stubs/meson.build
index 744fb759a2..49cede8582 100644
--- a/stubs/meson.build
+++ b/stubs/meson.build
@@ -12,6 +12,7 @@ stub_ss.add(files('monitor-hmp.c'))
stub_ss.add(files('qapi-event-emit.c'))
stub_ss.add(files('replay-mode.c'))
stub_ss.add(files('trace-control.c'))
+stub_ss.add(files('target-mask-selected.c'))
if have_block
stub_ss.add(files('bdrv-next-monitor-owned.c'))
diff --git a/stubs/target-mask-selected.c b/stubs/target-mask-selected.c
new file mode 100644
index 0000000000..510a515851
--- /dev/null
+++ b/stubs/target-mask-selected.c
@@ -0,0 +1,13 @@
+/*
+ * Tools have no selected target.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/target-info.h"
+
+uint64_t target_mask_selected(void)
+{
+ return 0;
+}
diff --git a/target-info-def.c b/target-info-def.c
index bcf9cfe1e4..a992019626 100644
--- a/target-info-def.c
+++ b/target-info-def.c
@@ -9,6 +9,9 @@
#include "qemu/osdep.h"
#include "qemu/target-info.h"
#include "qemu/target-info-def.h"
+#ifdef CONFIG_USER_ONLY
+#include "qemu/base-arch-defs.h"
+#endif
#include "qemu/target-info-init.h"
#include "hw/core/boards.h"
#include "cpu.h"
diff --git a/target-info-qom.c b/target-info-qom.c
index aeeedb7e81..fb4c9835e5 100644
--- a/target-info-qom.c
+++ b/target-info-qom.c
@@ -9,6 +9,8 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qom/object.h"
+#include "qemu/base-arch-defs.h"
+#include "qemu/target-info.h"
#include "qemu/target-info-def.h"
#include "qemu/target-info-init.h"
#include "qemu/target-info-qom.h"
@@ -40,6 +42,14 @@ const TargetInfo *target_info(void)
return target_info_ptr;
}
+uint64_t target_mask_selected(void)
+{
+ if (!target_info_ptr) {
+ return QEMU_ARCH_ALL;
+ }
+ return QEMU_ARCH_BIT(target_info_ptr->target_arch);
+}
+
void target_info_qom_set_target(void)
{
g_autoptr(GSList) targets = object_class_get_list(TYPE_TARGET_INFO, false);
--
2.55.0.windows.3
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 3/5] qom: add target_mask_filter()
2026-11-05 19:03 [PATCH 0/5] qom: prepare a TypeBucket for same-name target variants Yonggang Luo
2026-11-05 19:03 ` [PATCH 1/5] qom: store registration targets on TypeImpl Yonggang Luo
2026-11-05 19:03 ` [PATCH 2/5] target-info: add target_mask_selected() Yonggang Luo
@ 2026-11-05 19:03 ` Yonggang Luo
2026-11-05 19:03 ` [PATCH 4/5] qom: filter type lookup with TypeBucket Yonggang Luo
` (2 subsequent siblings)
5 siblings, 0 replies; 14+ messages in thread
From: Yonggang Luo @ 2026-11-05 19:03 UTC (permalink / raw)
To: qemu-devel
Cc: Pierrick Bouvier, Philippe Mathieu-Daudé, Paolo Bonzini,
Daniel P. Berrangé, Philippe Mathieu-Daude
target_mask_filter() intersects any other mask with
target_mask_selected(). QEMU_ARCH_ALL stays unchanged. Tools
cannot select a target, so a mask other than QEMU_ARCH_ALL aborts
registration. System mode keeps the mask until a target is
selected, then keeps only that target's bit. Registration returns
NULL when the filtered mask is empty.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
qom/object.c | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/qom/object.c b/qom/object.c
index b7e1924e81..c224263112 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -16,6 +16,8 @@
#include "qom/object.h"
#include "qom/object_interfaces.h"
#include "qemu/cutils.h"
+#include "qemu/base-arch-defs.h"
+#include "qemu/target-info.h"
#include "qemu/memalign.h"
#include "qapi/visitor.h"
#include "qapi/string-input-visitor.h"
@@ -88,6 +90,29 @@ static GHashTable *type_table;
static bool enumerating_types;
+/**
+ * target_mask_filter:
+ * @mask: QEMU_ARCH_* mask to filter.
+ *
+ * QEMU_ARCH_ALL is unchanged for tools, user mode, and system mode.
+ *
+ * Tools return 0 from target_mask_selected() and cannot select a
+ * target, so any other mask aborts registration.
+ *
+ * Before system mode selects a target, target_mask_selected() is
+ * QEMU_ARCH_ALL and @mask is unchanged.
+ *
+ * When a target is selected, any other mask is intersected with
+ * QEMU_ARCH_BIT() of that target. User mode always has a target.
+ */
+static uint64_t target_mask_filter(uint64_t mask)
+{
+ if (mask == QEMU_ARCH_ALL) {
+ return mask;
+ }
+ return mask & target_mask_selected();
+}
+
static void type_table_add(TypeImpl *ti)
{
assert(!enumerating_types);
@@ -174,6 +199,19 @@ static TypeImpl *type_register_internal(const TypeInfo *info, uint64_t targets)
return NULL;
}
+ /* Tools cannot select a target, so targets must be QEMU_ARCH_ALL. */
+ if (target_mask_selected() == 0 && targets != QEMU_ARCH_ALL) {
+ fprintf(stderr,
+ "Registering '%s' with targets other than QEMU_ARCH_ALL "
+ "in tools\n", info->name);
+ abort();
+ }
+
+ targets = target_mask_filter(targets);
+ if (!targets) {
+ return NULL;
+ }
+
ti = type_new(info, targets);
type_table_add(ti);
--
2.55.0.windows.3
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 4/5] qom: filter type lookup with TypeBucket
2026-11-05 19:03 [PATCH 0/5] qom: prepare a TypeBucket for same-name target variants Yonggang Luo
` (2 preceding siblings ...)
2026-11-05 19:03 ` [PATCH 3/5] qom: add target_mask_filter() Yonggang Luo
@ 2026-11-05 19:03 ` Yonggang Luo
2026-11-05 19:03 ` [PATCH 5/5] qom: add type_register_targets() Yonggang Luo
2026-11-12 13:53 ` [PATCH 0/5] qom: prepare a TypeBucket for same-name target variants Daniel P. Berrangé
5 siblings, 0 replies; 14+ messages in thread
From: Yonggang Luo @ 2026-11-05 19:03 UTC (permalink / raw)
To: qemu-devel
Cc: Pierrick Bouvier, Philippe Mathieu-Daudé, Paolo Bonzini,
Daniel P. Berrangé, Philippe Mathieu-Daude
type_table maps each name to a TypeBucket of TypeImpl variants and
the union of their target masks. Registration aborts when the new
mask overlaps a variant already in the bucket, so same-name types
for disjoint targets can coexist.
Bare-name lookup, class enumeration, and parent, interface, and
dynamic cast resolution walk that bucket. Enumeration and bare-name
lookup keep a variant when target_mask_filter() of its mask is
non-empty. With no target selected, bare-name lookup returns the
variant only when the bucket holds one.
type_list_lookup() returns those variants. need == 0 does not
require any architecture bits. Any other need keeps the variant
whose mask contains every bit of need, which is at most one.
type_lookup_current() passes 0 and returns that variant only when
one remains. type_table_lookup() passes the class mask for parent,
interface, and dynamic cast resolution.
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
qom/object.c | 107 ++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 85 insertions(+), 22 deletions(-)
diff --git a/qom/object.c b/qom/object.c
index c224263112..265cf19041 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -19,6 +19,7 @@
#include "qemu/base-arch-defs.h"
#include "qemu/target-info.h"
#include "qemu/memalign.h"
+#include "qemu/queue.h"
#include "qapi/visitor.h"
#include "qapi/string-input-visitor.h"
#include "qapi/string-output-visitor.h"
@@ -74,6 +75,7 @@ struct TypeImpl
bool secure;
uint64_t targets;
+ QSLIST_ENTRY(TypeImpl) next;
const char *parent;
TypeImpl *parent_type;
@@ -84,6 +86,11 @@ struct TypeImpl
InterfaceImpl interfaces[MAX_INTERFACES];
};
+typedef struct TypeBucket {
+ uint64_t targets;
+ QSLIST_HEAD(, TypeImpl) variants;
+} TypeBucket;
+
static Type type_interface;
static GHashTable *type_table;
@@ -113,15 +120,56 @@ static uint64_t target_mask_filter(uint64_t mask)
return mask & target_mask_selected();
}
-static void type_table_add(TypeImpl *ti)
+static void type_table_add(TypeBucket *bucket, TypeImpl *ti)
{
assert(!enumerating_types);
- g_hash_table_insert(type_table, (void *)ti->name, ti);
+ if (!bucket) {
+ bucket = g_new0(TypeBucket, 1);
+ g_hash_table_insert(type_table, (void *)ti->name, bucket);
+ }
+ bucket->targets |= ti->targets;
+ QSLIST_INSERT_HEAD(&bucket->variants, ti, next);
+}
+
+static GSList *type_list_lookup(const char *name, uint64_t need)
+{
+ TypeBucket *bucket;
+ TypeImpl *ti;
+ GSList *list = NULL;
+
+ if (!name) {
+ return NULL;
+ }
+ bucket = g_hash_table_lookup(type_table, name);
+ if (!bucket) {
+ return NULL;
+ }
+ QSLIST_FOREACH(ti, &bucket->variants, next) {
+ if (!target_mask_filter(ti->targets)) {
+ continue;
+ }
+ /* need == 0 keeps all variants; any other need matches at most one mask. */
+ if ((ti->targets & need) != need) {
+ continue;
+ }
+ list = g_slist_append(list, ti);
+ }
+ return list;
+}
+
+static TypeImpl *type_table_lookup(const char *name, uint64_t need)
+{
+ g_autoptr(GSList) list;
+
+ g_assert(need != 0);
+ list = type_list_lookup(name, need);
+ return list ? list->data : NULL;
}
-static TypeImpl *type_table_lookup(const char *name)
+static TypeImpl *type_lookup_current(const char *name)
{
- return g_hash_table_lookup(type_table, name);
+ g_autoptr(GSList) list = type_list_lookup(name, 0);
+ return g_slist_length(list) == 1 ? list->data : NULL;
}
static TypeImpl *type_new(const TypeInfo *info, uint64_t targets)
@@ -131,11 +179,6 @@ static TypeImpl *type_new(const TypeInfo *info, uint64_t targets)
g_assert(info->name != NULL);
- if (type_table_lookup(info->name) != NULL) {
- fprintf(stderr, "Registering `%s' which already exists\n", info->name);
- abort();
- }
-
ti->name = g_strdup(info->name);
ti->parent = g_strdup(info->parent);
@@ -188,6 +231,7 @@ static bool type_name_is_valid(const char *name)
static TypeImpl *type_register_internal(const TypeInfo *info, uint64_t targets)
{
+ TypeBucket *bucket;
TypeImpl *ti;
if (!type_name_is_valid(info->name)) {
@@ -212,9 +256,15 @@ static TypeImpl *type_register_internal(const TypeInfo *info, uint64_t targets)
return NULL;
}
+ bucket = g_hash_table_lookup(type_table, info->name);
+ if (bucket && (bucket->targets & targets)) {
+ fprintf(stderr, "Registering '%s' which already exists\n", info->name);
+ abort();
+ }
+
ti = type_new(info, targets);
- type_table_add(ti);
+ type_table_add(bucket, ti);
return ti;
}
@@ -233,24 +283,24 @@ void type_register_static_array(const TypeInfo *infos, int nr_infos)
}
}
-static TypeImpl *type_get_by_name_noload(const char *name)
+static TypeImpl *type_get_by_name_noload(const char *name, uint64_t need)
{
if (name == NULL) {
return NULL;
}
- return type_table_lookup(name);
+ return type_table_lookup(name, need);
}
static TypeImpl *type_get_or_load_by_name(const char *name, Error **errp)
{
- TypeImpl *type = type_get_by_name_noload(name);
+ TypeImpl *type = type_lookup_current(name);
#ifdef CONFIG_MODULES
if (!type) {
int rv = module_load_qom(name, errp);
if (rv > 0) {
- type = type_get_by_name_noload(name);
+ type = type_lookup_current(name);
} else {
error_prepend(errp, "could not load a module for type '%s'", name);
return NULL;
@@ -267,7 +317,7 @@ static TypeImpl *type_get_or_load_by_name(const char *name, Error **errp)
static TypeImpl *type_get_parent(TypeImpl *type)
{
if (!type->parent_type && type->parent) {
- type->parent_type = type_get_by_name_noload(type->parent);
+ type->parent_type = type_get_by_name_noload(type->parent, type->targets);
if (!type->parent_type) {
fprintf(stderr, "Type '%s' is missing its parent '%s'\n",
type->name, type->parent);
@@ -422,7 +472,7 @@ static void type_initialize(TypeImpl *ti)
}
for (i = 0; i < ti->num_interfaces; i++) {
- TypeImpl *t = type_get_by_name_noload(ti->interfaces[i].typename);
+ TypeImpl *t = type_get_by_name_noload(ti->interfaces[i].typename, ti->targets);
if (!t) {
error_report("missing interface '%s' for object '%s'",
ti->interfaces[i].typename, parent->name);
@@ -1097,7 +1147,7 @@ ObjectClass *object_class_dynamic_cast(ObjectClass *class,
return class;
}
- target_type = type_get_by_name_noload(typename);
+ target_type = type_get_by_name_noload(typename, type->targets);
if (!target_type) {
/* target class type unknown, so fail the cast */
return NULL;
@@ -1201,7 +1251,7 @@ const char *object_class_get_name(ObjectClass *klass)
ObjectClass *object_class_by_name(const char *typename)
{
- TypeImpl *type = type_get_by_name_noload(typename);
+ TypeImpl *type = type_lookup_current(typename);
if (!type) {
return NULL;
@@ -1246,13 +1296,14 @@ typedef struct OCFData
void *opaque;
} OCFData;
-static void object_class_foreach_tramp(gpointer key, gpointer value,
- gpointer opaque)
+static void object_class_foreach_type(TypeImpl *type, OCFData *data)
{
- OCFData *data = opaque;
- TypeImpl *type = value;
ObjectClass *k;
+ if (!target_mask_filter(type->targets)) {
+ return;
+ }
+
type_initialize(type);
k = type->class;
@@ -1268,6 +1319,18 @@ static void object_class_foreach_tramp(gpointer key, gpointer value,
data->fn(k, data->opaque);
}
+static void object_class_foreach_tramp(gpointer key, gpointer value,
+ gpointer opaque)
+{
+ OCFData *data = opaque;
+ TypeBucket *bucket = value;
+ TypeImpl *type;
+
+ QSLIST_FOREACH(type, &bucket->variants, next) {
+ object_class_foreach_type(type, data);
+ }
+}
+
void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),
const char *implements_type, bool include_abstract,
void *opaque)
--
2.55.0.windows.3
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 5/5] qom: add type_register_targets()
2026-11-05 19:03 [PATCH 0/5] qom: prepare a TypeBucket for same-name target variants Yonggang Luo
` (3 preceding siblings ...)
2026-11-05 19:03 ` [PATCH 4/5] qom: filter type lookup with TypeBucket Yonggang Luo
@ 2026-11-05 19:03 ` Yonggang Luo
2026-11-12 13:53 ` [PATCH 0/5] qom: prepare a TypeBucket for same-name target variants Daniel P. Berrangé
5 siblings, 0 replies; 14+ messages in thread
From: Yonggang Luo @ 2026-11-05 19:03 UTC (permalink / raw)
To: qemu-devel
Cc: Pierrick Bouvier, Philippe Mathieu-Daudé, Paolo Bonzini,
Daniel P. Berrangé, Philippe Mathieu-Daude
type_register_static() always registers with QEMU_ARCH_ALL.
type_register_targets() takes a QEMU_ARCH_* mask and passes it to
type_register_internal(), which filters the mask and returns NULL
when nothing remains. As call to this function needs QEMU_ARCH_*,
so include "qemu/base-arch-defs.h" in object.h
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
include/qom/object.h | 12 ++++++++++++
qom/object.c | 6 ++++++
2 files changed, 18 insertions(+)
diff --git a/include/qom/object.h b/include/qom/object.h
index 70d8ea3e29..bda9b8901e 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -16,6 +16,7 @@
#include "qapi/qapi-builtin-types.h"
#include "qapi/qapi-type-info.h"
+#include "qemu/base-arch-defs.h"
#include "qemu/module.h"
struct TypeImpl;
@@ -988,6 +989,17 @@ const char *object_get_typename(const Object *obj);
*/
Type type_register_static(const TypeInfo *info);
+/**
+ * type_register_targets:
+ * @info: The #TypeInfo of the new type.
+ * @targets: QEMU_ARCH_* mask of targets that may use this type.
+ *
+ * @targets is passed through target_mask_filter(). QEMU_ARCH_ALL stays
+ * QEMU_ARCH_ALL. Returns the new #Type, or %NULL when the filtered
+ * mask is empty.
+ */
+Type type_register_targets(const TypeInfo *info, uint64_t targets);
+
/**
* type_register_static_array:
* @infos: The array of the new type #TypeInfo structures.
diff --git a/qom/object.c b/qom/object.c
index 265cf19041..0e50b0011b 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -274,6 +274,12 @@ TypeImpl *type_register_static(const TypeInfo *info)
return type_register_internal(info, QEMU_ARCH_ALL);
}
+TypeImpl *type_register_targets(const TypeInfo *info, uint64_t targets)
+{
+ assert(info->parent);
+ return type_register_internal(info, targets);
+}
+
void type_register_static_array(const TypeInfo *infos, int nr_infos)
{
int i;
--
2.55.0.windows.3
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 2/5] target-info: add target_mask_selected()
2026-11-05 19:03 ` [PATCH 2/5] target-info: add target_mask_selected() Yonggang Luo
@ 2026-11-06 15:45 ` Daniel P. Berrangé
2026-11-06 16:17 ` Yonggang Luo
2026-11-06 17:44 ` Pierrick Bouvier
1 sibling, 1 reply; 14+ messages in thread
From: Daniel P. Berrangé @ 2026-11-06 15:45 UTC (permalink / raw)
To: Yonggang Luo
Cc: qemu-devel, Pierrick Bouvier, Philippe Mathieu-Daudé,
Paolo Bonzini, Philippe Mathieu-Daude
On Fri, Nov 06, 2026 at 03:03:43AM +0800, Yonggang Luo wrote:
> Return the QEMU_ARCH_* mask of the selected target. System mode
> returns QEMU_ARCH_ALL until a target is selected. User mode returns
> that target's bit. Tools return 0.
I was wondering if it was better to have system mode return
0 or QEMU_ARCH_ALL, when no target is selected.
I guess QEMU_ARCH_ALL (or a mask of all arches that are
built-in to the bniary) is a better approach, as it expresses
that the system's current state is capable of targetting
any of the include arches, while '0' conceptually represents
the "no arch specific features" scenario for tools.
>
> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> ---
> include/qemu/target-info-init.h | 15 ++++++++++-----
> include/qemu/target-info.h | 9 +++++++++
> stubs/meson.build | 1 +
> stubs/target-mask-selected.c | 13 +++++++++++++
> target-info-def.c | 3 +++
> target-info-qom.c | 10 ++++++++++
> 6 files changed, 46 insertions(+), 5 deletions(-)
> create mode 100644 stubs/target-mask-selected.c
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
this patch looks applicable independently of 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] 14+ messages in thread
* Re: [PATCH 2/5] target-info: add target_mask_selected()
2026-11-06 15:45 ` Daniel P. Berrangé
@ 2026-11-06 16:17 ` Yonggang Luo
0 siblings, 0 replies; 14+ messages in thread
From: Yonggang Luo @ 2026-11-06 16:17 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: qemu-devel, Pierrick Bouvier, Philippe Mathieu-Daudé,
Paolo Bonzini, Philippe Mathieu-Daude
On Fri, Nov 6, 2026 at 11:45 PM Daniel P. Berrangé <berrange@redhat.com> wrote:
>
> On Fri, Nov 06, 2026 at 03:03:43AM +0800, Yonggang Luo wrote:
> > Return the QEMU_ARCH_* mask of the selected target. System mode
> > returns QEMU_ARCH_ALL until a target is selected. User mode returns
> > that target's bit. Tools return 0.
>
> I was wondering if it was better to have system mode return
> 0 or QEMU_ARCH_ALL, when no target is selected.
Tools return 0, so only an object whose targets are
QEMU_ARCH_ALL is accepted. Any other mask is filtered out,
because 0 AND anything is 0.
System mode returns QEMU_ARCH_ALL until a target is
selected, so every target mask is accepted.
User mode always has a target selected, so it returns that
target's bitmask.
Tools and system mode need different values so the two
binaries can be distinguished. 0 is tools. QEMU_ARCH_ALL is
system mode before a target is selected.
>
> I guess QEMU_ARCH_ALL (or a mask of all arches that are
> built-in to the bniary) is a better approach, as it expresses
That "mask" is a subset of QEMU_ARCH_ALL. A user-mode binary
still contains every bit of QEMU_ARCH_ALL, so the subset
cannot replace it. TYPE_INTERFACE and TYPE_OBJECT are
registered with QEMU_ARCH_ALL. If the "mask" is still a
generated macro, registering them with it filters them out
for some user target, or object.c has to be compiled twice(user/system),
or we need a stub variable for the mask. That is far more
complicated. QEMU_ARCH_ALL has no such restriction.
> that the system's current state is capable of targetting
> any of the include arches, while '0' conceptually represents
> the "no arch specific features" scenario for tools.
>
> >
> > Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> > ---
> > include/qemu/target-info-init.h | 15 ++++++++++-----
> > include/qemu/target-info.h | 9 +++++++++
> > stubs/meson.build | 1 +
> > stubs/target-mask-selected.c | 13 +++++++++++++
> > target-info-def.c | 3 +++
> > target-info-qom.c | 10 ++++++++++
> > 6 files changed, 46 insertions(+), 5 deletions(-)
> > create mode 100644 stubs/target-mask-selected.c
>
> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
>
> this patch looks applicable independently of 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 :|
>
--
此致
礼
罗勇刚
Yours
sincerely,
Yonggang Luo
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/5] target-info: add target_mask_selected()
2026-11-05 19:03 ` [PATCH 2/5] target-info: add target_mask_selected() Yonggang Luo
2026-11-06 15:45 ` Daniel P. Berrangé
@ 2026-11-06 17:44 ` Pierrick Bouvier
2026-11-06 17:46 ` Yonggang Luo
1 sibling, 1 reply; 14+ messages in thread
From: Pierrick Bouvier @ 2026-11-06 17:44 UTC (permalink / raw)
To: Yonggang Luo, qemu-devel
Cc: Philippe Mathieu-Daudé, Paolo Bonzini,
Daniel P. Berrangé, Philippe Mathieu-Daude
On 11/5/2026 11:03 AM, Yonggang Luo wrote:
> Return the QEMU_ARCH_* mask of the selected target. System mode
> returns QEMU_ARCH_ALL until a target is selected. User mode returns
> that target's bit. Tools return 0.
>
> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> ---
> include/qemu/target-info-init.h | 15 ++++++++++-----
> include/qemu/target-info.h | 9 +++++++++
> stubs/meson.build | 1 +
> stubs/target-mask-selected.c | 13 +++++++++++++
> target-info-def.c | 3 +++
> target-info-qom.c | 10 ++++++++++
> 6 files changed, 46 insertions(+), 5 deletions(-)
> create mode 100644 stubs/target-mask-selected.c
>
> diff --git a/include/qemu/target-info-init.h b/include/qemu/target-info-init.h
> index b7024c9fae..8492986832 100644
> --- a/include/qemu/target-info-init.h
> +++ b/include/qemu/target-info-init.h
> @@ -24,12 +24,17 @@ module_init(do_qemu_init_target_info, MODULE_INIT_TARGET_INFO)
>
> /*
> * User mode does not support multiple targets in the same binary, so just
> - * define target_info().
> + * define target_info() and target_mask_selected(). The target is always
> + * selected.
> */
> -#define target_info_init(ti_var) \
> -const TargetInfo *target_info(void) \
> -{ \
> - return &ti_var; \
> +#define target_info_init(ti_var) \
> +const TargetInfo *target_info(void) \
> +{ \
> + return &ti_var; \
> +} \
> +uint64_t target_mask_selected(void) \
> +{ \
> + return QEMU_ARCH_BIT((ti_var).target_arch); \
> }
>
> #else /* CONFIG_USER_ONLY */
> diff --git a/include/qemu/target-info.h b/include/qemu/target-info.h
> index 2cd4cc5671..5673d10eba 100644
> --- a/include/qemu/target-info.h
> +++ b/include/qemu/target-info.h
> @@ -134,4 +134,13 @@ bool target_base_riscv(void);
> */
> bool target_riscv64(void);
>
> +/**
> + * target_mask_selected:
> + *
> + * Returns the QEMU_ARCH_* mask of the selected target. System mode
> + * returns QEMU_ARCH_ALL until a target is selected. User mode returns
> + * that target's bit. Tools return 0.
> + */
> +uint64_t target_mask_selected(void);
> +
> #endif
> diff --git a/stubs/meson.build b/stubs/meson.build
> index 744fb759a2..49cede8582 100644
> --- a/stubs/meson.build
> +++ b/stubs/meson.build
> @@ -12,6 +12,7 @@ stub_ss.add(files('monitor-hmp.c'))
> stub_ss.add(files('qapi-event-emit.c'))
> stub_ss.add(files('replay-mode.c'))
> stub_ss.add(files('trace-control.c'))
> +stub_ss.add(files('target-mask-selected.c'))
>
For which configs is the stub required?
target-info-def will always be present.
> if have_block
> stub_ss.add(files('bdrv-next-monitor-owned.c'))
> diff --git a/stubs/target-mask-selected.c b/stubs/target-mask-selected.c
> new file mode 100644
> index 0000000000..510a515851
> --- /dev/null
> +++ b/stubs/target-mask-selected.c
> @@ -0,0 +1,13 @@
> +/*
> + * Tools have no selected target.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/target-info.h"
> +
> +uint64_t target_mask_selected(void)
> +{
> + return 0;
> +}
> diff --git a/target-info-def.c b/target-info-def.c
> index bcf9cfe1e4..a992019626 100644
> --- a/target-info-def.c
> +++ b/target-info-def.c
> @@ -9,6 +9,9 @@
> #include "qemu/osdep.h"
> #include "qemu/target-info.h"
> #include "qemu/target-info-def.h"
> +#ifdef CONFIG_USER_ONLY
> +#include "qemu/base-arch-defs.h"
> +#endif
> #include "qemu/target-info-init.h"
> #include "hw/core/boards.h"
> #include "cpu.h"
> diff --git a/target-info-qom.c b/target-info-qom.c
> index aeeedb7e81..fb4c9835e5 100644
> --- a/target-info-qom.c
> +++ b/target-info-qom.c
> @@ -9,6 +9,8 @@
> #include "qemu/osdep.h"
> #include "qapi/error.h"
> #include "qom/object.h"
> +#include "qemu/base-arch-defs.h"
> +#include "qemu/target-info.h"
> #include "qemu/target-info-def.h"
> #include "qemu/target-info-init.h"
> #include "qemu/target-info-qom.h"
> @@ -40,6 +42,14 @@ const TargetInfo *target_info(void)
> return target_info_ptr;
> }
>
> +uint64_t target_mask_selected(void)
> +{
> + if (!target_info_ptr) {
> + return QEMU_ARCH_ALL;
> + }
> + return QEMU_ARCH_BIT(target_info_ptr->target_arch);
> +}
> +
> void target_info_qom_set_target(void)
> {
> g_autoptr(GSList) targets = object_class_get_list(TYPE_TARGET_INFO, false);
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/5] target-info: add target_mask_selected()
2026-11-06 17:44 ` Pierrick Bouvier
@ 2026-11-06 17:46 ` Yonggang Luo
2026-11-06 17:47 ` Pierrick Bouvier
0 siblings, 1 reply; 14+ messages in thread
From: Yonggang Luo @ 2026-11-06 17:46 UTC (permalink / raw)
To: Pierrick Bouvier
Cc: qemu-devel, Philippe Mathieu-Daudé, Paolo Bonzini,
Daniel P. Berrangé, Philippe Mathieu-Daude
On Sat, Nov 7, 2026 at 1:44 AM Pierrick Bouvier
<pierrick.bouvier@oss.qualcomm.com> wrote:
>
> On 11/5/2026 11:03 AM, Yonggang Luo wrote:
> > Return the QEMU_ARCH_* mask of the selected target. System mode
> > returns QEMU_ARCH_ALL until a target is selected. User mode returns
> > that target's bit. Tools return 0.
> >
> > Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> > ---
> > include/qemu/target-info-init.h | 15 ++++++++++-----
> > include/qemu/target-info.h | 9 +++++++++
> > stubs/meson.build | 1 +
> > stubs/target-mask-selected.c | 13 +++++++++++++
> > target-info-def.c | 3 +++
> > target-info-qom.c | 10 ++++++++++
> > 6 files changed, 46 insertions(+), 5 deletions(-)
> > create mode 100644 stubs/target-mask-selected.c
> >
> > diff --git a/include/qemu/target-info-init.h b/include/qemu/target-info-init.h
> > index b7024c9fae..8492986832 100644
> > --- a/include/qemu/target-info-init.h
> > +++ b/include/qemu/target-info-init.h
> > @@ -24,12 +24,17 @@ module_init(do_qemu_init_target_info, MODULE_INIT_TARGET_INFO)
> >
> > /*
> > * User mode does not support multiple targets in the same binary, so just
> > - * define target_info().
> > + * define target_info() and target_mask_selected(). The target is always
> > + * selected.
> > */
> > -#define target_info_init(ti_var) \
> > -const TargetInfo *target_info(void) \
> > -{ \
> > - return &ti_var; \
> > +#define target_info_init(ti_var) \
> > +const TargetInfo *target_info(void) \
> > +{ \
> > + return &ti_var; \
> > +} \
> > +uint64_t target_mask_selected(void) \
> > +{ \
> > + return QEMU_ARCH_BIT((ti_var).target_arch); \
> > }
> >
> > #else /* CONFIG_USER_ONLY */
> > diff --git a/include/qemu/target-info.h b/include/qemu/target-info.h
> > index 2cd4cc5671..5673d10eba 100644
> > --- a/include/qemu/target-info.h
> > +++ b/include/qemu/target-info.h
> > @@ -134,4 +134,13 @@ bool target_base_riscv(void);
> > */
> > bool target_riscv64(void);
> >
> > +/**
> > + * target_mask_selected:
> > + *
> > + * Returns the QEMU_ARCH_* mask of the selected target. System mode
> > + * returns QEMU_ARCH_ALL until a target is selected. User mode returns
> > + * that target's bit. Tools return 0.
> > + */
> > +uint64_t target_mask_selected(void);
> > +
> > #endif
> > diff --git a/stubs/meson.build b/stubs/meson.build
> > index 744fb759a2..49cede8582 100644
> > --- a/stubs/meson.build
> > +++ b/stubs/meson.build
> > @@ -12,6 +12,7 @@ stub_ss.add(files('monitor-hmp.c'))
> > stub_ss.add(files('qapi-event-emit.c'))
> > stub_ss.add(files('replay-mode.c'))
> > stub_ss.add(files('trace-control.c'))
> > +stub_ss.add(files('target-mask-selected.c'))
> >
>
> For which configs is the stub required?
> target-info-def will always be present.
For tools
>
> > if have_block
> > stub_ss.add(files('bdrv-next-monitor-owned.c'))
> > diff --git a/stubs/target-mask-selected.c b/stubs/target-mask-selected.c
> > new file mode 100644
> > index 0000000000..510a515851
> > --- /dev/null
> > +++ b/stubs/target-mask-selected.c
> > @@ -0,0 +1,13 @@
> > +/*
> > + * Tools have no selected target.
> > + *
> > + * SPDX-License-Identifier: GPL-2.0-or-later
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "qemu/target-info.h"
> > +
> > +uint64_t target_mask_selected(void)
> > +{
> > + return 0;
> > +}
> > diff --git a/target-info-def.c b/target-info-def.c
> > index bcf9cfe1e4..a992019626 100644
> > --- a/target-info-def.c
> > +++ b/target-info-def.c
> > @@ -9,6 +9,9 @@
> > #include "qemu/osdep.h"
> > #include "qemu/target-info.h"
> > #include "qemu/target-info-def.h"
> > +#ifdef CONFIG_USER_ONLY
> > +#include "qemu/base-arch-defs.h"
> > +#endif
> > #include "qemu/target-info-init.h"
> > #include "hw/core/boards.h"
> > #include "cpu.h"
> > diff --git a/target-info-qom.c b/target-info-qom.c
> > index aeeedb7e81..fb4c9835e5 100644
> > --- a/target-info-qom.c
> > +++ b/target-info-qom.c
> > @@ -9,6 +9,8 @@
> > #include "qemu/osdep.h"
> > #include "qapi/error.h"
> > #include "qom/object.h"
> > +#include "qemu/base-arch-defs.h"
> > +#include "qemu/target-info.h"
> > #include "qemu/target-info-def.h"
> > #include "qemu/target-info-init.h"
> > #include "qemu/target-info-qom.h"
> > @@ -40,6 +42,14 @@ const TargetInfo *target_info(void)
> > return target_info_ptr;
> > }
> >
> > +uint64_t target_mask_selected(void)
> > +{
> > + if (!target_info_ptr) {
> > + return QEMU_ARCH_ALL;
> > + }
> > + return QEMU_ARCH_BIT(target_info_ptr->target_arch);
> > +}
> > +
> > void target_info_qom_set_target(void)
> > {
> > g_autoptr(GSList) targets = object_class_get_list(TYPE_TARGET_INFO, false);
>
--
此致
礼
罗勇刚
Yours
sincerely,
Yonggang Luo
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/5] target-info: add target_mask_selected()
2026-11-06 17:46 ` Yonggang Luo
@ 2026-11-06 17:47 ` Pierrick Bouvier
2026-11-06 19:52 ` Yonggang Luo
0 siblings, 1 reply; 14+ messages in thread
From: Pierrick Bouvier @ 2026-11-06 17:47 UTC (permalink / raw)
To: luoyonggang
Cc: qemu-devel, Philippe Mathieu-Daudé, Paolo Bonzini,
Daniel P. Berrangé, Philippe Mathieu-Daude
On 11/6/2026 9:46 AM, Yonggang Luo wrote:
> On Sat, Nov 7, 2026 at 1:44 AM Pierrick Bouvier
> <pierrick.bouvier@oss.qualcomm.com> wrote:
>>
>> On 11/5/2026 11:03 AM, Yonggang Luo wrote:
>>> Return the QEMU_ARCH_* mask of the selected target. System mode
>>> returns QEMU_ARCH_ALL until a target is selected. User mode returns
>>> that target's bit. Tools return 0.
>>>
>>> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
>>> ---
>>> include/qemu/target-info-init.h | 15 ++++++++++-----
>>> include/qemu/target-info.h | 9 +++++++++
>>> stubs/meson.build | 1 +
>>> stubs/target-mask-selected.c | 13 +++++++++++++
>>> target-info-def.c | 3 +++
>>> target-info-qom.c | 10 ++++++++++
>>> 6 files changed, 46 insertions(+), 5 deletions(-)
>>> create mode 100644 stubs/target-mask-selected.c
>>>
>>> diff --git a/include/qemu/target-info-init.h b/include/qemu/target-info-init.h
>>> index b7024c9fae..8492986832 100644
>>> --- a/include/qemu/target-info-init.h
>>> +++ b/include/qemu/target-info-init.h
>>> @@ -24,12 +24,17 @@ module_init(do_qemu_init_target_info, MODULE_INIT_TARGET_INFO)
>>>
>>> /*
>>> * User mode does not support multiple targets in the same binary, so just
>>> - * define target_info().
>>> + * define target_info() and target_mask_selected(). The target is always
>>> + * selected.
>>> */
>>> -#define target_info_init(ti_var) \
>>> -const TargetInfo *target_info(void) \
>>> -{ \
>>> - return &ti_var; \
>>> +#define target_info_init(ti_var) \
>>> +const TargetInfo *target_info(void) \
>>> +{ \
>>> + return &ti_var; \
>>> +} \
>>> +uint64_t target_mask_selected(void) \
>>> +{ \
>>> + return QEMU_ARCH_BIT((ti_var).target_arch); \
>>> }
>>>
>>> #else /* CONFIG_USER_ONLY */
>>> diff --git a/include/qemu/target-info.h b/include/qemu/target-info.h
>>> index 2cd4cc5671..5673d10eba 100644
>>> --- a/include/qemu/target-info.h
>>> +++ b/include/qemu/target-info.h
>>> @@ -134,4 +134,13 @@ bool target_base_riscv(void);
>>> */
>>> bool target_riscv64(void);
>>>
>>> +/**
>>> + * target_mask_selected:
>>> + *
>>> + * Returns the QEMU_ARCH_* mask of the selected target. System mode
>>> + * returns QEMU_ARCH_ALL until a target is selected. User mode returns
>>> + * that target's bit. Tools return 0.
>>> + */
>>> +uint64_t target_mask_selected(void);
>>> +
>>> #endif
>>> diff --git a/stubs/meson.build b/stubs/meson.build
>>> index 744fb759a2..49cede8582 100644
>>> --- a/stubs/meson.build
>>> +++ b/stubs/meson.build
>>> @@ -12,6 +12,7 @@ stub_ss.add(files('monitor-hmp.c'))
>>> stub_ss.add(files('qapi-event-emit.c'))
>>> stub_ss.add(files('replay-mode.c'))
>>> stub_ss.add(files('trace-control.c'))
>>> +stub_ss.add(files('target-mask-selected.c'))
>>>
>>
>> For which configs is the stub required?
>> target-info-def will always be present.
>
> For tools
>
Can you post the exact link error that exposes the absence of this symbol?
>>
>>> if have_block
>>> stub_ss.add(files('bdrv-next-monitor-owned.c'))
>>> diff --git a/stubs/target-mask-selected.c b/stubs/target-mask-selected.c
>>> new file mode 100644
>>> index 0000000000..510a515851
>>> --- /dev/null
>>> +++ b/stubs/target-mask-selected.c
>>> @@ -0,0 +1,13 @@
>>> +/*
>>> + * Tools have no selected target.
>>> + *
>>> + * SPDX-License-Identifier: GPL-2.0-or-later
>>> + */
>>> +
>>> +#include "qemu/osdep.h"
>>> +#include "qemu/target-info.h"
>>> +
>>> +uint64_t target_mask_selected(void)
>>> +{
>>> + return 0;
>>> +}
>>> diff --git a/target-info-def.c b/target-info-def.c
>>> index bcf9cfe1e4..a992019626 100644
>>> --- a/target-info-def.c
>>> +++ b/target-info-def.c
>>> @@ -9,6 +9,9 @@
>>> #include "qemu/osdep.h"
>>> #include "qemu/target-info.h"
>>> #include "qemu/target-info-def.h"
>>> +#ifdef CONFIG_USER_ONLY
>>> +#include "qemu/base-arch-defs.h"
>>> +#endif
>>> #include "qemu/target-info-init.h"
>>> #include "hw/core/boards.h"
>>> #include "cpu.h"
>>> diff --git a/target-info-qom.c b/target-info-qom.c
>>> index aeeedb7e81..fb4c9835e5 100644
>>> --- a/target-info-qom.c
>>> +++ b/target-info-qom.c
>>> @@ -9,6 +9,8 @@
>>> #include "qemu/osdep.h"
>>> #include "qapi/error.h"
>>> #include "qom/object.h"
>>> +#include "qemu/base-arch-defs.h"
>>> +#include "qemu/target-info.h"
>>> #include "qemu/target-info-def.h"
>>> #include "qemu/target-info-init.h"
>>> #include "qemu/target-info-qom.h"
>>> @@ -40,6 +42,14 @@ const TargetInfo *target_info(void)
>>> return target_info_ptr;
>>> }
>>>
>>> +uint64_t target_mask_selected(void)
>>> +{
>>> + if (!target_info_ptr) {
>>> + return QEMU_ARCH_ALL;
>>> + }
>>> + return QEMU_ARCH_BIT(target_info_ptr->target_arch);
>>> +}
>>> +
>>> void target_info_qom_set_target(void)
>>> {
>>> g_autoptr(GSList) targets = object_class_get_list(TYPE_TARGET_INFO, false);
>>
>
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/5] target-info: add target_mask_selected()
2026-11-06 17:47 ` Pierrick Bouvier
@ 2026-11-06 19:52 ` Yonggang Luo
2026-11-06 20:19 ` Pierrick Bouvier
0 siblings, 1 reply; 14+ messages in thread
From: Yonggang Luo @ 2026-11-06 19:52 UTC (permalink / raw)
To: Pierrick Bouvier
Cc: qemu-devel, Philippe Mathieu-Daudé, Paolo Bonzini,
Daniel P. Berrangé, Philippe Mathieu-Daude
On Sat, Nov 7, 2026 at 1:47 AM Pierrick Bouvier
<pierrick.bouvier@oss.qualcomm.com> wrote:
>
> On 11/6/2026 9:46 AM, Yonggang Luo wrote:
> > On Sat, Nov 7, 2026 at 1:44 AM Pierrick Bouvier
> > <pierrick.bouvier@oss.qualcomm.com> wrote:
> >>
> >> On 11/5/2026 11:03 AM, Yonggang Luo wrote:
> >>> Return the QEMU_ARCH_* mask of the selected target. System mode
> >>> returns QEMU_ARCH_ALL until a target is selected. User mode returns
> >>> that target's bit. Tools return 0.
> >>>
> >>> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> >>> ---
> >>> include/qemu/target-info-init.h | 15 ++++++++++-----
> >>> include/qemu/target-info.h | 9 +++++++++
> >>> stubs/meson.build | 1 +
> >>> stubs/target-mask-selected.c | 13 +++++++++++++
> >>> target-info-def.c | 3 +++
> >>> target-info-qom.c | 10 ++++++++++
> >>> 6 files changed, 46 insertions(+), 5 deletions(-)
> >>> create mode 100644 stubs/target-mask-selected.c
> >>>
> >>> diff --git a/include/qemu/target-info-init.h b/include/qemu/target-info-init.h
> >>> index b7024c9fae..8492986832 100644
> >>> --- a/include/qemu/target-info-init.h
> >>> +++ b/include/qemu/target-info-init.h
> >>> @@ -24,12 +24,17 @@ module_init(do_qemu_init_target_info, MODULE_INIT_TARGET_INFO)
> >>>
> >>> /*
> >>> * User mode does not support multiple targets in the same binary, so just
> >>> - * define target_info().
> >>> + * define target_info() and target_mask_selected(). The target is always
> >>> + * selected.
> >>> */
> >>> -#define target_info_init(ti_var) \
> >>> -const TargetInfo *target_info(void) \
> >>> -{ \
> >>> - return &ti_var; \
> >>> +#define target_info_init(ti_var) \
> >>> +const TargetInfo *target_info(void) \
> >>> +{ \
> >>> + return &ti_var; \
> >>> +} \
> >>> +uint64_t target_mask_selected(void) \
> >>> +{ \
> >>> + return QEMU_ARCH_BIT((ti_var).target_arch); \
> >>> }
> >>>
> >>> #else /* CONFIG_USER_ONLY */
> >>> diff --git a/include/qemu/target-info.h b/include/qemu/target-info.h
> >>> index 2cd4cc5671..5673d10eba 100644
> >>> --- a/include/qemu/target-info.h
> >>> +++ b/include/qemu/target-info.h
> >>> @@ -134,4 +134,13 @@ bool target_base_riscv(void);
> >>> */
> >>> bool target_riscv64(void);
> >>>
> >>> +/**
> >>> + * target_mask_selected:
> >>> + *
> >>> + * Returns the QEMU_ARCH_* mask of the selected target. System mode
> >>> + * returns QEMU_ARCH_ALL until a target is selected. User mode returns
> >>> + * that target's bit. Tools return 0.
> >>> + */
> >>> +uint64_t target_mask_selected(void);
> >>> +
> >>> #endif
> >>> diff --git a/stubs/meson.build b/stubs/meson.build
> >>> index 744fb759a2..49cede8582 100644
> >>> --- a/stubs/meson.build
> >>> +++ b/stubs/meson.build
> >>> @@ -12,6 +12,7 @@ stub_ss.add(files('monitor-hmp.c'))
> >>> stub_ss.add(files('qapi-event-emit.c'))
> >>> stub_ss.add(files('replay-mode.c'))
> >>> stub_ss.add(files('trace-control.c'))
> >>> +stub_ss.add(files('target-mask-selected.c'))
> >>>
> >>
> >> For which configs is the stub required?
> >> target-info-def will always be present.
> >
> > For tools
> >
>
> Can you post the exact link error that exposes the absence of this symbol?
There is very much, I extract part of them:
[61/389] Linking target tests/fp/fp-test
FAILED: [code=1] tests/fp/fp-test
gcc -m64 -o tests/fp/fp-test
libevent-loop-base.a.p/event-loop-base.c.o
libqom.a.p/qom_container.c.o libqom.a.p/qom_object.c.o
libqom.a.p/qom_object_interfaces.c.o libqom.a.p/qom_qom-qobject.c.o
libqom.a.p/qom_compat-properties.c.o tests/fp/fp-test.p/fp-test.c.o
tests/fp/fp-test.p/.._.._fpu_softfloat.c.o -Wl,--as-needed
-Wl,--no-undefined -pie -fstack-protector-strong -Wl,-z,relro
-Wl,-z,now -Wl,--start-group libqemuutil.a
subprojects/libvhost-user/libvhost-user-glib.a
subprojects/libvhost-user/libvhost-user.a
subprojects/berkeley-softfloat-3/libsoftfloat.a
subprojects/berkeley-testfloat-3/libtestfloat.a
subprojects/berkeley-testfloat-3/libslowfloat.a -lnuma
/usr/lib/x86_64-linux-gnu/liburing.so
/usr/lib/x86_64-linux-gnu/libgio-2.0.so
/usr/lib/x86_64-linux-gnu/libgobject-2.0.so
/usr/lib/x86_64-linux-gnu/libglib-2.0.so -Wl,--export-dynamic
/usr/lib/x86_64-linux-gnu/libgmodule-2.0.so -pthread -lm
/usr/lib/x86_64-linux-gnu/libpixman-1.so
/usr/lib/x86_64-linux-gnu/libepoxy.so -Wl,--end-group
/usr/bin/x86_64-linux-gnu-ld.bfd: libqom.a.p/qom_object.c.o: in
function `type_register_internal':
/build/release-amd64/../../qom/object.c:243:(.text+0x1c2): undefined
reference to `target_mask_selected'
/usr/bin/x86_64-linux-gnu-ld.bfd: libqom.a.p/qom_object.c.o: in
function `target_mask_filter':
/build/release-amd64/../../qom/object.c:120:(.text+0x1df): undefined
reference to `target_mask_selected'
/usr/bin/x86_64-linux-gnu-ld.bfd:
/build/release-amd64/../../qom/object.c:120:(.text+0x37a): undefined
reference to`target_mask_selected'
/usr/bin/x86_64-linux-gnu-ld.bfd:
/build/release-amd64/../../qom/object.c:120:(.text+0x1ebf): undefined
reference to `target_mask_selected'
collect2: error: ld returned 1 exit status
[62/389] Linking target tests/bench/benchmark-crypto-akcipher
FAILED: [code=1] tests/bench/benchmark-crypto-akcipher
gcc -m64 -o tests/bench/benchmark-crypto-akcipher
libevent-loop-base.a.p/event-loop-base.c.o
libqom.a.p/qom_container.c.o libqom.a.p/qom_object.c.o
libqom.a.p/qom_object_interfaces.c.o libqom.a.p/qom_qom-qobject.c.o
libqom.a.p/qom_compat-properties.c.o libcrypto.a.p/crypto_afsplit.c.o
libcrypto.a.p/crypto_akcipher.c.o libcrypto.a.p/crypto_block-luks.c.o
libcrypto.a.p/crypto_block-qcow.c.o libcrypto.a.p/crypto_block.c.o
libcrypto.a.p/crypto_cipher.c.o libcrypto.a.p/crypto_der.c.o
libcrypto.a.p/crypto_hash.c.o libcrypto.a.p/crypto_hmac.c.o
libcrypto.a.p/crypto_ivgen-essiv.c.o
libcrypto.a.p/crypto_ivgen-plain.c.o
libcrypto.a.p/crypto_ivgen-plain64.c.o libcrypto.a.p/crypto_ivgen.c.o
libcrypto.a.p/crypto_pbkdf.c.o libcrypto.a.p/crypto_secret_common.c.o
libcrypto.a.p/crypto_secret.c.o libcrypto.a.p/crypto_tlscreds.c.o
libcrypto.a.p/crypto_tlscredsanon.c.o
libcrypto.a.p/crypto_tlscredspsk.c.o
libcrypto.a.p/crypto_tlscredsx509.c.o
libcrypto.a.p/crypto_tlssession.c.o libcrypto.a.p/crypto_rsakey.c.o
libcrypto.a.p/crypto_x509-utils.c.o
libcrypto.a.p/crypto_hash-nettle.c.o
libcrypto.a.p/crypto_hmac-nettle.c.o
libcrypto.a.p/crypto_pbkdf-nettle.c.o
libcrypto.a.p/crypto_secret_keyring.c.o libauthz.a.p/authz_base.c.o
libauthz.a.p/authz_list.c.o libauthz.a.p/authz_listfile.c.o
libauthz.a.p/authz_simple.c.o
tests/bench/benchmark-crypto-akcipher.p/benchmark-crypto-akcipher.c.o
-Wl,--as-needed -Wl,--no-undefined -pie -fstack-protector-strong
-Wl,-z,relro -Wl,-z,now -Wl,--start-group libqemuutil.a
subprojects/libvhost-user/libvhost-user-glib.a
subprojects/libvhost-user/libvhost-user.a
/usr/lib/x86_64-linux-gnu/libnettle.so
/usr/lib/x86_64-linux-gnu/libgmp.so
/usr/lib/x86_64-linux-gnu/libhogweed.so -lnuma
/usr/lib/x86_64-linux-gnu/liburing.so
/usr/lib/x86_64-linux-gnu/libgio-2.0.so
/usr/lib/x86_64-linux-gnu/libgobject-2.0.so
/usr/lib/x86_64-linux-gnu/libglib-2.0.so -Wl,--export-dynamic
/usr/lib/x86_64-linux-gnu/libgmodule-2.0.so -pthread -lm
/usr/lib/x86_64-linux-gnu/libpixman-1.so
/usr/lib/x86_64-linux-gnu/libepoxy.so -Wl,--end-group
/usr/bin/x86_64-linux-gnu-ld.bfd: libqom.a.p/qom_object.c.o: in
function `type_register_internal':
/build/release-amd64/../../qom/object.c:243:(.text+0x1c2): undefined
reference to `target_mask_selected'
/usr/bin/x86_64-linux-gnu-ld.bfd: libqom.a.p/qom_object.c.o: in
function `target_mask_filter':
/build/release-amd64/../../qom/object.c:120:(.text+0x1df): undefined
reference to `target_mask_selected'
/usr/bin/x86_64-linux-gnu-ld.bfd:
/build/release-amd64/../../qom/object.c:120:(.text+0x37a): undefined
reference to`target_mask_selected'
/usr/bin/x86_64-linux-gnu-ld.bfd:
/build/release-amd64/../../qom/object.c:120:(.text+0x1ebf): undefined
reference to `target_mask_selected'
collect2: error: ld returned 1 exit status
[63/389] Linking target tests/bench/benchmark-crypto-hash
FAILED: [code=1] tests/bench/benchmark-crypto-hash
gcc -m64 -o tests/bench/benchmark-crypto-hash
libevent-loop-base.a.p/event-loop-base.c.o
libqom.a.p/qom_container.c.o libqom.a.p/qom_object.c.o
libqom.a.p/qom_object_interfaces.c.o libqom.a.p/qom_qom-qobject.c.o
libqom.a.p/qom_compat-properties.c.o libcrypto.a.p/crypto_afsplit.c.o
libcrypto.a.p/crypto_akcipher.c.o libcrypto.a.p/crypto_block-luks.c.o
libcrypto.a.p/crypto_block-qcow.c.o libcrypto.a.p/crypto_block.c.o
libcrypto.a.p/crypto_cipher.c.o libcrypto.a.p/crypto_der.c.o
libcrypto.a.p/crypto_hash.c.o libcrypto.a.p/crypto_hmac.c.o
libcrypto.a.p/crypto_ivgen-essiv.c.o
libcrypto.a.p/crypto_ivgen-plain.c.o
libcrypto.a.p/crypto_ivgen-plain64.c.o libcrypto.a.p/crypto_ivgen.c.o
libcrypto.a.p/crypto_pbkdf.c.o libcrypto.a.p/crypto_secret_common.c.o
libcrypto.a.p/crypto_secret.c.o libcrypto.a.p/crypto_tlscreds.c.o
libcrypto.a.p/crypto_tlscredsanon.c.o
libcrypto.a.p/crypto_tlscredspsk.c.o
libcrypto.a.p/crypto_tlscredsx509.c.o
libcrypto.a.p/crypto_tlssession.c.o libcrypto.a.p/crypto_rsakey.c.o
libcrypto.a.p/crypto_x509-utils.c.o
libcrypto.a.p/crypto_hash-nettle.c.o
libcrypto.a.p/crypto_hmac-nettle.c.o
libcrypto.a.p/crypto_pbkdf-nettle.c.o
libcrypto.a.p/crypto_secret_keyring.c.o libauthz.a.p/authz_base.c.o
libauthz.a.p/authz_list.c.o libauthz.a.p/authz_listfile.c.o
libauthz.a.p/authz_simple.c.o
tests/bench/benchmark-crypto-hash.p/benchmark-crypto-hash.c.o
-Wl,--as-needed -Wl,--no-undefined -pie -fstack-protector-strong
-Wl,-z,relro -Wl,-z,now -Wl,--start-group libqemuutil.a
subprojects/libvhost-user/libvhost-user-glib.a
subprojects/libvhost-user/libvhost-user.a
/usr/lib/x86_64-linux-gnu/libnettle.so
/usr/lib/x86_64-linux-gnu/libgmp.so
/usr/lib/x86_64-linux-gnu/libhogweed.so -lnuma
/usr/lib/x86_64-linux-gnu/liburing.so
/usr/lib/x86_64-linux-gnu/libgio-2.0.so
/usr/lib/x86_64-linux-gnu/libgobject-2.0.so
/usr/lib/x86_64-linux-gnu/libglib-2.0.so -Wl,--export-dynamic
/usr/lib/x86_64-linux-gnu/libgmodule-2.0.so -pthread -lm
/usr/lib/x86_64-linux-gnu/libpixman-1.so
/usr/lib/x86_64-linux-gnu/libepoxy.so -Wl,--end-group
/usr/bin/x86_64-linux-gnu-ld.bfd: libqom.a.p/qom_object.c.o: in
function `type_register_internal':
/build/release-amd64/../../qom/object.c:243:(.text+0x1c2): undefined
reference to `target_mask_selected'
/usr/bin/x86_64-linux-gnu-ld.bfd: libqom.a.p/qom_object.c.o: in
function `target_mask_filter':
/build/release-amd64/../../qom/object.c:120:(.text+0x1df): undefined
reference to `target_mask_selected'
/usr/bin/x86_64-linux-gnu-ld.bfd:
/build/release-amd64/../../qom/object.c:120:(.text+0x37a): undefined
reference to`target_mask_selected'
/usr/bin/x86_64-linux-gnu-ld.bfd:
/build/release-amd64/../../qom/object.c:120:(.text+0x1ebf): undefined
reference to `target_mask_selected'
collect2: error: ld returned 1 exit status
[64/389] Linking target tools/qemu-vnc/qemu-vnc
FAILED: [code=1] tools/qemu-vnc/qemu-vnc
gcc -m64 -o tools/qemu-vnc/qemu-vnc
tools/qemu-vnc/qemu-vnc.p/meson-generated_.._.._.._ui_dbus-display1.c.o
tools/qemu-vnc/qemu-vnc.p/meson-generated_.._qemu-vnc1.c.o
libio.a.p/io_channel-buffer.c.o libio.a.p/io_channel-command.c.o
libio.a.p/io_channel-file.c.o libio.a.p/io_channel-null.c.o
libio.a.p/io_channel-socket.c.o libio.a.p/io_channel-tls.c.o
libio.a.p/io_channel-util.c.o libio.a.p/io_channel-watch.c.o
libio.a.p/io_channel-websock.c.o libio.a.p/io_channel.c.o
libio.a.p/io_dns-resolver.c.o libio.a.p/io_net-listener.c.o
libio.a.p/io_task.c.o libcrypto.a.p/crypto_afsplit.c.o
libcrypto.a.p/crypto_akcipher.c.o libcrypto.a.p/crypto_block-luks.c.o
libcrypto.a.p/crypto_block-qcow.c.o libcrypto.a.p/crypto_block.c.o
libcrypto.a.p/crypto_cipher.c.o libcrypto.a.p/crypto_der.c.o
libcrypto.a.p/crypto_hash.c.o libcrypto.a.p/crypto_hmac.c.o
libcrypto.a.p/crypto_ivgen-essiv.c.o
libcrypto.a.p/crypto_ivgen-plain.c.o
libcrypto.a.p/crypto_ivgen-plain64.c.o libcrypto.a.p/crypto_ivgen.c.o
libcrypto.a.p/crypto_pbkdf.c.o libcrypto.a.p/crypto_secret_common.c.o
libcrypto.a.p/crypto_secret.c.o libcrypto.a.p/crypto_tlscreds.c.o
libcrypto.a.p/crypto_tlscredsanon.c.o
libcrypto.a.p/crypto_tlscredspsk.c.o
libcrypto.a.p/crypto_tlscredsx509.c.o
libcrypto.a.p/crypto_tlssession.c.o libcrypto.a.p/crypto_rsakey.c.o
libcrypto.a.p/crypto_x509-utils.c.o
libcrypto.a.p/crypto_hash-nettle.c.o
libcrypto.a.p/crypto_hmac-nettle.c.o
libcrypto.a.p/crypto_pbkdf-nettle.c.o
libcrypto.a.p/crypto_secret_keyring.c.o libauthz.a.p/authz_base.c.o
libauthz.a.p/authz_list.c.o libauthz.a.p/authz_listfile.c.o
libauthz.a.p/authz_simple.c.o libqom.a.p/qom_container.c.o
libqom.a.p/qom_object.c.o libqom.a.p/qom_object_interfaces.c.o
libqom.a.p/qom_qom-qobject.c.o libqom.a.p/qom_compat-properties.c.o
libevent-loop-base.a.p/event-loop-base.c.o
ui/libqemuui.a.p/clipboard.c.o ui/libqemuui.a.p/console.c.o
ui/libqemuui.a.p/cursor.c.o ui/libqemuui.a.p/dmabuf.c.o
ui/libqemuui.a.p/display-surface.c.o ui/libqemuui.a.p/input-keymap.c.o
ui/libqemuui.a.p/kbd-state.c.o ui/libqemuui.a.p/keymaps.c.o
ui/libqemuui.a.p/qemu-pixman.c.o ui/libqemuui.a.p/spice-module.c.o
ui/libqemuui.a.p/vgafont.c.o ui/libqemuui.a.p/cp437.c.o
ui/libqemuui.a.p/vt100.c.o tools/qemu-vnc/qemu-vnc.p/qemu-vnc.c.o
tools/qemu-vnc/qemu-vnc.p/display.c.o
tools/qemu-vnc/qemu-vnc.p/input.c.o
tools/qemu-vnc/qemu-vnc.p/audio.c.o
tools/qemu-vnc/qemu-vnc.p/chardev.c.o
tools/qemu-vnc/qemu-vnc.p/clipboard.c.o
tools/qemu-vnc/qemu-vnc.p/console.c.o
tools/qemu-vnc/qemu-vnc.p/dbus.c.o tools/qemu-vnc/qemu-vnc.p/stubs.c.o
tools/qemu-vnc/qemu-vnc.p/utils.c.o
tools/qemu-vnc/qemu-vnc.p/.._.._ui_vnc.c.o
tools/qemu-vnc/qemu-vnc.p/.._.._ui_vnc-enc-zlib.c.o
tools/qemu-vnc/qemu-vnc.p/.._.._ui_vnc-enc-hextile.c.o
tools/qemu-vnc/qemu-vnc.p/.._.._ui_vnc-enc-tight.c.o
tools/qemu-vnc/qemu-vnc.p/.._.._ui_vnc-palette.c.o
tools/qemu-vnc/qemu-vnc.p/.._.._ui_vnc-enc-zrle.c.o
tools/qemu-vnc/qemu-vnc.p/.._.._ui_vnc-auth-vencrypt.c.o
tools/qemu-vnc/qemu-vnc.p/.._.._ui_vnc-ws.c.o
tools/qemu-vnc/qemu-vnc.p/.._.._ui_vnc-jobs.c.o
tools/qemu-vnc/qemu-vnc.p/.._.._ui_vnc-clipboard.c.o
tools/qemu-vnc/qemu-vnc.p/.._.._ui_vnc-auth-sasl.c.o -Wl,--as-needed
-Wl,--no-undefined -pie -fstack-protector-strong -Wl,-z,relro
-Wl,-z,now -Wl,--start-group libqemuutil.a
subprojects/libvhost-user/libvhost-user-glib.a
subprojects/libvhost-user/libvhost-user.a
/usr/lib/x86_64-linux-gnu/libz.so /usr/lib/x86_64-linux-gnu/libjpeg.so
/usr/lib/x86_64-linux-gnu/libpng16.so -lsasl2
/usr/lib/x86_64-linux-gnu/libnettle.so
/usr/lib/x86_64-linux-gnu/libgmp.so
/usr/lib/x86_64-linux-gnu/libhogweed.so
/usr/lib/x86_64-linux-gnu/libgio-2.0.so/usr/lib/x86_64-linux-gnu/libgobject-2.0.so
/usr/lib/x86_64-linux-gnu/libglib-2.0.so
/usr/lib/x86_64-linux-gnu/libpixman-1.so -lnuma
/usr/lib/x86_64-linux-gnu/liburing.so -Wl,--export-dynamic
/usr/lib/x86_64-linux-gnu/libgmodule-2.0.so -pthread -lm
/usr/lib/x86_64-linux-gnu/libepoxy.so -Wl,--end-group
/usr/bin/x86_64-linux-gnu-ld.bfd: libqom.a.p/qom_object.c.o: in
function `type_register_internal':
/build/release-amd64/../../qom/object.c:243:(.text+0x1c2): undefined
reference to `target_mask_selected'
/usr/bin/x86_64-linux-gnu-ld.bfd: libqom.a.p/qom_object.c.o: in
function `target_mask_filter':
/build/release-amd64/../../qom/object.c:120:(.text+0x1df): undefined
reference to `target_mask_selected'
/usr/bin/x86_64-linux-gnu-ld.bfd:
/build/release-amd64/../../qom/object.c:120:(.text+0x37a): undefined
reference to`target_mask_selected'
/usr/bin/x86_64-linux-gnu-ld.bfd:
/build/release-amd64/../../qom/object.c:120:(.text+0x1ebf): undefined
reference to `target_mask_selected'
collect2: error: ld returned 1 exit status
[65/389] Generating block.syms with a custom command (wrapped by meson
to capture output)
[66/389] Generating qemu.syms with a custom command (wrapped by meson
to capture output)
>
> >>
> >>> if have_block
> >>> stub_ss.add(files('bdrv-next-monitor-owned.c'))
> >>> diff --git a/stubs/target-mask-selected.c b/stubs/target-mask-selected.c
> >>> new file mode 100644
> >>> index 0000000000..510a515851
> >>> --- /dev/null
> >>> +++ b/stubs/target-mask-selected.c
> >>> @@ -0,0 +1,13 @@
> >>> +/*
> >>> + * Tools have no selected target.
> >>> + *
> >>> + * SPDX-License-Identifier: GPL-2.0-or-later
> >>> + */
> >>> +
> >>> +#include "qemu/osdep.h"
> >>> +#include "qemu/target-info.h"
> >>> +
> >>> +uint64_t target_mask_selected(void)
> >>> +{
> >>> + return 0;
> >>> +}
> >>> diff --git a/target-info-def.c b/target-info-def.c
> >>> index bcf9cfe1e4..a992019626 100644
> >>> --- a/target-info-def.c
> >>> +++ b/target-info-def.c
> >>> @@ -9,6 +9,9 @@
> >>> #include "qemu/osdep.h"
> >>> #include "qemu/target-info.h"
> >>> #include "qemu/target-info-def.h"
> >>> +#ifdef CONFIG_USER_ONLY
> >>> +#include "qemu/base-arch-defs.h"
> >>> +#endif
> >>> #include "qemu/target-info-init.h"
> >>> #include "hw/core/boards.h"
> >>> #include "cpu.h"
> >>> diff --git a/target-info-qom.c b/target-info-qom.c
> >>> index aeeedb7e81..fb4c9835e5 100644
> >>> --- a/target-info-qom.c
> >>> +++ b/target-info-qom.c
> >>> @@ -9,6 +9,8 @@
> >>> #include "qemu/osdep.h"
> >>> #include "qapi/error.h"
> >>> #include "qom/object.h"
> >>> +#include "qemu/base-arch-defs.h"
> >>> +#include "qemu/target-info.h"
> >>> #include "qemu/target-info-def.h"
> >>> #include "qemu/target-info-init.h"
> >>> #include "qemu/target-info-qom.h"
> >>> @@ -40,6 +42,14 @@ const TargetInfo *target_info(void)
> >>> return target_info_ptr;
> >>> }
> >>>
> >>> +uint64_t target_mask_selected(void)
> >>> +{
> >>> + if (!target_info_ptr) {
> >>> + return QEMU_ARCH_ALL;
> >>> + }
> >>> + return QEMU_ARCH_BIT(target_info_ptr->target_arch);
> >>> +}
> >>> +
> >>> void target_info_qom_set_target(void)
> >>> {
> >>> g_autoptr(GSList) targets = object_class_get_list(TYPE_TARGET_INFO, false);
> >>
> >
> >
>
--
此致
礼
罗勇刚
Yours
sincerely,
Yonggang Luo
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/5] target-info: add target_mask_selected()
2026-11-06 19:52 ` Yonggang Luo
@ 2026-11-06 20:19 ` Pierrick Bouvier
0 siblings, 0 replies; 14+ messages in thread
From: Pierrick Bouvier @ 2026-11-06 20:19 UTC (permalink / raw)
To: luoyonggang
Cc: qemu-devel, Philippe Mathieu-Daudé, Paolo Bonzini,
Daniel P. Berrangé, Philippe Mathieu-Daude
On 11/6/2026 11:52 AM, Yonggang Luo wrote:
> On Sat, Nov 7, 2026 at 1:47 AM Pierrick Bouvier
> <pierrick.bouvier@oss.qualcomm.com> wrote:
>>
>> On 11/6/2026 9:46 AM, Yonggang Luo wrote:
>>> On Sat, Nov 7, 2026 at 1:44 AM Pierrick Bouvier
>>> <pierrick.bouvier@oss.qualcomm.com> wrote:
>>>>
>>>> On 11/5/2026 11:03 AM, Yonggang Luo wrote:
>>>>> Return the QEMU_ARCH_* mask of the selected target. System mode
>>>>> returns QEMU_ARCH_ALL until a target is selected. User mode returns
>>>>> that target's bit. Tools return 0.
>>>>>
>>>>> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
>>>>> ---
>>>>> include/qemu/target-info-init.h | 15 ++++++++++-----
>>>>> include/qemu/target-info.h | 9 +++++++++
>>>>> stubs/meson.build | 1 +
>>>>> stubs/target-mask-selected.c | 13 +++++++++++++
>>>>> target-info-def.c | 3 +++
>>>>> target-info-qom.c | 10 ++++++++++
>>>>> 6 files changed, 46 insertions(+), 5 deletions(-)
>>>>> create mode 100644 stubs/target-mask-selected.c
>>>>>
>>>>> diff --git a/include/qemu/target-info-init.h b/include/qemu/target-info-init.h
>>>>> index b7024c9fae..8492986832 100644
>>>>> --- a/include/qemu/target-info-init.h
>>>>> +++ b/include/qemu/target-info-init.h
>>>>> @@ -24,12 +24,17 @@ module_init(do_qemu_init_target_info, MODULE_INIT_TARGET_INFO)
>>>>>
>>>>> /*
>>>>> * User mode does not support multiple targets in the same binary, so just
>>>>> - * define target_info().
>>>>> + * define target_info() and target_mask_selected(). The target is always
>>>>> + * selected.
>>>>> */
>>>>> -#define target_info_init(ti_var) \
>>>>> -const TargetInfo *target_info(void) \
>>>>> -{ \
>>>>> - return &ti_var; \
>>>>> +#define target_info_init(ti_var) \
>>>>> +const TargetInfo *target_info(void) \
>>>>> +{ \
>>>>> + return &ti_var; \
>>>>> +} \
>>>>> +uint64_t target_mask_selected(void) \
>>>>> +{ \
>>>>> + return QEMU_ARCH_BIT((ti_var).target_arch); \
>>>>> }
>>>>>
>>>>> #else /* CONFIG_USER_ONLY */
>>>>> diff --git a/include/qemu/target-info.h b/include/qemu/target-info.h
>>>>> index 2cd4cc5671..5673d10eba 100644
>>>>> --- a/include/qemu/target-info.h
>>>>> +++ b/include/qemu/target-info.h
>>>>> @@ -134,4 +134,13 @@ bool target_base_riscv(void);
>>>>> */
>>>>> bool target_riscv64(void);
>>>>>
>>>>> +/**
>>>>> + * target_mask_selected:
>>>>> + *
>>>>> + * Returns the QEMU_ARCH_* mask of the selected target. System mode
>>>>> + * returns QEMU_ARCH_ALL until a target is selected. User mode returns
>>>>> + * that target's bit. Tools return 0.
>>>>> + */
>>>>> +uint64_t target_mask_selected(void);
>>>>> +
>>>>> #endif
>>>>> diff --git a/stubs/meson.build b/stubs/meson.build
>>>>> index 744fb759a2..49cede8582 100644
>>>>> --- a/stubs/meson.build
>>>>> +++ b/stubs/meson.build
>>>>> @@ -12,6 +12,7 @@ stub_ss.add(files('monitor-hmp.c'))
>>>>> stub_ss.add(files('qapi-event-emit.c'))
>>>>> stub_ss.add(files('replay-mode.c'))
>>>>> stub_ss.add(files('trace-control.c'))
>>>>> +stub_ss.add(files('target-mask-selected.c'))
>>>>>
>>>>
>>>> For which configs is the stub required?
>>>> target-info-def will always be present.
>>>
>>> For tools
>>>
>>
>> Can you post the exact link error that exposes the absence of this symbol?
>
> There is very much, I extract part of them:
>
>
> [61/389] Linking target tests/fp/fp-test
> FAILED: [code=1] tests/fp/fp-test
> gcc -m64 -o tests/fp/fp-test
> libevent-loop-base.a.p/event-loop-base.c.o
> libqom.a.p/qom_container.c.o libqom.a.p/qom_object.c.o
> libqom.a.p/qom_object_interfaces.c.o libqom.a.p/qom_qom-qobject.c.o
> libqom.a.p/qom_compat-properties.c.o tests/fp/fp-test.p/fp-test.c.o
> tests/fp/fp-test.p/.._.._fpu_softfloat.c.o -Wl,--as-needed
> -Wl,--no-undefined -pie -fstack-protector-strong -Wl,-z,relro
> -Wl,-z,now -Wl,--start-group libqemuutil.a
> subprojects/libvhost-user/libvhost-user-glib.a
> subprojects/libvhost-user/libvhost-user.a
> subprojects/berkeley-softfloat-3/libsoftfloat.a
> subprojects/berkeley-testfloat-3/libtestfloat.a
> subprojects/berkeley-testfloat-3/libslowfloat.a -lnuma
> /usr/lib/x86_64-linux-gnu/liburing.so
> /usr/lib/x86_64-linux-gnu/libgio-2.0.so
> /usr/lib/x86_64-linux-gnu/libgobject-2.0.so
> /usr/lib/x86_64-linux-gnu/libglib-2.0.so -Wl,--export-dynamic
> /usr/lib/x86_64-linux-gnu/libgmodule-2.0.so -pthread -lm
> /usr/lib/x86_64-linux-gnu/libpixman-1.so
> /usr/lib/x86_64-linux-gnu/libepoxy.so -Wl,--end-group
> /usr/bin/x86_64-linux-gnu-ld.bfd: libqom.a.p/qom_object.c.o: in
> function `type_register_internal':
> /build/release-amd64/../../qom/object.c:243:(.text+0x1c2): undefined
> reference to `target_mask_selected'
> /usr/bin/x86_64-linux-gnu-ld.bfd: libqom.a.p/qom_object.c.o: in
> function `target_mask_filter':
> /build/release-amd64/../../qom/object.c:120:(.text+0x1df): undefined
> reference to `target_mask_selected'
> /usr/bin/x86_64-linux-gnu-ld.bfd:
> /build/release-amd64/../../qom/object.c:120:(.text+0x37a): undefined
> reference to`target_mask_selected'
> /usr/bin/x86_64-linux-gnu-ld.bfd:
> /build/release-amd64/../../qom/object.c:120:(.text+0x1ebf): undefined
> reference to `target_mask_selected'
> collect2: error: ld returned 1 exit status
> [62/389] Linking target tests/bench/benchmark-crypto-akcipher
> FAILED: [code=1] tests/bench/benchmark-crypto-akcipher
> gcc -m64 -o tests/bench/benchmark-crypto-akcipher
> libevent-loop-base.a.p/event-loop-base.c.o
> libqom.a.p/qom_container.c.o libqom.a.p/qom_object.c.o
> libqom.a.p/qom_object_interfaces.c.o libqom.a.p/qom_qom-qobject.c.o
> libqom.a.p/qom_compat-properties.c.o libcrypto.a.p/crypto_afsplit.c.o
> libcrypto.a.p/crypto_akcipher.c.o libcrypto.a.p/crypto_block-luks.c.o
> libcrypto.a.p/crypto_block-qcow.c.o libcrypto.a.p/crypto_block.c.o
> libcrypto.a.p/crypto_cipher.c.o libcrypto.a.p/crypto_der.c.o
> libcrypto.a.p/crypto_hash.c.o libcrypto.a.p/crypto_hmac.c.o
> libcrypto.a.p/crypto_ivgen-essiv.c.o
> libcrypto.a.p/crypto_ivgen-plain.c.o
> libcrypto.a.p/crypto_ivgen-plain64.c.o libcrypto.a.p/crypto_ivgen.c.o
> libcrypto.a.p/crypto_pbkdf.c.o libcrypto.a.p/crypto_secret_common.c.o
> libcrypto.a.p/crypto_secret.c.o libcrypto.a.p/crypto_tlscreds.c.o
> libcrypto.a.p/crypto_tlscredsanon.c.o
> libcrypto.a.p/crypto_tlscredspsk.c.o
> libcrypto.a.p/crypto_tlscredsx509.c.o
> libcrypto.a.p/crypto_tlssession.c.o libcrypto.a.p/crypto_rsakey.c.o
> libcrypto.a.p/crypto_x509-utils.c.o
> libcrypto.a.p/crypto_hash-nettle.c.o
> libcrypto.a.p/crypto_hmac-nettle.c.o
> libcrypto.a.p/crypto_pbkdf-nettle.c.o
> libcrypto.a.p/crypto_secret_keyring.c.o libauthz.a.p/authz_base.c.o
> libauthz.a.p/authz_list.c.o libauthz.a.p/authz_listfile.c.o
> libauthz.a.p/authz_simple.c.o
> tests/bench/benchmark-crypto-akcipher.p/benchmark-crypto-akcipher.c.o
> -Wl,--as-needed -Wl,--no-undefined -pie -fstack-protector-strong
> -Wl,-z,relro -Wl,-z,now -Wl,--start-group libqemuutil.a
> subprojects/libvhost-user/libvhost-user-glib.a
> subprojects/libvhost-user/libvhost-user.a
> /usr/lib/x86_64-linux-gnu/libnettle.so
> /usr/lib/x86_64-linux-gnu/libgmp.so
> /usr/lib/x86_64-linux-gnu/libhogweed.so -lnuma
> /usr/lib/x86_64-linux-gnu/liburing.so
> /usr/lib/x86_64-linux-gnu/libgio-2.0.so
> /usr/lib/x86_64-linux-gnu/libgobject-2.0.so
> /usr/lib/x86_64-linux-gnu/libglib-2.0.so -Wl,--export-dynamic
> /usr/lib/x86_64-linux-gnu/libgmodule-2.0.so -pthread -lm
> /usr/lib/x86_64-linux-gnu/libpixman-1.so
> /usr/lib/x86_64-linux-gnu/libepoxy.so -Wl,--end-group
> /usr/bin/x86_64-linux-gnu-ld.bfd: libqom.a.p/qom_object.c.o: in
> function `type_register_internal':
> /build/release-amd64/../../qom/object.c:243:(.text+0x1c2): undefined
> reference to `target_mask_selected'
> /usr/bin/x86_64-linux-gnu-ld.bfd: libqom.a.p/qom_object.c.o: in
> function `target_mask_filter':
> /build/release-amd64/../../qom/object.c:120:(.text+0x1df): undefined
> reference to `target_mask_selected'
> /usr/bin/x86_64-linux-gnu-ld.bfd:
> /build/release-amd64/../../qom/object.c:120:(.text+0x37a): undefined
> reference to`target_mask_selected'
> /usr/bin/x86_64-linux-gnu-ld.bfd:
> /build/release-amd64/../../qom/object.c:120:(.text+0x1ebf): undefined
> reference to `target_mask_selected'
> collect2: error: ld returned 1 exit status
> [63/389] Linking target tests/bench/benchmark-crypto-hash
> FAILED: [code=1] tests/bench/benchmark-crypto-hash
> gcc -m64 -o tests/bench/benchmark-crypto-hash
> libevent-loop-base.a.p/event-loop-base.c.o
> libqom.a.p/qom_container.c.o libqom.a.p/qom_object.c.o
> libqom.a.p/qom_object_interfaces.c.o libqom.a.p/qom_qom-qobject.c.o
> libqom.a.p/qom_compat-properties.c.o libcrypto.a.p/crypto_afsplit.c.o
> libcrypto.a.p/crypto_akcipher.c.o libcrypto.a.p/crypto_block-luks.c.o
> libcrypto.a.p/crypto_block-qcow.c.o libcrypto.a.p/crypto_block.c.o
> libcrypto.a.p/crypto_cipher.c.o libcrypto.a.p/crypto_der.c.o
> libcrypto.a.p/crypto_hash.c.o libcrypto.a.p/crypto_hmac.c.o
> libcrypto.a.p/crypto_ivgen-essiv.c.o
> libcrypto.a.p/crypto_ivgen-plain.c.o
> libcrypto.a.p/crypto_ivgen-plain64.c.o libcrypto.a.p/crypto_ivgen.c.o
> libcrypto.a.p/crypto_pbkdf.c.o libcrypto.a.p/crypto_secret_common.c.o
> libcrypto.a.p/crypto_secret.c.o libcrypto.a.p/crypto_tlscreds.c.o
> libcrypto.a.p/crypto_tlscredsanon.c.o
> libcrypto.a.p/crypto_tlscredspsk.c.o
> libcrypto.a.p/crypto_tlscredsx509.c.o
> libcrypto.a.p/crypto_tlssession.c.o libcrypto.a.p/crypto_rsakey.c.o
> libcrypto.a.p/crypto_x509-utils.c.o
> libcrypto.a.p/crypto_hash-nettle.c.o
> libcrypto.a.p/crypto_hmac-nettle.c.o
> libcrypto.a.p/crypto_pbkdf-nettle.c.o
> libcrypto.a.p/crypto_secret_keyring.c.o libauthz.a.p/authz_base.c.o
> libauthz.a.p/authz_list.c.o libauthz.a.p/authz_listfile.c.o
> libauthz.a.p/authz_simple.c.o
> tests/bench/benchmark-crypto-hash.p/benchmark-crypto-hash.c.o
> -Wl,--as-needed -Wl,--no-undefined -pie -fstack-protector-strong
> -Wl,-z,relro -Wl,-z,now -Wl,--start-group libqemuutil.a
> subprojects/libvhost-user/libvhost-user-glib.a
> subprojects/libvhost-user/libvhost-user.a
> /usr/lib/x86_64-linux-gnu/libnettle.so
> /usr/lib/x86_64-linux-gnu/libgmp.so
> /usr/lib/x86_64-linux-gnu/libhogweed.so -lnuma
> /usr/lib/x86_64-linux-gnu/liburing.so
> /usr/lib/x86_64-linux-gnu/libgio-2.0.so
> /usr/lib/x86_64-linux-gnu/libgobject-2.0.so
> /usr/lib/x86_64-linux-gnu/libglib-2.0.so -Wl,--export-dynamic
> /usr/lib/x86_64-linux-gnu/libgmodule-2.0.so -pthread -lm
> /usr/lib/x86_64-linux-gnu/libpixman-1.so
> /usr/lib/x86_64-linux-gnu/libepoxy.so -Wl,--end-group
> /usr/bin/x86_64-linux-gnu-ld.bfd: libqom.a.p/qom_object.c.o: in
> function `type_register_internal':
> /build/release-amd64/../../qom/object.c:243:(.text+0x1c2): undefined
> reference to `target_mask_selected'
> /usr/bin/x86_64-linux-gnu-ld.bfd: libqom.a.p/qom_object.c.o: in
> function `target_mask_filter':
> /build/release-amd64/../../qom/object.c:120:(.text+0x1df): undefined
> reference to `target_mask_selected'
> /usr/bin/x86_64-linux-gnu-ld.bfd:
> /build/release-amd64/../../qom/object.c:120:(.text+0x37a): undefined
> reference to`target_mask_selected'
> /usr/bin/x86_64-linux-gnu-ld.bfd:
> /build/release-amd64/../../qom/object.c:120:(.text+0x1ebf): undefined
> reference to `target_mask_selected'
> collect2: error: ld returned 1 exit status
> [64/389] Linking target tools/qemu-vnc/qemu-vnc
> FAILED: [code=1] tools/qemu-vnc/qemu-vnc
> gcc -m64 -o tools/qemu-vnc/qemu-vnc
> tools/qemu-vnc/qemu-vnc.p/meson-generated_.._.._.._ui_dbus-display1.c.o
> tools/qemu-vnc/qemu-vnc.p/meson-generated_.._qemu-vnc1.c.o
> libio.a.p/io_channel-buffer.c.o libio.a.p/io_channel-command.c.o
> libio.a.p/io_channel-file.c.o libio.a.p/io_channel-null.c.o
> libio.a.p/io_channel-socket.c.o libio.a.p/io_channel-tls.c.o
> libio.a.p/io_channel-util.c.o libio.a.p/io_channel-watch.c.o
> libio.a.p/io_channel-websock.c.o libio.a.p/io_channel.c.o
> libio.a.p/io_dns-resolver.c.o libio.a.p/io_net-listener.c.o
> libio.a.p/io_task.c.o libcrypto.a.p/crypto_afsplit.c.o
> libcrypto.a.p/crypto_akcipher.c.o libcrypto.a.p/crypto_block-luks.c.o
> libcrypto.a.p/crypto_block-qcow.c.o libcrypto.a.p/crypto_block.c.o
> libcrypto.a.p/crypto_cipher.c.o libcrypto.a.p/crypto_der.c.o
> libcrypto.a.p/crypto_hash.c.o libcrypto.a.p/crypto_hmac.c.o
> libcrypto.a.p/crypto_ivgen-essiv.c.o
> libcrypto.a.p/crypto_ivgen-plain.c.o
> libcrypto.a.p/crypto_ivgen-plain64.c.o libcrypto.a.p/crypto_ivgen.c.o
> libcrypto.a.p/crypto_pbkdf.c.o libcrypto.a.p/crypto_secret_common.c.o
> libcrypto.a.p/crypto_secret.c.o libcrypto.a.p/crypto_tlscreds.c.o
> libcrypto.a.p/crypto_tlscredsanon.c.o
> libcrypto.a.p/crypto_tlscredspsk.c.o
> libcrypto.a.p/crypto_tlscredsx509.c.o
> libcrypto.a.p/crypto_tlssession.c.o libcrypto.a.p/crypto_rsakey.c.o
> libcrypto.a.p/crypto_x509-utils.c.o
> libcrypto.a.p/crypto_hash-nettle.c.o
> libcrypto.a.p/crypto_hmac-nettle.c.o
> libcrypto.a.p/crypto_pbkdf-nettle.c.o
> libcrypto.a.p/crypto_secret_keyring.c.o libauthz.a.p/authz_base.c.o
> libauthz.a.p/authz_list.c.o libauthz.a.p/authz_listfile.c.o
> libauthz.a.p/authz_simple.c.o libqom.a.p/qom_container.c.o
> libqom.a.p/qom_object.c.o libqom.a.p/qom_object_interfaces.c.o
> libqom.a.p/qom_qom-qobject.c.o libqom.a.p/qom_compat-properties.c.o
> libevent-loop-base.a.p/event-loop-base.c.o
> ui/libqemuui.a.p/clipboard.c.o ui/libqemuui.a.p/console.c.o
> ui/libqemuui.a.p/cursor.c.o ui/libqemuui.a.p/dmabuf.c.o
> ui/libqemuui.a.p/display-surface.c.o ui/libqemuui.a.p/input-keymap.c.o
> ui/libqemuui.a.p/kbd-state.c.o ui/libqemuui.a.p/keymaps.c.o
> ui/libqemuui.a.p/qemu-pixman.c.o ui/libqemuui.a.p/spice-module.c.o
> ui/libqemuui.a.p/vgafont.c.o ui/libqemuui.a.p/cp437.c.o
> ui/libqemuui.a.p/vt100.c.o tools/qemu-vnc/qemu-vnc.p/qemu-vnc.c.o
> tools/qemu-vnc/qemu-vnc.p/display.c.o
> tools/qemu-vnc/qemu-vnc.p/input.c.o
> tools/qemu-vnc/qemu-vnc.p/audio.c.o
> tools/qemu-vnc/qemu-vnc.p/chardev.c.o
> tools/qemu-vnc/qemu-vnc.p/clipboard.c.o
> tools/qemu-vnc/qemu-vnc.p/console.c.o
> tools/qemu-vnc/qemu-vnc.p/dbus.c.o tools/qemu-vnc/qemu-vnc.p/stubs.c.o
> tools/qemu-vnc/qemu-vnc.p/utils.c.o
> tools/qemu-vnc/qemu-vnc.p/.._.._ui_vnc.c.o
> tools/qemu-vnc/qemu-vnc.p/.._.._ui_vnc-enc-zlib.c.o
> tools/qemu-vnc/qemu-vnc.p/.._.._ui_vnc-enc-hextile.c.o
> tools/qemu-vnc/qemu-vnc.p/.._.._ui_vnc-enc-tight.c.o
> tools/qemu-vnc/qemu-vnc.p/.._.._ui_vnc-palette.c.o
> tools/qemu-vnc/qemu-vnc.p/.._.._ui_vnc-enc-zrle.c.o
> tools/qemu-vnc/qemu-vnc.p/.._.._ui_vnc-auth-vencrypt.c.o
> tools/qemu-vnc/qemu-vnc.p/.._.._ui_vnc-ws.c.o
> tools/qemu-vnc/qemu-vnc.p/.._.._ui_vnc-jobs.c.o
> tools/qemu-vnc/qemu-vnc.p/.._.._ui_vnc-clipboard.c.o
> tools/qemu-vnc/qemu-vnc.p/.._.._ui_vnc-auth-sasl.c.o -Wl,--as-needed
> -Wl,--no-undefined -pie -fstack-protector-strong -Wl,-z,relro
> -Wl,-z,now -Wl,--start-group libqemuutil.a
> subprojects/libvhost-user/libvhost-user-glib.a
> subprojects/libvhost-user/libvhost-user.a
> /usr/lib/x86_64-linux-gnu/libz.so /usr/lib/x86_64-linux-gnu/libjpeg.so
> /usr/lib/x86_64-linux-gnu/libpng16.so -lsasl2
> /usr/lib/x86_64-linux-gnu/libnettle.so
> /usr/lib/x86_64-linux-gnu/libgmp.so
> /usr/lib/x86_64-linux-gnu/libhogweed.so
> /usr/lib/x86_64-linux-gnu/libgio-2.0.so/usr/lib/x86_64-linux-gnu/libgobject-2.0.so
> /usr/lib/x86_64-linux-gnu/libglib-2.0.so
> /usr/lib/x86_64-linux-gnu/libpixman-1.so -lnuma
> /usr/lib/x86_64-linux-gnu/liburing.so -Wl,--export-dynamic
> /usr/lib/x86_64-linux-gnu/libgmodule-2.0.so -pthread -lm
> /usr/lib/x86_64-linux-gnu/libepoxy.so -Wl,--end-group
> /usr/bin/x86_64-linux-gnu-ld.bfd: libqom.a.p/qom_object.c.o: in
> function `type_register_internal':
> /build/release-amd64/../../qom/object.c:243:(.text+0x1c2): undefined
> reference to `target_mask_selected'
> /usr/bin/x86_64-linux-gnu-ld.bfd: libqom.a.p/qom_object.c.o: in
> function `target_mask_filter':
> /build/release-amd64/../../qom/object.c:120:(.text+0x1df): undefined
> reference to `target_mask_selected'
> /usr/bin/x86_64-linux-gnu-ld.bfd:
> /build/release-amd64/../../qom/object.c:120:(.text+0x37a): undefined
> reference to`target_mask_selected'
> /usr/bin/x86_64-linux-gnu-ld.bfd:
> /build/release-amd64/../../qom/object.c:120:(.text+0x1ebf): undefined
> reference to `target_mask_selected'
> collect2: error: ld returned 1 exit status
> [65/389] Generating block.syms with a custom command (wrapped by meson
> to capture output)
> [66/389] Generating qemu.syms with a custom command (wrapped by meson
> to capture output)
>
Thanks, that's indeed coming with patch 4. In case we don't pursuit with
buckets approach, stub can be removed from this patch.
>
>>
>>>>
>>>>> if have_block
>>>>> stub_ss.add(files('bdrv-next-monitor-owned.c'))
>>>>> diff --git a/stubs/target-mask-selected.c b/stubs/target-mask-selected.c
>>>>> new file mode 100644
>>>>> index 0000000000..510a515851
>>>>> --- /dev/null
>>>>> +++ b/stubs/target-mask-selected.c
>>>>> @@ -0,0 +1,13 @@
>>>>> +/*
>>>>> + * Tools have no selected target.
>>>>> + *
>>>>> + * SPDX-License-Identifier: GPL-2.0-or-later
>>>>> + */
>>>>> +
>>>>> +#include "qemu/osdep.h"
>>>>> +#include "qemu/target-info.h"
>>>>> +
>>>>> +uint64_t target_mask_selected(void)
>>>>> +{
>>>>> + return 0;
>>>>> +}
>>>>> diff --git a/target-info-def.c b/target-info-def.c
>>>>> index bcf9cfe1e4..a992019626 100644
>>>>> --- a/target-info-def.c
>>>>> +++ b/target-info-def.c
>>>>> @@ -9,6 +9,9 @@
>>>>> #include "qemu/osdep.h"
>>>>> #include "qemu/target-info.h"
>>>>> #include "qemu/target-info-def.h"
>>>>> +#ifdef CONFIG_USER_ONLY
>>>>> +#include "qemu/base-arch-defs.h"
>>>>> +#endif
>>>>> #include "qemu/target-info-init.h"
>>>>> #include "hw/core/boards.h"
>>>>> #include "cpu.h"
>>>>> diff --git a/target-info-qom.c b/target-info-qom.c
>>>>> index aeeedb7e81..fb4c9835e5 100644
>>>>> --- a/target-info-qom.c
>>>>> +++ b/target-info-qom.c
>>>>> @@ -9,6 +9,8 @@
>>>>> #include "qemu/osdep.h"
>>>>> #include "qapi/error.h"
>>>>> #include "qom/object.h"
>>>>> +#include "qemu/base-arch-defs.h"
>>>>> +#include "qemu/target-info.h"
>>>>> #include "qemu/target-info-def.h"
>>>>> #include "qemu/target-info-init.h"
>>>>> #include "qemu/target-info-qom.h"
>>>>> @@ -40,6 +42,14 @@ const TargetInfo *target_info(void)
>>>>> return target_info_ptr;
>>>>> }
>>>>>
>>>>> +uint64_t target_mask_selected(void)
>>>>> +{
>>>>> + if (!target_info_ptr) {
>>>>> + return QEMU_ARCH_ALL;
>>>>> + }
>>>>> + return QEMU_ARCH_BIT(target_info_ptr->target_arch);
>>>>> +}
>>>>> +
>>>>> void target_info_qom_set_target(void)
>>>>> {
>>>>> g_autoptr(GSList) targets = object_class_get_list(TYPE_TARGET_INFO, false);
>>>>
>>>
>>>
>>
>
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 0/5] qom: prepare a TypeBucket for same-name target variants
2026-11-05 19:03 [PATCH 0/5] qom: prepare a TypeBucket for same-name target variants Yonggang Luo
` (4 preceding siblings ...)
2026-11-05 19:03 ` [PATCH 5/5] qom: add type_register_targets() Yonggang Luo
@ 2026-11-12 13:53 ` Daniel P. Berrangé
5 siblings, 0 replies; 14+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:53 UTC (permalink / raw)
To: Yonggang Luo
Cc: qemu-devel, Pierrick Bouvier, Philippe Mathieu-Daudé,
Paolo Bonzini, Philippe Mathieu-Daude
On Fri, Nov 06, 2026 at 03:03:41AM +0800, Yonggang Luo wrote:
> This series prepares QOM to hold more than one TypeImpl under the same name, one
> per target, so a multi-target binary can register same-name types without
> renaming them. Nothing uses it yet.
>
> type_table maps each name to a TypeBucket, which holds the variants and the
> union of their QEMU_ARCH_* masks. Registration still aborts when masks overlap,
> and a name lookup returns the one variant left for the selected target.
> type_register_targets() registers a variant for a target mask.
> type_register_static() is unchanged, so binaries keep one TypeImpl per name.
>
> The change stays in qom and target-info and does not conflict with the virt QOM
> name or is_available series.
>
> Daniel asked what a TypeBucket means. This is that prototype, based on the
> bucket idea from Pierrick.
Thank you for sending this.
IIUC the overall idea here is not all that different from the
existing 'is_available' callback approach. It is still allowing
us to have multiple different classes registered with the same
name. Instead of a opaque callback being used for the filter,
each type is tagged with an explicit target, which can be
filtered on.
So the end result is still the same, we have multiple QOM classes
with the same name, and dynamically filter which are visible to
the management app at runtime. It is slightly better in the that
filtering is data driven, instead of callback driven, but IMHO
this still doesn't address the fundamental historical design
flaw of having clashing QOM type names.
IMHO we need to work from a principal that we should produce a
This gives us a unified type model across the whole of QEMU which
is *invariant at runtime*. This means type names must be unique
and statically defined at build time, and that properties must
be unique and unconditionally defined against classes at build
time.
The property part in particular is not tied to the multi-target
work. We have other technical debt cleanup work going on that
moves from registering properties against the object instance,
to registering properties against the object class, to produce
an invariant class definition. Removing target-specific property
registration is a natural part of that we would want to do even
without the multi-target motivation.
I've proposed a refinement of my previous PoC from last week that
properly adapts the machine types to unique names:
https://lists.gnu.org/archive/html/qemu-devel/2026-11/msg02706.html
and pulled in your patches for removing target specific properties
there, since although not a dependency, it is complementary.
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] 14+ messages in thread
end of thread, other threads:[~2026-11-12 13:54 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-05 19:03 [PATCH 0/5] qom: prepare a TypeBucket for same-name target variants Yonggang Luo
2026-11-05 19:03 ` [PATCH 1/5] qom: store registration targets on TypeImpl Yonggang Luo
2026-11-05 19:03 ` [PATCH 2/5] target-info: add target_mask_selected() Yonggang Luo
2026-11-06 15:45 ` Daniel P. Berrangé
2026-11-06 16:17 ` Yonggang Luo
2026-11-06 17:44 ` Pierrick Bouvier
2026-11-06 17:46 ` Yonggang Luo
2026-11-06 17:47 ` Pierrick Bouvier
2026-11-06 19:52 ` Yonggang Luo
2026-11-06 20:19 ` Pierrick Bouvier
2026-11-05 19:03 ` [PATCH 3/5] qom: add target_mask_filter() Yonggang Luo
2026-11-05 19:03 ` [PATCH 4/5] qom: filter type lookup with TypeBucket Yonggang Luo
2026-11-05 19:03 ` [PATCH 5/5] qom: add type_register_targets() Yonggang Luo
2026-11-12 13:53 ` [PATCH 0/5] qom: prepare a TypeBucket for same-name target variants Daniel P. Berrangé
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.