* [PATCH 01/48] iotests: better heuristics to find I/O tests build/source dirs
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 02/48] target-info: add target_mask_selected() Daniel P. Berrangé
` (47 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
Currently the I/O tests cannot be run if executing directly
from the source directory, even when wrapped by the 'run'
script, due to inadequate heuristics to guess the directories.
If using the 'run' script, meson can tell us exactly where the
top level build and source directories are, so we don't need
to guess. Just read MESON_BUILD_ROOT and MESON_SOURCE_ROOT
env variables if present.
If not using the 'run' script, we can do a bit better at
guessing the path from the 'check' filename. Always resolve
from sys.argv[0], even when it is not a symlink, instead of
falling back to 'cwd()' which doesn't work since we stopped
having in-tree builds. If invoked directly from the source
tree, guess that the build root is the default 'build' name
which often works.
With this change the following all work:
1. From root of build dir, with run script
cd build
./run tests/qemu-iotests/check 5
2. From root of build dir, without run script
cd build
tests/qemu-iotests/check 5
3. From I/O tests subdir of build dir, with run script
cd build/tests/qemu-iotests
../../run ./check 5
4. From I/O tests subdir of build dir, without run script
cd build/tests/qemu-iotests
./check 5
5. From root of source dir, with run script
./build/run tests/qemu-iotests/check 5
6. From root of source dir, without run script
tests/qemu-iotests/check 5
7. From I/O tests subdir of source dir, with run script
cd tests/qemu-iotests
../../build/run ./check 5
8. From I/O tests subdir of source dir, without run script
cd tests/qemu-iotests
./check 5
Before this commit, items 5-8 would always fail. Items 6 and
8 will not work if using a build directory with a name other
than the default 'build'. For those scenarios use one of the
other 6 possible variants.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
meson.build | 1 +
tests/qemu-iotests/check | 52 +++++++++++++++++++++++++++++-----------
2 files changed, 39 insertions(+), 14 deletions(-)
diff --git a/meson.build b/meson.build
index d7bcb581c18..9d15f2e9551 100644
--- a/meson.build
+++ b/meson.build
@@ -3502,6 +3502,7 @@ genh += config_host_h
devenv = environment()
devenv.set('MESON_BUILD_ROOT', meson.project_build_root())
+devenv.set('MESON_SOURCE_ROOT', meson.project_source_root())
devenv.set('VIRTUAL_ENV', meson.project_build_root() / 'pyvenv')
devenv.prepend('PATH', meson.project_build_root() / 'pyvenv'/ 'bin')
devenv.prepend('PYTHONPATH', meson.current_source_dir() / 'tests' / 'functional')
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
index c8ba536970c..40baa2b4107 100755
--- a/tests/qemu-iotests/check
+++ b/tests/qemu-iotests/check
@@ -28,18 +28,42 @@ from findtests import TestFinder
from testenv import TestEnv
from testrunner import TestRunner
-def get_default_path(follow_link=False):
- """
- Try to automagically figure out the path we are running from.
- """
- # called from the build tree?
- if os.path.islink(sys.argv[0]):
- if follow_link:
- return os.path.dirname(os.readlink(sys.argv[0]))
+
+def get_build_dir():
+ if "MESON_BUILD_ROOT" in os.environ:
+ br = os.environ["MESON_BUILD_ROOT"]
+ return os.path.join(br, "tests", "qemu-iotests")
+ else:
+ if os.path.islink(sys.argv[0]):
+ iobr = os.path.dirname(sys.argv[0])
+ else:
+ iobr = os.path.join(os.path.dirname(sys.argv[0]),
+ "..", "..", "build", "tests", "qemu-iotests")
+ if (not os.path.exists(os.path.join(iobr, "check")) or
+ os.path.exists(os.path.join(iobr, "testenv.py"))):
+ raise Exception(f"MESON_BUILD_ROOT is not set, and guessed "
+ "I/O tests build root {iobr} does not look "
+ "valid. Please use the 'run' script to invoke "
+ "the I/O tests")
+ return os.path.abspath(iobr)
+
+
+def get_source_dir():
+ if "MESON_SOURCE_ROOT" in os.environ:
+ sr = os.environ["MESON_SOURCE_ROOT"]
+ return os.path.join(sr, "tests", "qemu-iotests")
+ else:
+ if os.path.islink(sys.argv[0]):
+ iosr = os.path.dirname(os.readlink(sys.argv[0]))
else:
- return os.path.dirname(os.path.abspath(sys.argv[0]))
- else: # or source tree?
- return os.getcwd()
+ iosr = os.path.dirname(sys.argv[0])
+ if not os.path.exists(os.path.join(iosr, "testenv.py")):
+ raise Exception(f"MESON_SOURCE_ROOT is not set, and guessed "
+ "I/O tests source root {iosr} does not look "
+ "valid. Please use the 'run' script to invoke "
+ "the I/O tests")
+ return os.path.abspath(iosr)
+
def make_argparser() -> argparse.ArgumentParser:
p = argparse.ArgumentParser(
@@ -131,11 +155,11 @@ def make_argparser() -> argparse.ArgumentParser:
'middle of the process.')
g_sel.add_argument('tests', metavar='TEST_FILES', nargs='*',
help='tests to run, or "--" followed by a command')
- g_sel.add_argument('--build-dir', default=get_default_path(),
+ g_sel.add_argument('--build-dir', default=get_build_dir(),
help='Path to iotests build directory')
g_sel.add_argument('--source-dir',
- default=get_default_path(follow_link=True),
- help='Path to iotests build directory')
+ default=get_source_dir(),
+ help='Path to iotests source directory')
return p
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 02/48] target-info: add target_mask_selected()
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 01/48] iotests: better heuristics to find I/O tests build/source dirs Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 03/48] qom: define a TargetSpecific interface Daniel P. Berrangé
` (46 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
From: Yonggang Luo <luoyonggang@gmail.com>
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.
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
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 b7024c9faef..84929868328 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 2cd4cc5671b..5673d10ebae 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 744fb759a2f..49cede8582f 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 00000000000..510a515851c
--- /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 bcf9cfe1e43..a9920196266 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 aeeedb7e818..fb4c9835e5a 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.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 03/48] qom: define a TargetSpecific interface
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 01/48] iotests: better heuristics to find I/O tests build/source dirs Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 02/48] target-info: add target_mask_selected() Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 04/48] qom: define an Aliased interface Daniel P. Berrangé
` (45 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
This can be used to declare a type as being target specific.
Implementing the interface just records the target metadata,
applying the enforcement requires the object creation path to
call 'target_specific_class_check()' to validate the system
state.
This approach is intended to allow classes to be unconditionally
registered, which allows introspection at any time. The target
specific enforcement is applied at runtime in the object
creation codepaths that need to apply restrictions. This implies
that QOM class names must be globally unique across all targets
known to QEMU.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
include/qom/object_interfaces.h | 75 +++++++++++++++++++++++++++++++++
qom/object_interfaces.c | 31 ++++++++++++++
2 files changed, 106 insertions(+)
diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
index afd0fb93b2b..d222a3d7481 100644
--- a/include/qom/object_interfaces.h
+++ b/include/qom/object_interfaces.h
@@ -16,6 +16,17 @@ DECLARE_CLASS_CHECKERS(UserCreatableClass, USER_CREATABLE,
typedef struct UserCreatable UserCreatable;
+#define TYPE_TARGET_SPECIFIC "target-specific"
+
+typedef struct TargetSpecificClass TargetSpecificClass;
+DECLARE_CLASS_CHECKERS(TargetSpecificClass, TARGET_SPECIFIC,
+ TYPE_TARGET_SPECIFIC)
+#define TARGET_SPECIFIC(obj) \
+ INTERFACE_CHECK(TargetSpecific, (obj), \
+ TYPE_TARGET_SPECIFIC)
+
+typedef struct TargetSpecific TargetSpecific;
+
/**
* UserCreatableClass:
* @parent_class: the base class
@@ -167,4 +178,68 @@ bool user_creatable_del(const char *id, Error **errp);
*/
void user_creatable_cleanup(void);
+/**
+ * TargetSpecificClass:
+ * @parent_class: the base class
+ *
+ * Interface for classes that want to declare they have target
+ * specific restrictions. This is intended to allow classes to
+ * be registered and introspected unconditionally, while
+ * preventing creation of instances unless a compatible target
+ * is selected.
+ */
+struct TargetSpecificClass {
+ InterfaceClass parent_class;
+
+ /*
+ * Leave as 0 to indicate no target specific creation restrictions,
+ * or set to a bitmask of QEMU_ARCH_nnn constants to limit what
+ * targets it can be created under.
+ */
+ int targets;
+};
+
+
+/**
+ * target_specific_class_creatable:
+ * @oc: the object class to check
+ *
+ * Determine whether @oc implements the TargetSpecific
+ * interface and if so, whether its declared targets
+ * allow creation in the current system state.
+ *
+ * If @oc does not implement the TargetSpecific interface
+ * it is assumed there are no creation restrictions.
+ *
+ * If @oc implements the TargetSpecific interface but leaves
+ * the 'targets' field as zero, it is assumed there are
+ * no creation restrictions.
+ *
+ * If @oc implements the TargetSpecific interface and the
+ * 'targets' field is non-zero, it is compared to
+ * target_mask_selected() to determine if it is valid to
+ * create an instance of @oc.
+ *
+ * Returns: true if it is valid to create an instance of @oc
+ * in the current system state, false otherwise.
+ */
+bool target_specific_class_creatable(ObjectClass *oc);
+
+
+/**
+ * target_specific_class_check:
+ * @oc: the object class to check
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Check whether it is permitted to create an instance
+ * of @oc in the current system target state.
+ *
+ * This validates @oc against target_specific_class_creatable
+ * and sets @errp if it is not creatable.
+ *
+ * Returns: @oc if it is creatable, NULL otherwise with @errp set.
+ */
+ObjectClass *target_specific_class_check(ObjectClass *oc,
+ Error **errp);
+
#endif
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index d83c12744b7..f523a55b93a 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -20,6 +20,7 @@
#include "qapi/opts-visitor.h"
#include "qemu/config-file.h"
#include "qemu/keyval.h"
+#include "qemu/target-info.h"
#include "trace.h"
bool user_creatable_complete(UserCreatable *uc, Error **errp)
@@ -280,6 +281,30 @@ void user_creatable_cleanup(void)
object_unparent(object_get_objects_root());
}
+
+bool target_specific_class_creatable(ObjectClass *oc)
+{
+ TargetSpecificClass *tsc =
+ (TargetSpecificClass *)object_class_dynamic_cast(
+ oc, TYPE_TARGET_SPECIFIC);
+
+ return !tsc || !tsc->targets || (tsc->targets & target_mask_selected());
+}
+
+
+ObjectClass *target_specific_class_check(ObjectClass *oc,
+ Error **errp)
+{
+ if (!target_specific_class_creatable(oc)) {
+ error_setg(errp, "Object '%s' not compatible with selected target",
+ object_class_get_name(oc));
+ return NULL;
+ }
+
+ return oc;
+}
+
+
static void register_types(void)
{
static const TypeInfo uc_interface_info = {
@@ -287,8 +312,14 @@ static void register_types(void)
.parent = TYPE_INTERFACE,
.class_size = sizeof(UserCreatableClass),
};
+ static const TypeInfo ts_interface_info = {
+ .name = TYPE_TARGET_SPECIFIC,
+ .parent = TYPE_INTERFACE,
+ .class_size = sizeof(TargetSpecificClass),
+ };
type_register_static(&uc_interface_info);
+ type_register_static(&ts_interface_info);
}
type_init(register_types)
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 04/48] qom: define an Aliased interface
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (2 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 03/48] qom: define a TargetSpecific interface Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 05/48] hw: tweak approach to setting alias in machine macros Daniel P. Berrangé
` (44 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
All QOM types must have a globally unique typename, however, for
user convenience, some might also want to have aliases which are
permitted to be ambiguous. Define an "Aliased" interface which
can be implemented by types which want to support aliases.
When resolving an alias, if there are multiple QOM types with a
matching alias this is considered an error. Ambiguity can be
resolved by matching system state, with the selected target
being the currently implemented filter.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
include/qom/object_interfaces.h | 77 +++++++++++++++++++++++++++++++++
qom/object_interfaces.c | 57 ++++++++++++++++++++++++
2 files changed, 134 insertions(+)
diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
index d222a3d7481..010e37d63f7 100644
--- a/include/qom/object_interfaces.h
+++ b/include/qom/object_interfaces.h
@@ -27,6 +27,17 @@ DECLARE_CLASS_CHECKERS(TargetSpecificClass, TARGET_SPECIFIC,
typedef struct TargetSpecific TargetSpecific;
+#define TYPE_ALIASED "aliased"
+
+typedef struct AliasedClass AliasedClass;
+DECLARE_CLASS_CHECKERS(AliasedClass, ALIASED,
+ TYPE_ALIASED)
+#define ALIASED(obj) \
+ INTERFACE_CHECK(Aliased, (obj), \
+ TYPE_ALIASED)
+
+typedef struct Aliased Aliased;
+
/**
* UserCreatableClass:
* @parent_class: the base class
@@ -242,4 +253,70 @@ bool target_specific_class_creatable(ObjectClass *oc);
ObjectClass *target_specific_class_check(ObjectClass *oc,
Error **errp);
+/**
+ * AliasedClass
+ * @parent_class: the base class
+ *
+ * Interface for classes that want to declare they have aliases
+ * for their primary type name.
+ *
+ * While QOM type names are required to be unique, aliases allow
+ * for ambiguity across classes. The ambiguity is resolved at
+ * runtime based on system state, typically by the selection of
+ * a specific target. If ambiguity cannot be resolved, the user
+ * will need to use the unique QOM type name instead.
+ */
+struct AliasedClass {
+ InterfaceClass parent_class;
+
+ const char *const *aliases; /* NULL terminated list of typenames */
+};
+
+
+/**
+ * aliased_class_matches:
+ * @oc: the class object to check
+ * @typename: the possible type name alias to check
+ *
+ * Determine whether @oc implements the Aliased interface
+ * and has declared an alias that matches @typename.
+ *
+ * Returns: true if @oc implements Aliased and has an
+ * alias named @typename, false otherwise
+ */
+bool aliased_class_matches(ObjectClass *oc,
+ const char *typename);
+
+
+/**
+ * aliased_class_resolve:
+ * @implements: a parent type to validate
+ * @typename: a type name to search for
+ * @errp: pointer to a NULL initialized error object
+ *
+ * Search all registered QOM types that implement
+ * both @implements and the Aliased interface for
+ * one that declares an alias @typename.
+ *
+ * If there is a single QOM class with a matching alias
+ * it will be returned.
+ *
+ * If there are multiple QOM classes with a matching
+ * alias an error will be raised about the ambiguous
+ * match.
+ *
+ * If the QOM class also implements the TargetSpecific
+ * interface and the current system target does not
+ * match the declared supported targets, aliases for
+ * that QOM class will be ignored. This is usually
+ * sufficient to resolve ambiguity between types.
+ *
+ * Returns: a unique QOM class with an alias @typename,
+ * or NULL if zero or multiple aliases match, with @errp
+ * set.
+ */
+ ObjectClass *aliased_class_resolve(const char *implements,
+ const char *typename,
+ Error **errp);
+
#endif
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index f523a55b93a..136629f88b2 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -305,6 +305,57 @@ ObjectClass *target_specific_class_check(ObjectClass *oc,
}
+bool aliased_class_matches(ObjectClass *oc, const char *typename)
+{
+ AliasedClass *alc =
+ (AliasedClass *)object_class_dynamic_cast(
+ oc, TYPE_ALIASED);
+
+ return alc && alc->aliases && g_strv_contains(alc->aliases, typename);
+}
+
+
+ObjectClass *aliased_class_resolve(const char *implements,
+ const char *typename,
+ Error **errp)
+{
+ g_autoptr(GSList) objs = object_class_get_list(implements, false);
+ GSList *el;
+ ObjectClass *ret = NULL;
+ g_autofree const char **matches = NULL;
+ size_t nmatches = 0;
+
+ for (el = objs; el; el = el->next) {
+ ObjectClass *oc = el->data;
+
+ if (aliased_class_matches(oc, typename) &&
+ target_specific_class_creatable(oc)) {
+ matches = g_renew(const char *, matches, nmatches + 2);
+ matches[nmatches] = object_class_get_name(oc);
+ matches[nmatches + 1] = NULL;
+
+ ret = oc;
+ }
+ }
+
+ if (nmatches > 1) {
+ g_autofree char *matchesstr = g_strjoinv(", ", (char **)matches);
+ error_setg(errp,
+ "Object alias '%s' is not unique, matches %s",
+ typename, matchesstr);
+ return NULL;
+ }
+
+ if (!ret) {
+ error_setg(errp, "Object '%s' not found, no child of '%s' registered",
+ typename, implements);
+ return NULL;
+ }
+
+ return ret;
+}
+
+
static void register_types(void)
{
static const TypeInfo uc_interface_info = {
@@ -317,9 +368,15 @@ static void register_types(void)
.parent = TYPE_INTERFACE,
.class_size = sizeof(TargetSpecificClass),
};
+ static const TypeInfo al_interface_info = {
+ .name = TYPE_ALIASED,
+ .parent = TYPE_INTERFACE,
+ .class_size = sizeof(AliasedClass),
+ };
type_register_static(&uc_interface_info);
type_register_static(&ts_interface_info);
+ type_register_static(&al_interface_info);
}
type_init(register_types)
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 05/48] hw: tweak approach to setting alias in machine macros
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (3 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 04/48] qom: define an Aliased interface Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 06/48] hw/core: implement TYPE_ALIASED interface in machines Daniel P. Berrangé
` (43 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
Currently the pattern for DEFINE_MACHINE macros is to
pass a boolean "latest" flag as a macro parameter, which
is then used in a test. For example
...
if (latest) {
mc->alias = "s390-ccw-virtio";
mc->is_default = true;
}
On the surface this looks fine, but this is actually taking a
build time static characteristic of the machine type and turning
it into a runtime tunable that only ever has a single code path.
ie the macro code expands to:
if (true) {
mc->alias = "s390-ccw-virtio";
mc->is_default = true;
}
or
if (false) {
mc->alias = "s390-ccw-virtio";
mc->is_default = true;
}
The compiler should optimize out the condition, but we can do
do this explicitly by passing the desired extra initializers
to the macro directly.
This makes the macro definition a bit more verbose, but it will
facilitate forthcoming changes that require more complex
initialization to be added to the class initializer methods.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/arm/virt.c | 12 ++++++------
hw/i386/pc_piix.c | 7 +++++--
hw/i386/pc_q35.c | 10 +++++++---
hw/loongarch/virt.c | 14 +++++++-------
hw/m68k/virt.c | 12 ++++++------
hw/ppc/spapr.c | 19 +++++++------------
hw/s390x/s390-virtio-ccw.c | 14 +++++++-------
include/hw/core/boards.h | 18 +++++++++---------
include/hw/i386/pc.h | 5 ++---
9 files changed, 56 insertions(+), 55 deletions(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 0b11f7e328c..e481d0e548b 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -112,7 +112,7 @@ static void arm_virt_compat_default_set(MachineClass *mc)
arm_virt_compat_defaults_len);
}
-#define DEFINE_VIRT_MACHINE_IMPL(latest, ...) \
+#define DEFINE_VIRT_MACHINE_IMPL(classinitextra, ...) \
static void MACHINE_VER_SYM(class_init, virt, __VA_ARGS__)( \
ObjectClass *oc, \
const void *data) \
@@ -122,9 +122,7 @@ static void arm_virt_compat_default_set(MachineClass *mc)
MACHINE_VER_SYM(options, virt, __VA_ARGS__)(mc); \
mc->desc = "QEMU " MACHINE_VER_STR(__VA_ARGS__) " ARM Virtual Machine"; \
MACHINE_VER_DEPRECATION(__VA_ARGS__); \
- if (latest) { \
- mc->alias = "virt"; \
- } \
+ classinitextra \
} \
static const TypeInfo MACHINE_VER_SYM(info, virt, __VA_ARGS__) = \
{ \
@@ -142,9 +140,11 @@ static void arm_virt_compat_default_set(MachineClass *mc)
type_init(MACHINE_VER_SYM(register, virt, __VA_ARGS__));
#define DEFINE_VIRT_MACHINE_AS_LATEST(major, minor) \
- DEFINE_VIRT_MACHINE_IMPL(true, major, minor)
+ DEFINE_VIRT_MACHINE_IMPL({ \
+ mc->alias = "virt"; \
+ }, major, minor)
#define DEFINE_VIRT_MACHINE(major, minor) \
- DEFINE_VIRT_MACHINE_IMPL(false, major, minor)
+ DEFINE_VIRT_MACHINE_IMPL({}, major, minor)
/* Number of external interrupt lines to configure the GIC with */
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 446590e4e55..88356bf0d77 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -363,10 +363,13 @@ static void pc_i440fx_init(MachineState *machine)
}
#define DEFINE_I440FX_MACHINE(major, minor) \
- DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, false, NULL, major, minor);
+ DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, \
+ {}, major, minor);
#define DEFINE_I440FX_MACHINE_AS_LATEST(major, minor) \
- DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, true, "pc", major, minor);
+ DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, { \
+ mc->is_default = true; mc->alias = "pc"; \
+ }, major, minor);
static void pc_i440fx_machine_options(MachineClass *m)
{
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index c3ce9c56492..9c6459b934d 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -339,13 +339,17 @@ static void pc_q35_machine_set_wdat(Object *o, bool value, Error **errp)
}
#define DEFINE_Q35_MACHINE(major, minor) \
- DEFINE_PC_VER_MACHINE(pc_q35, "pc-q35", pc_q35_init, false, NULL, major, minor);
+ DEFINE_PC_VER_MACHINE(pc_q35, "pc-q35", pc_q35_init, {}, \
+ major, minor);
#define DEFINE_Q35_MACHINE_AS_LATEST(major, minor) \
- DEFINE_PC_VER_MACHINE(pc_q35, "pc-q35", pc_q35_init, false, "q35", major, minor);
+ DEFINE_PC_VER_MACHINE(pc_q35, "pc-q35", pc_q35_init, { \
+ mc->alias = "q35"; \
+ }, major, minor);
#define DEFINE_Q35_MACHINE_BUGFIX(major, minor, micro) \
- DEFINE_PC_VER_MACHINE(pc_q35, "pc-q35", pc_q35_init, false, NULL, major, minor, micro);
+ DEFINE_PC_VER_MACHINE(pc_q35, "pc-q35", pc_q35_init, {}, \
+ major, minor, micro);
static void pc_q35_machine_options(MachineClass *m)
{
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index c67dad095ab..30a2ab6be9d 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -1521,7 +1521,7 @@ static void virt_class_init(ObjectClass *oc, const void *data)
"for PCI MMIO");
}
-#define DEFINE_VIRT_MACHINE_VERSION(latest, ...) \
+#define DEFINE_VIRT_MACHINE_VERSION(classinitextra, ...) \
static void MACHINE_VER_SYM(class_init, virt, __VA_ARGS__)( \
ObjectClass *oc, \
const void *data) \
@@ -1530,10 +1530,7 @@ static void virt_class_init(ObjectClass *oc, const void *data)
MACHINE_VER_SYM(options, virt, __VA_ARGS__)(mc); \
mc->desc = "QEMU " MACHINE_VER_STR(__VA_ARGS__) " LoongArch Virtual Machine"; \
MACHINE_VER_DEPRECATION(__VA_ARGS__); \
- if (latest) { \
- mc->alias = "virt"; \
- mc->is_default = true; \
- } \
+ classinitextra \
} \
static const TypeInfo MACHINE_VER_SYM(info, virt, __VA_ARGS__) = \
{ \
@@ -1550,9 +1547,12 @@ static void virt_class_init(ObjectClass *oc, const void *data)
type_init(MACHINE_VER_SYM(register, virt, __VA_ARGS__));
#define DEFINE_VIRT_MACHINE_AS_LATEST(major, minor) \
- DEFINE_VIRT_MACHINE_VERSION(true, major, minor)
+ DEFINE_VIRT_MACHINE_VERSION({ \
+ mc->alias = "virt"; \
+ mc->is_default = true; \
+ }, major, minor)
#define DEFINE_VIRT_MACHINE(major, minor) \
- DEFINE_VIRT_MACHINE_VERSION(false, major, minor)
+ DEFINE_VIRT_MACHINE_VERSION({}, major, minor)
static void virt_instance_finalize(Object *obj)
{
diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c
index e52546e4fab..2418bd3d503 100644
--- a/hw/m68k/virt.c
+++ b/hw/m68k/virt.c
@@ -337,7 +337,7 @@ static void virt_machine_register_types(void)
type_init(virt_machine_register_types)
-#define DEFINE_VIRT_MACHINE_IMPL(latest, ...) \
+#define DEFINE_VIRT_MACHINE_IMPL(classinitextra, ...) \
static void MACHINE_VER_SYM(class_init, virt, __VA_ARGS__)( \
ObjectClass *oc, \
const void *data) \
@@ -346,9 +346,7 @@ type_init(virt_machine_register_types)
MACHINE_VER_SYM(options, virt, __VA_ARGS__)(mc); \
mc->desc = "QEMU " MACHINE_VER_STR(__VA_ARGS__) " M68K Virtual Machine"; \
MACHINE_VER_DEPRECATION(__VA_ARGS__); \
- if (latest) { \
- mc->alias = "virt"; \
- } \
+ classinitextra \
} \
static const TypeInfo MACHINE_VER_SYM(info, virt, __VA_ARGS__) = \
{ \
@@ -365,9 +363,11 @@ type_init(virt_machine_register_types)
type_init(MACHINE_VER_SYM(register, virt, __VA_ARGS__));
#define DEFINE_VIRT_MACHINE_AS_LATEST(major, minor) \
- DEFINE_VIRT_MACHINE_IMPL(true, major, minor)
+ DEFINE_VIRT_MACHINE_IMPL({ \
+ mc->alias = "virt"; \
+ }, major, minor)
#define DEFINE_VIRT_MACHINE(major, minor) \
- DEFINE_VIRT_MACHINE_IMPL(false, major, minor)
+ DEFINE_VIRT_MACHINE_IMPL({}, major, minor)
static void virt_machine_11_2_options(MachineClass *mc)
{
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 54e3cc3cbe4..8816f607a8f 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -4728,13 +4728,7 @@ static const TypeInfo spapr_machine_info = {
},
};
-static void spapr_machine_latest_class_options(MachineClass *mc)
-{
- mc->alias = "pseries";
- mc->is_default = true;
-}
-
-#define DEFINE_SPAPR_MACHINE_IMPL(latest, ...) \
+#define DEFINE_SPAPR_MACHINE_IMPL(classinitextra, ...) \
static void MACHINE_VER_SYM(class_init, spapr, __VA_ARGS__)( \
ObjectClass *oc, \
const void *data) \
@@ -4742,9 +4736,7 @@ static void spapr_machine_latest_class_options(MachineClass *mc)
MachineClass *mc = MACHINE_CLASS(oc); \
MACHINE_VER_SYM(class_options, spapr, __VA_ARGS__)(mc); \
MACHINE_VER_DEPRECATION(__VA_ARGS__); \
- if (latest) { \
- spapr_machine_latest_class_options(mc); \
- } \
+ classinitextra; \
} \
static const TypeInfo MACHINE_VER_SYM(info, spapr, __VA_ARGS__) = \
{ \
@@ -4761,9 +4753,12 @@ static void spapr_machine_latest_class_options(MachineClass *mc)
type_init(MACHINE_VER_SYM(register, spapr, __VA_ARGS__))
#define DEFINE_SPAPR_MACHINE_AS_LATEST(major, minor) \
- DEFINE_SPAPR_MACHINE_IMPL(true, major, minor)
+ DEFINE_SPAPR_MACHINE_IMPL({ \
+ mc->alias = "pseries"; \
+ mc->is_default = true; \
+ }, major, minor)
#define DEFINE_SPAPR_MACHINE(major, minor) \
- DEFINE_SPAPR_MACHINE_IMPL(false, major, minor)
+ DEFINE_SPAPR_MACHINE_IMPL({}, major, minor)
/*
* pseries-11.2
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 214445c018f..eafb603f3e0 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -961,7 +961,7 @@ static const TypeInfo ccw_machine_info = {
},
};
-#define DEFINE_CCW_MACHINE_IMPL(latest, ...) \
+#define DEFINE_CCW_MACHINE_IMPL(classinitextra, ...) \
static void MACHINE_VER_SYM(mach_init, ccw, __VA_ARGS__)(MachineState *mach) \
{ \
MACHINE_VER_SYM(instance_options, ccw, __VA_ARGS__)(mach); \
@@ -979,10 +979,7 @@ static const TypeInfo ccw_machine_info = {
mc->desc = "Virtual s390x machine (version " MACHINE_VER_STR(__VA_ARGS__) ")"; \
mc->init = MACHINE_VER_SYM(mach_init, ccw, __VA_ARGS__); \
MACHINE_VER_DEPRECATION(__VA_ARGS__); \
- if (latest) { \
- mc->alias = "s390-ccw-virtio"; \
- mc->is_default = true; \
- } \
+ classinitextra \
} \
static const TypeInfo MACHINE_VER_SYM(info, ccw, __VA_ARGS__) = \
{ \
@@ -999,10 +996,13 @@ static const TypeInfo ccw_machine_info = {
type_init(MACHINE_VER_SYM(register, ccw, __VA_ARGS__))
#define DEFINE_CCW_MACHINE_AS_LATEST(major, minor) \
- DEFINE_CCW_MACHINE_IMPL(true, major, minor)
+ DEFINE_CCW_MACHINE_IMPL({ \
+ mc->alias = "s390-ccw-virtio"; \
+ mc->is_default = true; \
+ }, major, minor)
#define DEFINE_CCW_MACHINE(major, minor) \
- DEFINE_CCW_MACHINE_IMPL(false, major, minor)
+ DEFINE_CCW_MACHINE_IMPL({}, major, minor)
static void ccw_machine_11_2_instance_options(MachineState *machine)
diff --git a/include/hw/core/boards.h b/include/hw/core/boards.h
index d0e4ad98201..a25c627c0c8 100644
--- a/include/hw/core/boards.h
+++ b/include/hw/core/boards.h
@@ -464,7 +464,7 @@ struct MachineState {
* For example, a macro that can be used to define versioned
* 'virt' machine types would look like:
*
- * #define DEFINE_VIRT_MACHINE_IMPL(latest, ...) \
+ * #define DEFINE_VIRT_MACHINE_IMPL(classinitextra, ...) \
* static void MACHINE_VER_SYM(class_init, virt, __VA_ARGS__)( \
* ObjectClass *oc, \
* void *data) \
@@ -473,9 +473,7 @@ struct MachineState {
* MACHINE_VER_SYM(options, virt, __VA_ARGS__)(mc); \
* mc->desc = "QEMU " MACHINE_VER_STR(__VA_ARGS__) " Virtual Machine"; \
* MACHINE_VER_DEPRECATION(__VA_ARGS__); \
- * if (latest) { \
- * mc->alias = "virt"; \
- * } \
+ * classinitextra \
* } \
* static const TypeInfo MACHINE_VER_SYM(info, virt, __VA_ARGS__) = { \
* .name = MACHINE_VER_TYPE_NAME("virt", __VA_ARGS__), \
@@ -494,23 +492,25 @@ struct MachineState {
*
* // Normal 2 digit, marked as latest e.g. 'virt-9.0'
* #define DEFINE_VIRT_MACHINE_LATEST(major, minor) \
- * DEFINE_VIRT_MACHINE_IMPL(true, major, minor)
+ * DEFINE_VIRT_MACHINE_IMPL({ \
+ * mc->alias = "virt"; \
+ * }, major, minor)
*
* // Normal 2 digit e.g. 'virt-9.0'
* #define DEFINE_VIRT_MACHINE(major, minor) \
- * DEFINE_VIRT_MACHINE_IMPL(false, major, minor)
+ * DEFINE_VIRT_MACHINE_IMPL({}, major, minor)
*
* // Bugfix 3 digit e.g. 'virt-9.0.1'
* #define DEFINE_VIRT_MACHINE_BUGFIX(major, minor, micro) \
- * DEFINE_VIRT_MACHINE_IMPL(false, major, minor, micro)
+ * DEFINE_VIRT_MACHINE_IMPL({}, major, minor, micro)
*
* // Tagged 2 digit e.g. 'virt-9.0-extra'
* #define DEFINE_VIRT_MACHINE_TAGGED(major, minor, tag) \
- * DEFINE_VIRT_MACHINE_IMPL(false, major, minor, _, tag)
+ * DEFINE_VIRT_MACHINE_IMPL({}, major, minor, _, tag)
*
* // Tagged bugfix 2 digit e.g. 'virt-9.0.1-extra'
* #define DEFINE_VIRT_MACHINE_TAGGED(major, minor, micro, tag) \
- * DEFINE_VIRT_MACHINE_IMPL(false, major, minor, micro, _, tag)
+ * DEFINE_VIRT_MACHINE_IMPL({}, major, minor, micro, _, tag)
*/
#define DEFINE_MACHINE_EXTENDED(namestr, PARENT_NAME, InstanceName, \
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 844ae835784..190d966c7bb 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -308,7 +308,7 @@ extern const size_t pc_compat_4_1_len;
DEFINE_PC_MACHINE_EXTENDED(suffix, namestr, initfn, optsfn, true)
-#define DEFINE_PC_VER_MACHINE(namesym, namestr, initfn, isdefault, malias, ...) \
+#define DEFINE_PC_VER_MACHINE(namesym, namestr, initfn, classinitextra, ...) \
static void MACHINE_VER_SYM(init, namesym, __VA_ARGS__)( \
MachineState *machine) \
{ \
@@ -322,8 +322,7 @@ extern const size_t pc_compat_4_1_len;
MACHINE_VER_SYM(options, namesym, __VA_ARGS__)(mc); \
mc->init = MACHINE_VER_SYM(init, namesym, __VA_ARGS__); \
MACHINE_VER_DEPRECATION(__VA_ARGS__); \
- mc->is_default = isdefault; \
- mc->alias = malias; \
+ classinitextra \
} \
static const TypeInfo MACHINE_VER_SYM(info, namesym, __VA_ARGS__) = \
{ \
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 06/48] hw/core: implement TYPE_ALIASED interface in machines
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (4 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 05/48] hw: tweak approach to setting alias in machine macros Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 07/48] qapi: report multiple aliases in MachineInfo Daniel P. Berrangé
` (42 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
Make the TYPE_MACHINE class implement the TYPE_ALIASED
interface which will replace use of the 'alias' parameter
in MachineClass. The current 'alias' records the user
facing machine name, while 'aliases' in TYPE_ALIASED
will report an internal type name alias.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/core/machine.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/hw/core/machine.c b/hw/core/machine.c
index ed9bf8f5008..f7406537aa7 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -1802,6 +1802,10 @@ static const TypeInfo machine_info = {
.instance_size = sizeof(MachineState),
.instance_init = machine_initfn,
.instance_finalize = machine_finalize,
+ .interfaces = (const InterfaceInfo[]) {
+ { TYPE_ALIASED },
+ { }
+ }
};
static void machine_register_types(void)
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 07/48] qapi: report multiple aliases in MachineInfo
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (5 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 06/48] hw/core: implement TYPE_ALIASED interface in machines Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-13 7:41 ` Markus Armbruster
2026-11-12 13:30 ` [PATCH 08/48] system: report multiple machine aliases in help output Daniel P. Berrangé
` (41 subsequent siblings)
48 siblings, 1 reply; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
The MachineInfo struct is extended to report the list of aliases
from the TYPE_ALIASED interface, in preference to the traditional
alias from the TYPE_MACHINE struct.
Initially we use 'alias' to fill the 'aliases' field in QOM. As
machines get converted to set 'aliases', the first 'aliases'
element will get used to fill 'alias. This provides backcompat
during the transition phase.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/core/machine-qmp-cmds.c | 25 +++++++++++++++++++++++++
qapi/machine.json | 3 +++
2 files changed, 28 insertions(+)
diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
index 0558d6d703c..787c69e176f 100644
--- a/hw/core/machine-qmp-cmds.c
+++ b/hw/core/machine-qmp-cmds.c
@@ -33,6 +33,7 @@
#include "system/runstate.h"
#include "system/system.h"
#include "hw/s390x/storage-keys.h"
+#include "qom/object_interfaces.h"
/*
* QMP query for enabled and present accelerators
@@ -163,6 +164,7 @@ MachineInfoList *qmp_query_machines(bool has_compat_props, bool compat_props,
MachineClass *mc = el->data;
const char *default_cpu_type = machine_class_default_cpu_type(mc);
MachineInfo *info;
+ AliasedClass *alc = ALIASED_CLASS(mc);
info = g_malloc0(sizeof(*info));
if (mc->is_default) {
@@ -170,8 +172,31 @@ MachineInfoList *qmp_query_machines(bool has_compat_props, bool compat_props,
info->is_default = true;
}
+ if (alc->aliases) {
+ strList **aliases = &info->aliases;
+ size_t i;
+ info->has_aliases = true;
+ for (i = 0; alc->aliases[i] != NULL; i++) {
+ /*
+ * We record type names internally, but publically
+ * we report machine types to the user, hence must
+ * strip the typename suffix
+ */
+ int len = strlen(alc->aliases[i]) - strlen(TYPE_MACHINE_SUFFIX);
+ QAPI_LIST_APPEND(aliases,
+ g_strndup(alc->aliases[i], len));
+ }
+ if (!mc->alias) {
+ int len = strlen(alc->aliases[0]) - strlen(TYPE_MACHINE_SUFFIX);
+ info->alias = g_strndup(alc->aliases[0], len);
+ }
+ }
if (mc->alias) {
info->alias = g_strdup(mc->alias);
+ if (!info->aliases) {
+ strList **aliases = &info->aliases;
+ QAPI_LIST_APPEND(aliases, g_strdup(mc->alias));
+ }
}
info->name = g_strdup(mc->name);
diff --git a/qapi/machine.json b/qapi/machine.json
index 18d9dce849b..c25a492a4e8 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -163,6 +163,8 @@
#
# @alias: an alias for the machine name
#
+# @aliases: a list of aliases for the machine type name (since 12.0)
+#
# @is-default: whether the machine is default
#
# @cpu-max: maximum number of CPUs supported by the machine type
@@ -202,6 +204,7 @@
##
{ 'struct': 'MachineInfo',
'data': { 'name': 'str', '*alias': 'str',
+ '*aliases': ['str'],
'*is-default': 'bool', 'cpu-max': 'int',
'hotpluggable-cpus': 'bool', 'numa-mem-supported': 'bool',
'deprecated': 'bool', '*default-cpu-type': 'str',
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* Re: [PATCH 07/48] qapi: report multiple aliases in MachineInfo
2026-11-12 13:30 ` [PATCH 07/48] qapi: report multiple aliases in MachineInfo Daniel P. Berrangé
@ 2026-11-13 7:41 ` Markus Armbruster
2026-11-13 9:31 ` Daniel P. Berrangé
0 siblings, 1 reply; 58+ messages in thread
From: Markus Armbruster @ 2026-11-13 7:41 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: qemu-devel, Philippe Mathieu-Daudé, Pierrick Bouvier,
Yonggang Luo
Daniel P. Berrangé <berrange@redhat.com> writes:
> The MachineInfo struct is extended to report the list of aliases
> from the TYPE_ALIASED interface, in preference to the traditional
> alias from the TYPE_MACHINE struct.
>
> Initially we use 'alias' to fill the 'aliases' field in QOM. As
> machines get converted to set 'aliases', the first 'aliases'
> element will get used to fill 'alias. This provides backcompat
> during the transition phase.
>
> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
[...]
> diff --git a/qapi/machine.json b/qapi/machine.json
> index 18d9dce849b..c25a492a4e8 100644
> --- a/qapi/machine.json
> +++ b/qapi/machine.json
> @@ -163,6 +163,8 @@
> #
> # @alias: an alias for the machine name
> #
> +# @aliases: a list of aliases for the machine type name (since 12.0)
> +#
How are these two related? Can one be present, and not the other? If
both are present, does @alias always equal the first element of
@aliases?
@alias gets deprecated in PATCH 11. Mention in the commit message?
> # @is-default: whether the machine is default
> #
> # @cpu-max: maximum number of CPUs supported by the machine type
> @@ -202,6 +204,7 @@
> ##
> { 'struct': 'MachineInfo',
> 'data': { 'name': 'str', '*alias': 'str',
> + '*aliases': ['str'],
> '*is-default': 'bool', 'cpu-max': 'int',
> 'hotpluggable-cpus': 'bool', 'numa-mem-supported': 'bool',
> 'deprecated': 'bool', '*default-cpu-type': 'str',
^ permalink raw reply [flat|nested] 58+ messages in thread* Re: [PATCH 07/48] qapi: report multiple aliases in MachineInfo
2026-11-13 7:41 ` Markus Armbruster
@ 2026-11-13 9:31 ` Daniel P. Berrangé
2026-11-13 10:21 ` Markus Armbruster
0 siblings, 1 reply; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-13 9:31 UTC (permalink / raw)
To: Markus Armbruster
Cc: qemu-devel, Philippe Mathieu-Daudé, Pierrick Bouvier,
Yonggang Luo
On Fri, Nov 13, 2026 at 08:41:35AM +0100, Markus Armbruster wrote:
> Daniel P. Berrangé <berrange@redhat.com> writes:
>
> > The MachineInfo struct is extended to report the list of aliases
> > from the TYPE_ALIASED interface, in preference to the traditional
> > alias from the TYPE_MACHINE struct.
> >
> > Initially we use 'alias' to fill the 'aliases' field in QOM. As
> > machines get converted to set 'aliases', the first 'aliases'
> > element will get used to fill 'alias. This provides backcompat
> > during the transition phase.
> >
> > Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
>
> [...]
>
> > diff --git a/qapi/machine.json b/qapi/machine.json
> > index 18d9dce849b..c25a492a4e8 100644
> > --- a/qapi/machine.json
> > +++ b/qapi/machine.json
> > @@ -163,6 +163,8 @@
> > #
> > # @alias: an alias for the machine name
> > #
> > +# @aliases: a list of aliases for the machine type name (since 12.0)
> > +#
>
> How are these two related? Can one be present, and not the other? If
> both are present, does @alias always equal the first element of
> @aliases?
Yes, both are set, or neither are set. If set, @alias and @aliases[0]
must always be identical.
> @alias gets deprecated in PATCH 11. Mention in the commit message?
Sure
>
> > # @is-default: whether the machine is default
> > #
> > # @cpu-max: maximum number of CPUs supported by the machine type
> > @@ -202,6 +204,7 @@
> > ##
> > { 'struct': 'MachineInfo',
> > 'data': { 'name': 'str', '*alias': 'str',
> > + '*aliases': ['str'],
> > '*is-default': 'bool', 'cpu-max': 'int',
> > 'hotpluggable-cpus': 'bool', 'numa-mem-supported': 'bool',
> > 'deprecated': 'bool', '*default-cpu-type': 'str',
>
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] 58+ messages in thread* Re: [PATCH 07/48] qapi: report multiple aliases in MachineInfo
2026-11-13 9:31 ` Daniel P. Berrangé
@ 2026-11-13 10:21 ` Markus Armbruster
0 siblings, 0 replies; 58+ messages in thread
From: Markus Armbruster @ 2026-11-13 10:21 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: qemu-devel, Philippe Mathieu-Daudé, Pierrick Bouvier,
Yonggang Luo
Daniel P. Berrangé <berrange@redhat.com> writes:
> On Fri, Nov 13, 2026 at 08:41:35AM +0100, Markus Armbruster wrote:
>> Daniel P. Berrangé <berrange@redhat.com> writes:
>>
>> > The MachineInfo struct is extended to report the list of aliases
>> > from the TYPE_ALIASED interface, in preference to the traditional
>> > alias from the TYPE_MACHINE struct.
>> >
>> > Initially we use 'alias' to fill the 'aliases' field in QOM. As
>> > machines get converted to set 'aliases', the first 'aliases'
>> > element will get used to fill 'alias. This provides backcompat
>> > during the transition phase.
>> >
>> > Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
>>
>> [...]
>>
>> > diff --git a/qapi/machine.json b/qapi/machine.json
>> > index 18d9dce849b..c25a492a4e8 100644
>> > --- a/qapi/machine.json
>> > +++ b/qapi/machine.json
>> > @@ -163,6 +163,8 @@
>> > #
>> > # @alias: an alias for the machine name
>> > #
>> > +# @aliases: a list of aliases for the machine type name (since 12.0)
>> > +#
>>
>> How are these two related? Can one be present, and not the other? If
>> both are present, does @alias always equal the first element of
>> @aliases?
>
> Yes, both are set, or neither are set. If set, @alias and @aliases[0]
> must always be identical.
Let's spell that out in the description.
>> @alias gets deprecated in PATCH 11. Mention in the commit message?
>
> Sure
>
>>
>> > # @is-default: whether the machine is default
>> > #
>> > # @cpu-max: maximum number of CPUs supported by the machine type
>> > @@ -202,6 +204,7 @@
>> > ##
>> > { 'struct': 'MachineInfo',
>> > 'data': { 'name': 'str', '*alias': 'str',
>> > + '*aliases': ['str'],
>> > '*is-default': 'bool', 'cpu-max': 'int',
>> > 'hotpluggable-cpus': 'bool', 'numa-mem-supported': 'bool',
>> > 'deprecated': 'bool', '*default-cpu-type': 'str',
>>
>
> With regards,
> Daniel
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 08/48] system: report multiple machine aliases in help output
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (6 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 07/48] qapi: report multiple aliases in MachineInfo Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 09/48] system: increase space for machine name in '-machine help' Daniel P. Berrangé
` (40 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
Update '-machine help' to report 'aliases' from the TYPE_ALIASED
interface, in preference to the traditional 'alias' from the
TYPE_MACHINE class. It is assumed that only one of the two fields
will be set at any time give a given class. Shortly existing
machines will be converted to the new approach and the old field
removed. '-machine help' output will remain unchanged across
this transition.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
system/vl.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/system/vl.c b/system/vl.c
index e7b759d5442..8ddf306002f 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -1583,7 +1583,16 @@ static void machine_help_func(const QDict *qdict)
machines = g_slist_sort_with_data(machines, machine_class_cmp, NULL);
for (el = machines; el; el = el->next) {
MachineClass *mc = el->data;
- if (mc->alias) {
+ AliasedClass *alc = ALIASED_CLASS(mc);
+ if (alc->aliases) {
+ size_t i;
+ for (i = 0; alc->aliases[i] != NULL; i++) {
+ printf("%-*.20s %s (alias of %s)\n",
+ (int)(strlen(alc->aliases[i]) -
+ strlen(TYPE_MACHINE_SUFFIX)),
+ alc->aliases[i], mc->desc, mc->name);
+ }
+ } else if (mc->alias) {
printf("%-20s %s (alias of %s)\n", mc->alias, mc->desc, mc->name);
}
printf("%-20s %s%s%s%s\n", mc->name, mc->desc,
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 09/48] system: increase space for machine name in '-machine help'
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (7 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 08/48] system: report multiple machine aliases in help output Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 10/48] system: resolve multiple aliases when creating machines Daniel P. Berrangé
` (39 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
The 20 character space allowed for machine names is quite tight
and is about to be exceeded, so bump it up to 25 characters.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
system/vl.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/system/vl.c b/system/vl.c
index 8ddf306002f..daf0637fb5e 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -1587,15 +1587,15 @@ static void machine_help_func(const QDict *qdict)
if (alc->aliases) {
size_t i;
for (i = 0; alc->aliases[i] != NULL; i++) {
- printf("%-*.20s %s (alias of %s)\n",
+ printf("%-*.25s %s (alias of %s)\n",
(int)(strlen(alc->aliases[i]) -
strlen(TYPE_MACHINE_SUFFIX)),
alc->aliases[i], mc->desc, mc->name);
}
} else if (mc->alias) {
- printf("%-20s %s (alias of %s)\n", mc->alias, mc->desc, mc->name);
+ printf("%-25s %s (alias of %s)\n", mc->alias, mc->desc, mc->name);
}
- printf("%-20s %s%s%s%s\n", mc->name, mc->desc,
+ printf("%-25s %s%s%s%s\n", mc->name, mc->desc,
mc->is_default ? " (default)" : "",
mc->deprecation_reason ? " (deprecated)" : "",
object_class_is_secure(OBJECT_CLASS(mc)) ? " (secure)" : "");
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 10/48] system: resolve multiple aliases when creating machines
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (8 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 09/48] system: increase space for machine name in '-machine help' Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 11/48] qapi: deprecate 'alias' field in MachineInfo Daniel P. Berrangé
` (38 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
Use aliased_class_resolve() to lookup a machine class when
no primary QOM type or MachineClass alias matches.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
system/vl.c | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/system/vl.c b/system/vl.c
index daf0637fb5e..f4e17173f96 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -843,19 +843,22 @@ static bool usb_parse(const char *cmdline, Error **errp)
/***********************************************************/
/* machine registration */
-static MachineClass *find_machine(const char *name, GSList *machines)
+static ObjectClass *find_machine(const char *name, GSList *machines,
+ Error **errp)
{
GSList *el;
+ g_autofree char *typename = NULL;
for (el = machines; el; el = el->next) {
MachineClass *mc = el->data;
if (!strcmp(mc->name, name) || !g_strcmp0(mc->alias, name)) {
- return mc;
+ return OBJECT_CLASS(mc);
}
}
- return NULL;
+ typename = g_strdup_printf("%s" TYPE_MACHINE_SUFFIX, name);
+ return aliased_class_resolve(TYPE_MACHINE, typename, errp);
}
static MachineClass *find_default_machine(GSList *machines)
@@ -1572,11 +1575,14 @@ static void machine_help_func(const QDict *qdict)
machines = object_class_get_list(TYPE_MACHINE, false);
if (type) {
- ObjectClass *machine_class = OBJECT_CLASS(find_machine(type, machines));
- if (machine_class) {
- type_print_class_properties(object_class_get_name(machine_class));
+ Error *local_err = NULL;
+ ObjectClass *machine_class = find_machine(type, machines, &local_err);
+ if (local_err) {
+ error_report_err(local_err);
return;
}
+ type_print_class_properties(object_class_get_name(machine_class));
+ return;
}
printf("Supported machines are:\n");
@@ -1696,10 +1702,8 @@ static MachineClass *select_machine(QDict *qdict, Error **errp)
MachineClass *machine_class = NULL;
if (machine_type) {
- machine_class = find_machine(machine_type, machines);
- if (!machine_class) {
- error_setg(errp, "unsupported machine type: \"%s\"", machine_type);
- }
+ machine_class = MACHINE_CLASS(
+ find_machine(machine_type, machines, errp));
qdict_del(qdict, "type");
} else {
machine_class = find_default_machine(machines);
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 11/48] qapi: deprecate 'alias' field in MachineInfo
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (9 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 10/48] system: resolve multiple aliases when creating machines Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-13 7:51 ` Markus Armbruster
2026-11-12 13:30 ` [PATCH 12/48] hw/arm: convert machines to use AliasedClass interface Daniel P. Berrangé
` (37 subsequent siblings)
48 siblings, 1 reply; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
It is replaced by the new 'aliases' field.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
docs/about/deprecated.rst | 7 +++++++
qapi/machine.json | 4 +++-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
index 0891bbc44de..88b21a018f9 100644
--- a/docs/about/deprecated.rst
+++ b/docs/about/deprecated.rst
@@ -182,6 +182,13 @@ execution. This special treatment of ``"no"`` is deprecated. Use an
empty string instead. In a future version, ``"no"`` will be treated as
a plain file name.
+``alias`` field of ``MachineInfo`` (since 12.0)
+'''''''''''''''''''''''''''''''''''''''''''''''
+
+The ``MachineInfo`` struct now has an ``aliases`` field which
+can report multiple aliases per machine, thus the ``alias``
+field is now redundant.
+
Human Machine Protocol (HMP) commands
-------------------------------------
diff --git a/qapi/machine.json b/qapi/machine.json
index c25a492a4e8..40fda705462 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -199,11 +199,13 @@
# Features:
#
# @unstable: Member @compat-props is experimental.
+# @deprecated: Member @alias is replaced by @aliases.
#
# Since: 1.2
##
{ 'struct': 'MachineInfo',
- 'data': { 'name': 'str', '*alias': 'str',
+ 'data': { 'name': 'str',
+ '*alias': { 'type': 'str', 'features': ['deprecated'] },
'*aliases': ['str'],
'*is-default': 'bool', 'cpu-max': 'int',
'hotpluggable-cpus': 'bool', 'numa-mem-supported': 'bool',
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* Re: [PATCH 11/48] qapi: deprecate 'alias' field in MachineInfo
2026-11-12 13:30 ` [PATCH 11/48] qapi: deprecate 'alias' field in MachineInfo Daniel P. Berrangé
@ 2026-11-13 7:51 ` Markus Armbruster
0 siblings, 0 replies; 58+ messages in thread
From: Markus Armbruster @ 2026-11-13 7:51 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: qemu-devel, Philippe Mathieu-Daudé, Pierrick Bouvier,
Yonggang Luo
Daniel P. Berrangé <berrange@redhat.com> writes:
> It is replaced by the new 'aliases' field.
>
> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
> ---
> docs/about/deprecated.rst | 7 +++++++
> qapi/machine.json | 4 +++-
> 2 files changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
> index 0891bbc44de..88b21a018f9 100644
> --- a/docs/about/deprecated.rst
> +++ b/docs/about/deprecated.rst
> @@ -182,6 +182,13 @@ execution. This special treatment of ``"no"`` is deprecated. Use an
> empty string instead. In a future version, ``"no"`` will be treated as
> a plain file name.
>
> +``alias`` field of ``MachineInfo`` (since 12.0)
> +'''''''''''''''''''''''''''''''''''''''''''''''
I prefer to talk about commands and events instead of types here.
Commands and events are what the user cares about. Types are detail.
Existing notes nearby use "member", not "field".
Together:
``query-machines`` return value member ``alias`` (since 12.0)
> +
> +The ``MachineInfo`` struct now has an ``aliases`` field which
> +can report multiple aliases per machine, thus the ``alias``
> +field is now redundant.
> +
We commonly phrase these notes like "don't use this, use that". Your
note conveys this, but it's not explicit. Maybe
Use member ``aliases`` instead.
would suffice.
We should've used a list of aliases from day one.
> Human Machine Protocol (HMP) commands
> -------------------------------------
>
> diff --git a/qapi/machine.json b/qapi/machine.json
> index c25a492a4e8..40fda705462 100644
> --- a/qapi/machine.json
> +++ b/qapi/machine.json
> @@ -199,11 +199,13 @@
> # Features:
> #
> # @unstable: Member @compat-props is experimental.
Blank line, please.
> +# @deprecated: Member @alias is replaced by @aliases.
We commonly phrase this as
# @deprecated: Member @alias is deprecated. Use @aliases instead.
> #
> # Since: 1.2
> ##
> { 'struct': 'MachineInfo',
> - 'data': { 'name': 'str', '*alias': 'str',
> + 'data': { 'name': 'str',
> + '*alias': { 'type': 'str', 'features': ['deprecated'] },
> '*aliases': ['str'],
> '*is-default': 'bool', 'cpu-max': 'int',
> 'hotpluggable-cpus': 'bool', 'numa-mem-supported': 'bool',
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 12/48] hw/arm: convert machines to use AliasedClass interface
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (10 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 11/48] qapi: deprecate 'alias' field in MachineInfo Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 13/48] hw/avr: " Daniel P. Berrangé
` (36 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
Stop setting 'alias' in the MachineClass and instead set
'aliases' in the AliasedClass.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/arm/aspeed_ast27x0_evb.c | 7 ++++++-
hw/arm/virt.c | 12 +++++++++++-
hw/arm/xlnx-versal-virt.c | 7 ++++++-
3 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/hw/arm/aspeed_ast27x0_evb.c b/hw/arm/aspeed_ast27x0_evb.c
index 460c9ff0d2e..9f7d4395114 100644
--- a/hw/arm/aspeed_ast27x0_evb.c
+++ b/hw/arm/aspeed_ast27x0_evb.c
@@ -11,6 +11,7 @@
#include "hw/arm/aspeed.h"
#include "hw/arm/aspeed_soc.h"
#include "hw/sensor/tmp105.h"
+#include "qom/object_interfaces.h"
/* AST2700 evb hardware value */
/* SCU HW Strap1 */
@@ -53,8 +54,12 @@ static void aspeed_machine_ast2700a2_evb_class_init(ObjectClass *oc,
{
MachineClass *mc = MACHINE_CLASS(oc);
AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
+ AliasedClass *alc = ALIASED_CLASS(oc);
+ static const char *const aliases[] = {
+ MACHINE_TYPE_NAME("ast2700-evb"), NULL,
+ };
- mc->alias = "ast2700-evb";
+ alc->aliases = aliases;
mc->desc = "Aspeed AST2700 A2 EVB (Cortex-A35)";
amc->soc_name = "ast2700-a2";
amc->hw_strap1 = AST2700_EVB_HW_STRAP1;
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index e481d0e548b..60385971b6a 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -94,6 +94,7 @@
#include "hw/cxl/cxl_host.h"
#include "qemu/guest-random.h"
#include "hw/watchdog/sbsa_gwdt.h"
+#include "qom/object_interfaces.h"
static GlobalProperty arm_virt_compat_defaults[] = {
{ TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "48" },
@@ -139,9 +140,18 @@ static void arm_virt_compat_default_set(MachineClass *mc)
} \
type_init(MACHINE_VER_SYM(register, virt, __VA_ARGS__));
+#define DEFINE_VIRT_MACHINE_ALIASES_LATEST(...) \
+ AliasedClass *alc = ALIASED_CLASS(oc); \
+ static const char *const MACHINE_VER_SYM(aliases, virt, __VA_ARGS__)[] = \
+ { \
+ MACHINE_TYPE_NAME("virt"), \
+ NULL, \
+ }; \
+ alc->aliases = MACHINE_VER_SYM(aliases, virt, __VA_ARGS__)
+
#define DEFINE_VIRT_MACHINE_AS_LATEST(major, minor) \
DEFINE_VIRT_MACHINE_IMPL({ \
- mc->alias = "virt"; \
+ DEFINE_VIRT_MACHINE_ALIASES_LATEST(major, minor); \
}, major, minor)
#define DEFINE_VIRT_MACHINE(major, minor) \
DEFINE_VIRT_MACHINE_IMPL({}, major, minor)
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
index 4018f2bf7d1..309063d38d8 100644
--- a/hw/arm/xlnx-versal-virt.c
+++ b/hw/arm/xlnx-versal-virt.c
@@ -23,6 +23,7 @@
#include "hw/arm/boot.h"
#include "qom/object.h"
#include "target/arm/cpu.h"
+#include "qom/object_interfaces.h"
#define TYPE_XLNX_VERSAL_VIRT_BASE_MACHINE \
MACHINE_TYPE_NAME("amd-versal-virt-base")
@@ -368,9 +369,13 @@ static void versal_virt_machine_class_init(ObjectClass *oc, const void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
VersalVirtClass *vvc = XLNX_VERSAL_VIRT_BASE_MACHINE_CLASS(oc);
+ AliasedClass *alc = ALIASED_CLASS(oc);
+ static const char *const aliases[] = {
+ MACHINE_TYPE_NAME("xlnx-versal-virt"), NULL,
+ };
mc->desc = "AMD Versal Virtual development board";
- mc->alias = "xlnx-versal-virt";
+ alc->aliases = aliases;
vvc->version = VERSAL_VER_VERSAL;
versal_virt_machine_class_init_common(oc);
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 13/48] hw/avr: convert machines to use AliasedClass interface
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (11 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 12/48] hw/arm: convert machines to use AliasedClass interface Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 14/48] hw/hexagon: " Daniel P. Berrangé
` (35 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
Stop setting 'alias' in the MachineClass and instead set
'aliases' in the AliasedClass.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/avr/arduino.c | 30 +++++++++++++++++++++++++-----
1 file changed, 25 insertions(+), 5 deletions(-)
diff --git a/hw/avr/arduino.c b/hw/avr/arduino.c
index e166ca18e11..fbcdc32a21f 100644
--- a/hw/avr/arduino.c
+++ b/hw/avr/arduino.c
@@ -14,7 +14,7 @@
#include "qapi/error.h"
#include "atmega.h"
#include "boot.h"
-#include "qom/object.h"
+#include "qom/object_interfaces.h"
struct ArduinoMachineState {
/*< private >*/
@@ -73,13 +73,18 @@ static void arduino_duemilanove_class_init(ObjectClass *oc, const void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc);
+ AliasedClass *alc = ALIASED_CLASS(mc);
+ static const char *const aliases[] = {
+ MACHINE_TYPE_NAME("2009"), NULL,
+ };
+
+ alc->aliases = aliases;
/*
* https://www.arduino.cc/en/Main/ArduinoBoardDuemilanove
* https://www.arduino.cc/en/uploads/Main/arduino-duemilanove-schematic.pdf
*/
mc->desc = "Arduino Duemilanove (ATmega168)",
- mc->alias = "2009";
amc->mcu_type = TYPE_ATMEGA168_MCU;
amc->xtal_hz = 16 * 1000 * 1000;
};
@@ -88,13 +93,18 @@ static void arduino_uno_class_init(ObjectClass *oc, const void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc);
+ AliasedClass *alc = ALIASED_CLASS(mc);
+ static const char *const aliases[] = {
+ MACHINE_TYPE_NAME("uno"), NULL,
+ };
+
+ alc->aliases = aliases;
/*
* https://store.arduino.cc/arduino-uno-rev3
* https://www.arduino.cc/en/uploads/Main/arduino-uno-schematic.pdf
*/
mc->desc = "Arduino UNO (ATmega328P)";
- mc->alias = "uno";
amc->mcu_type = TYPE_ATMEGA328_MCU;
amc->xtal_hz = 16 * 1000 * 1000;
};
@@ -103,13 +113,18 @@ static void arduino_mega_class_init(ObjectClass *oc, const void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc);
+ AliasedClass *alc = ALIASED_CLASS(mc);
+ static const char *const aliases[] = {
+ MACHINE_TYPE_NAME("mega"), NULL,
+ };
+
+ alc->aliases = aliases;
/*
* https://www.arduino.cc/en/Main/ArduinoBoardMega
* https://www.arduino.cc/en/uploads/Main/arduino-mega2560-schematic.pdf
*/
mc->desc = "Arduino Mega (ATmega1280)";
- mc->alias = "mega";
amc->mcu_type = TYPE_ATMEGA1280_MCU;
amc->xtal_hz = 16 * 1000 * 1000;
};
@@ -118,13 +133,18 @@ static void arduino_mega2560_class_init(ObjectClass *oc, const void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc);
+ AliasedClass *alc = ALIASED_CLASS(mc);
+ static const char *const aliases[] = {
+ MACHINE_TYPE_NAME("mega2560"), NULL,
+ };
+
+ alc->aliases = aliases;
/*
* https://store.arduino.cc/arduino-mega-2560-rev3
* https://www.arduino.cc/en/uploads/Main/arduino-mega2560_R3-sch.pdf
*/
mc->desc = "Arduino Mega 2560 (ATmega2560)";
- mc->alias = "mega2560";
amc->mcu_type = TYPE_ATMEGA2560_MCU;
amc->xtal_hz = 16 * 1000 * 1000; /* CSTCE16M0V53-R0 */
};
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 14/48] hw/hexagon: convert machines to use AliasedClass interface
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (12 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 13/48] hw/avr: " Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 15/48] hw/i386: " Daniel P. Berrangé
` (34 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
Stop setting 'alias' in the MachineClass and instead set
'aliases' in the AliasedClass.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/hexagon/hexagon_dsp.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/hw/hexagon/hexagon_dsp.c b/hw/hexagon/hexagon_dsp.c
index eddf69545ee..584b943cebf 100644
--- a/hw/hexagon/hexagon_dsp.c
+++ b/hw/hexagon/hexagon_dsp.c
@@ -38,6 +38,7 @@
#include "machine_cfg_v81qa_1.h.inc"
#include "machine_cfg_v85na_1.h.inc"
#include "machine_cfg_v85qa_1.h.inc"
+#include "qom/object_interfaces.h"
#define TYPE_HEXAGON_DSP_MACHINE "hexagon-dsp-machine"
#define HEXAGON_DSP_SUBSYSTEM_BASE 0xfc900000
@@ -365,9 +366,13 @@ static void v85na_1_config_init(MachineState *machine)
static void v85na_1_init(ObjectClass *oc, const void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
+ AliasedClass *alc = ALIASED_CLASS(oc);
+ static const char *const aliases[] = {
+ MACHINE_TYPE_NAME("sim"), NULL,
+ };
mc->desc = "Hexagon V85NA_1";
- mc->alias = "sim";
+ alc->aliases = aliases;
mc->init = v85na_1_config_init;
init_mc(mc);
mc->default_cpu_type = TYPE_HEXAGON_CPU_V85;
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 15/48] hw/i386: convert machines to use AliasedClass interface
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (13 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 14/48] hw/hexagon: " Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 16/48] hw/loongarch: " Daniel P. Berrangé
` (33 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
Stop setting 'alias' in the MachineClass and instead set
'aliases' in the AliasedClass.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/i386/pc_piix.c | 20 ++++++++++++++++++--
hw/i386/pc_q35.c | 12 +++++++++++-
2 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 88356bf0d77..8498dbeda81 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -66,6 +66,7 @@
#include "hw/uefi/var-service-api.h"
#include "hw/i386/acpi-build.h"
#include "target/i386/cpu.h"
+#include "qom/object_interfaces.h"
#define XEN_IOAPIC_NUM_PIRQS 128ULL
@@ -362,13 +363,23 @@ static void pc_i440fx_init(MachineState *machine)
pc_init1(machine, TYPE_I440FX_PCI_DEVICE);
}
+#define DEFINE_I440FX_MACHINE_ALIASES_LATEST(...) \
+ AliasedClass *alc = ALIASED_CLASS(oc); \
+ static const char *const MACHINE_VER_SYM(aliases, virt, __VA_ARGS__)[] = \
+ { \
+ MACHINE_TYPE_NAME("pc"), \
+ NULL, \
+ }; \
+ alc->aliases = MACHINE_VER_SYM(aliases, virt, __VA_ARGS__)
+
#define DEFINE_I440FX_MACHINE(major, minor) \
DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, \
{}, major, minor);
#define DEFINE_I440FX_MACHINE_AS_LATEST(major, minor) \
DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, { \
- mc->is_default = true; mc->alias = "pc"; \
+ DEFINE_I440FX_MACHINE_ALIASES_LATEST(major, minor); \
+ mc->is_default = true; \
}, major, minor);
static void pc_i440fx_machine_options(MachineClass *m)
@@ -637,9 +648,14 @@ DEFINE_I440FX_MACHINE(4, 1);
#ifdef CONFIG_XEN
static void xenfv_machine_4_2_options(MachineClass *m)
{
+ AliasedClass *alc = ALIASED_CLASS(m);
+ static const char *const aliases[] = {
+ MACHINE_TYPE_NAME("xenfv"), NULL,
+ };
+
pc_i440fx_machine_4_2_options(m);
m->desc = "Xen Fully-virtualized PC";
- m->alias = "xenfv";
+ alc->aliases = aliases;
m->max_cpus = HVM_MAX_VCPUS;
m->default_machine_opts = "accel=xen,suppress-vmdesc=on";
}
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 9c6459b934d..37fbb58ef39 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -63,6 +63,7 @@
#include "hw/uefi/var-service-api.h"
#include "hw/i386/acpi-build.h"
#include "target/i386/cpu.h"
+#include "qom/object_interfaces.h"
/* ICH9 AHCI has 6 ports */
#define MAX_SATA_PORTS 6
@@ -338,13 +339,22 @@ static void pc_q35_machine_set_wdat(Object *o, bool value, Error **errp)
pcms->wdat_enabled = value;
}
+#define DEFINE_Q35_MACHINE_ALIASES_LATEST(...) \
+ AliasedClass *alc = ALIASED_CLASS(oc); \
+ static const char *const MACHINE_VER_SYM(aliases, virt, __VA_ARGS__)[] = \
+ { \
+ MACHINE_TYPE_NAME("q35"), \
+ NULL, \
+ }; \
+ alc->aliases = MACHINE_VER_SYM(aliases, virt, __VA_ARGS__)
+
#define DEFINE_Q35_MACHINE(major, minor) \
DEFINE_PC_VER_MACHINE(pc_q35, "pc-q35", pc_q35_init, {}, \
major, minor);
#define DEFINE_Q35_MACHINE_AS_LATEST(major, minor) \
DEFINE_PC_VER_MACHINE(pc_q35, "pc-q35", pc_q35_init, { \
- mc->alias = "q35"; \
+ DEFINE_Q35_MACHINE_ALIASES_LATEST(major, minor); \
}, major, minor);
#define DEFINE_Q35_MACHINE_BUGFIX(major, minor, micro) \
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 16/48] hw/loongarch: convert machines to use AliasedClass interface
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (14 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 15/48] hw/i386: " Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 17/48] hw/m68k: " Daniel P. Berrangé
` (32 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
Stop setting 'alias' in the MachineClass and instead set
'aliases' in the AliasedClass.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/loongarch/virt.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 30a2ab6be9d..52b40883f4e 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -51,6 +51,7 @@
#include "qemu/error-report.h"
#include "qemu/log.h"
#include "kvm/kvm_loongarch.h"
+#include "qom/object_interfaces.h"
static int virt_get_dmsi(Object *obj, Error **errp)
{
@@ -1546,9 +1547,18 @@ static void virt_class_init(ObjectClass *oc, const void *data)
} \
type_init(MACHINE_VER_SYM(register, virt, __VA_ARGS__));
+#define DEFINE_VIRT_MACHINE_ALIASES_LATEST(...) \
+ AliasedClass *alc = ALIASED_CLASS(oc); \
+ static const char *const MACHINE_VER_SYM(aliases, virt, __VA_ARGS__)[] = \
+ { \
+ MACHINE_TYPE_NAME("virt"), \
+ NULL, \
+ }; \
+ alc->aliases = MACHINE_VER_SYM(aliases, virt, __VA_ARGS__)
+
#define DEFINE_VIRT_MACHINE_AS_LATEST(major, minor) \
DEFINE_VIRT_MACHINE_VERSION({ \
- mc->alias = "virt"; \
+ DEFINE_VIRT_MACHINE_ALIASES_LATEST(major, minor); \
mc->is_default = true; \
}, major, minor)
#define DEFINE_VIRT_MACHINE(major, minor) \
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 17/48] hw/m68k: convert machines to use AliasedClass interface
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (15 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 16/48] hw/loongarch: " Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 18/48] hw/ppc: " Daniel P. Berrangé
` (31 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
Stop setting 'alias' in the MachineClass and instead set
'aliases' in the AliasedClass.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/m68k/virt.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c
index 2418bd3d503..487d9bcc8d0 100644
--- a/hw/m68k/virt.c
+++ b/hw/m68k/virt.c
@@ -36,6 +36,7 @@
#include "hw/intc/goldfish_pic.h"
#include "hw/virtio/virtio-mmio.h"
#include "hw/virtio/virtio-blk.h"
+#include "qom/object_interfaces.h"
/*
* 6 goldfish-pic for CPU IRQ #1 to IRQ #6
@@ -362,10 +363,19 @@ type_init(virt_machine_register_types)
} \
type_init(MACHINE_VER_SYM(register, virt, __VA_ARGS__));
+#define DEFINE_VIRT_MACHINE_ALIASES_LATEST(...) \
+ AliasedClass *alc = ALIASED_CLASS(oc); \
+ static const char *const MACHINE_VER_SYM(aliases, virt, __VA_ARGS__)[] = \
+ { \
+ MACHINE_TYPE_NAME("virt"), \
+ NULL, \
+ }; \
+ alc->aliases = MACHINE_VER_SYM(aliases, virt, __VA_ARGS__)
+
#define DEFINE_VIRT_MACHINE_AS_LATEST(major, minor) \
DEFINE_VIRT_MACHINE_IMPL({ \
- mc->alias = "virt"; \
- }, major, minor)
+ DEFINE_VIRT_MACHINE_ALIASES_LATEST(major, minor); \
+ }, major, minor)
#define DEFINE_VIRT_MACHINE(major, minor) \
DEFINE_VIRT_MACHINE_IMPL({}, major, minor)
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 18/48] hw/ppc: convert machines to use AliasedClass interface
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (16 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 17/48] hw/m68k: " Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 19/48] hw/s390x: " Daniel P. Berrangé
` (30 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
Stop setting 'alias' in the MachineClass and instead set
'aliases' in the AliasedClass.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/ppc/pnv.c | 7 ++++++-
hw/ppc/spapr.c | 14 ++++++++++++--
2 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index f9478545ff9..a93d2953604 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -62,6 +62,7 @@
#include "hw/char/serial-isa.h"
#include "hw/rtc/mc146818rtc.h"
#include "exec/cpu-common.h"
+#include "qom/object_interfaces.h"
#include <libfdt.h>
@@ -3472,6 +3473,10 @@ static void pnv_machine_power11_class_init(ObjectClass *oc, const void *data)
PnvMachineClass *pmc = PNV_MACHINE_CLASS(oc);
XiveFabricClass *xfc = XIVE_FABRIC_CLASS(oc);
static const char compat[] = "qemu,powernv11\0ibm,powernv";
+ AliasedClass *alc = ALIASED_CLASS(oc);
+ static const char *const aliases[] = {
+ MACHINE_TYPE_NAME("powernv"), NULL
+ };
static GlobalProperty phb_compat[] = {
{ TYPE_PNV_PHB, "version", "5" },
@@ -3493,7 +3498,7 @@ static void pnv_machine_power11_class_init(ObjectClass *oc, const void *data)
mc->desc = "IBM PowerNV (Non-Virtualized) Power11";
mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power11_v2.0");
- mc->alias = "powernv";
+ alc->aliases = aliases;
object_class_property_add_bool(oc, "big-core",
pnv_machine_get_big_core,
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 8816f607a8f..aa14322222c 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -92,6 +92,7 @@
#include "hw/ppc/spapr_tpm_proxy.h"
#include "hw/ppc/spapr_nvdimm.h"
#include "hw/ppc/spapr_numa.h"
+#include "qom/object_interfaces.h"
#include <libfdt.h>
@@ -4752,9 +4753,18 @@ static const TypeInfo spapr_machine_info = {
} \
type_init(MACHINE_VER_SYM(register, spapr, __VA_ARGS__))
-#define DEFINE_SPAPR_MACHINE_AS_LATEST(major, minor) \
+#define DEFINE_SPAPR_MACHINE_ALIASES_LATEST(...) \
+ AliasedClass *alc = ALIASED_CLASS(oc); \
+ static const char *const MACHINE_VER_SYM(aliases, virt, __VA_ARGS__)[] = \
+ { \
+ MACHINE_TYPE_NAME("pseries"), \
+ NULL, \
+ }; \
+ alc->aliases = MACHINE_VER_SYM(aliases, virt, __VA_ARGS__)
+
+#define DEFINE_SPAPR_MACHINE_AS_LATEST(major, minor) \
DEFINE_SPAPR_MACHINE_IMPL({ \
- mc->alias = "pseries"; \
+ DEFINE_SPAPR_MACHINE_ALIASES_LATEST(major, minor); \
mc->is_default = true; \
}, major, minor)
#define DEFINE_SPAPR_MACHINE(major, minor) \
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 19/48] hw/s390x: convert machines to use AliasedClass interface
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (17 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 18/48] hw/ppc: " Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 20/48] include/hw: convert machine docs " Daniel P. Berrangé
` (29 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
Stop setting 'alias' in the MachineClass and instead set
'aliases' in the AliasedClass.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/s390x/s390-virtio-ccw.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index eafb603f3e0..3e14df4800f 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -52,6 +52,7 @@
#include "hw/virtio/virtio-md-pci.h"
#include "hw/s390x/virtio-ccw-md.h"
#include "system/replay.h"
+#include "qom/object_interfaces.h"
#include CONFIG_DEVICES
static Error *pv_mig_blocker;
@@ -995,9 +996,18 @@ static const TypeInfo ccw_machine_info = {
} \
type_init(MACHINE_VER_SYM(register, ccw, __VA_ARGS__))
+#define DEFINE_CCW_MACHINE_ALIASES_LATEST(...) \
+ AliasedClass *alc = ALIASED_CLASS(oc); \
+ static const char *const MACHINE_VER_SYM(aliases, virt, __VA_ARGS__)[] = \
+ { \
+ MACHINE_TYPE_NAME("s390-ccw-virtio"), \
+ NULL, \
+ }; \
+ alc->aliases = MACHINE_VER_SYM(aliases, virt, __VA_ARGS__)
+
#define DEFINE_CCW_MACHINE_AS_LATEST(major, minor) \
DEFINE_CCW_MACHINE_IMPL({ \
- mc->alias = "s390-ccw-virtio"; \
+ DEFINE_CCW_MACHINE_ALIASES_LATEST(major, minor); \
mc->is_default = true; \
}, major, minor)
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 20/48] include/hw: convert machine docs to use AliasedClass interface
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (18 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 19/48] hw/s390x: " Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 21/48] hw: drop 'alias' field from MachineClass Daniel P. Berrangé
` (28 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
Stop illustrating setting 'alias' in the MachineClass and
instead show setting 'aliases' in the AliasedClass.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
include/hw/core/boards.h | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/include/hw/core/boards.h b/include/hw/core/boards.h
index a25c627c0c8..ea1e26a8c52 100644
--- a/include/hw/core/boards.h
+++ b/include/hw/core/boards.h
@@ -490,10 +490,20 @@ struct MachineState {
* Following this, one (or more) helpers can be added for
* whichever scenarios need to be catered for with a machine:
*
+ *
+ * #define DEFINE_VIRT_MACHINE_ALIASES_LATEST(...) \
+ * AliasedClass *alc = ALIASED_CLASS(oc); \
+ * static const char *const MACHINE_VER_SYM(aliases, virt, __VA_ARGS__)[] = \
+ * { \
+ * MACHINE_TYPE_NAME("virt"), \
+ * NULL, \
+ * }; \
+ * alc->aliases = MACHINE_VER_SYM(aliases, virt, __VA_ARGS__)
+ *
* // Normal 2 digit, marked as latest e.g. 'virt-9.0'
* #define DEFINE_VIRT_MACHINE_LATEST(major, minor) \
* DEFINE_VIRT_MACHINE_IMPL({ \
- * mc->alias = "virt"; \
+ * DEFINE_VIRT_MACHINE_ALIASES_LATEST(major, minor); \
* }, major, minor)
*
* // Normal 2 digit e.g. 'virt-9.0'
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 21/48] hw: drop 'alias' field from MachineClass
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (19 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 20/48] include/hw: convert machine docs " Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 22/48] hw/arm: rename the 'virt' machines to 'arm-virt' Daniel P. Berrangé
` (27 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
Everything is converted to use the AliasedClass 'aliases' field
now.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/core/machine-qmp-cmds.c | 16 ++++------------
include/hw/core/boards.h | 1 -
system/vl.c | 4 +---
3 files changed, 5 insertions(+), 16 deletions(-)
diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
index 787c69e176f..ade5a31c239 100644
--- a/hw/core/machine-qmp-cmds.c
+++ b/hw/core/machine-qmp-cmds.c
@@ -175,6 +175,7 @@ MachineInfoList *qmp_query_machines(bool has_compat_props, bool compat_props,
if (alc->aliases) {
strList **aliases = &info->aliases;
size_t i;
+ int len;
info->has_aliases = true;
for (i = 0; alc->aliases[i] != NULL; i++) {
/*
@@ -182,21 +183,12 @@ MachineInfoList *qmp_query_machines(bool has_compat_props, bool compat_props,
* we report machine types to the user, hence must
* strip the typename suffix
*/
- int len = strlen(alc->aliases[i]) - strlen(TYPE_MACHINE_SUFFIX);
+ len = strlen(alc->aliases[i]) - strlen(TYPE_MACHINE_SUFFIX);
QAPI_LIST_APPEND(aliases,
g_strndup(alc->aliases[i], len));
}
- if (!mc->alias) {
- int len = strlen(alc->aliases[0]) - strlen(TYPE_MACHINE_SUFFIX);
- info->alias = g_strndup(alc->aliases[0], len);
- }
- }
- if (mc->alias) {
- info->alias = g_strdup(mc->alias);
- if (!info->aliases) {
- strList **aliases = &info->aliases;
- QAPI_LIST_APPEND(aliases, g_strdup(mc->alias));
- }
+ len = strlen(alc->aliases[0]) - strlen(TYPE_MACHINE_SUFFIX);
+ info->alias = g_strndup(alc->aliases[0], len);
}
info->name = g_strdup(mc->name);
diff --git a/include/hw/core/boards.h b/include/hw/core/boards.h
index ea1e26a8c52..0a5517a2a13 100644
--- a/include/hw/core/boards.h
+++ b/include/hw/core/boards.h
@@ -270,7 +270,6 @@ struct MachineClass {
const char *family; /* NULL iff @name identifies a standalone machtype */
char *name;
- const char *alias;
const char *desc;
const char *deprecation_reason;
diff --git a/system/vl.c b/system/vl.c
index f4e17173f96..fb5d55f3d68 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -852,7 +852,7 @@ static ObjectClass *find_machine(const char *name, GSList *machines,
for (el = machines; el; el = el->next) {
MachineClass *mc = el->data;
- if (!strcmp(mc->name, name) || !g_strcmp0(mc->alias, name)) {
+ if (!strcmp(mc->name, name)) {
return OBJECT_CLASS(mc);
}
}
@@ -1598,8 +1598,6 @@ static void machine_help_func(const QDict *qdict)
strlen(TYPE_MACHINE_SUFFIX)),
alc->aliases[i], mc->desc, mc->name);
}
- } else if (mc->alias) {
- printf("%-25s %s (alias of %s)\n", mc->alias, mc->desc, mc->name);
}
printf("%-25s %s%s%s%s\n", mc->name, mc->desc,
mc->is_default ? " (default)" : "",
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 22/48] hw/arm: rename the 'virt' machines to 'arm-virt'
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (20 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 21/48] hw: drop 'alias' field from MachineClass Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 23/48] hw/riscv: rename the 'virt' machines to 'riscv-virt' Daniel P. Berrangé
` (26 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
This introduces a globally unique QOM typename 'arm-virt' for
the virt machine types.
Aliases are added to resolve existing convenience names
'virt-$VER' and 'virt'.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/arm/virt.c | 17 +++++++++++++++--
include/hw/arm/virt.h | 2 +-
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 60385971b6a..6217771032e 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -127,7 +127,7 @@ static void arm_virt_compat_default_set(MachineClass *mc)
} \
static const TypeInfo MACHINE_VER_SYM(info, virt, __VA_ARGS__) = \
{ \
- .name = MACHINE_VER_TYPE_NAME("virt", __VA_ARGS__), \
+ .name = MACHINE_VER_TYPE_NAME("arm-virt", __VA_ARGS__), \
.parent = TYPE_VIRT_MACHINE, \
.class_init = MACHINE_VER_SYM(class_init, virt, __VA_ARGS__), \
.is_available = target_base_arm, \
@@ -145,6 +145,17 @@ static void arm_virt_compat_default_set(MachineClass *mc)
static const char *const MACHINE_VER_SYM(aliases, virt, __VA_ARGS__)[] = \
{ \
MACHINE_TYPE_NAME("virt"), \
+ MACHINE_VER_TYPE_NAME("virt", __VA_ARGS__), \
+ MACHINE_TYPE_NAME("arm-virt"), \
+ NULL, \
+ }; \
+ alc->aliases = MACHINE_VER_SYM(aliases, virt, __VA_ARGS__)
+
+#define DEFINE_VIRT_MACHINE_ALIASES(...) \
+ AliasedClass *alc = ALIASED_CLASS(oc); \
+ static const char *const MACHINE_VER_SYM(aliases, virt, __VA_ARGS__)[] = \
+ { \
+ MACHINE_VER_TYPE_NAME("virt", __VA_ARGS__), \
NULL, \
}; \
alc->aliases = MACHINE_VER_SYM(aliases, virt, __VA_ARGS__)
@@ -154,7 +165,9 @@ static void arm_virt_compat_default_set(MachineClass *mc)
DEFINE_VIRT_MACHINE_ALIASES_LATEST(major, minor); \
}, major, minor)
#define DEFINE_VIRT_MACHINE(major, minor) \
- DEFINE_VIRT_MACHINE_IMPL({}, major, minor)
+ DEFINE_VIRT_MACHINE_IMPL({ \
+ DEFINE_VIRT_MACHINE_ALIASES(major, minor); \
+ }, major, minor)
/* Number of external interrupt lines to configure the GIC with */
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 22e66d1a113..383ee320948 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -215,7 +215,7 @@ struct VirtMachineState {
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
-#define TYPE_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
+#define TYPE_VIRT_MACHINE MACHINE_TYPE_NAME("arm-virt")
OBJECT_DECLARE_TYPE(VirtMachineState, VirtMachineClass, VIRT_MACHINE)
void virt_acpi_setup(VirtMachineState *vms);
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 23/48] hw/riscv: rename the 'virt' machines to 'riscv-virt'
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (21 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 22/48] hw/arm: rename the 'virt' machines to 'arm-virt' Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 24/48] hw/hexagon: rename the 'virt' machine to 'hexagon-virt' Daniel P. Berrangé
` (25 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
This introduces a globally unique QOM typename 'riscv-virt' for
the virt machine type.
An alias is added to resolve existing convenience name 'virt'.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/riscv/virt.c | 9 ++++++++-
include/hw/riscv/virt.h | 2 +-
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 8bc5a7b0728..2901f67d796 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -61,6 +61,7 @@
#include "qapi/qapi-type-infos-common.h"
#include "hw/virtio/virtio-iommu.h"
#include "hw/uefi/var-service-api.h"
+#include "qom/object_interfaces.h"
#include "aia.h"
@@ -1123,6 +1124,10 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
+ AliasedClass *alc = ALIASED_CLASS(oc);
+ static const char *const aliases[] = {
+ MACHINE_TYPE_NAME("virt"), NULL,
+ };
mc->desc = "RISC-V VirtIO board";
mc->init = virt_machine_init;
@@ -1141,6 +1146,8 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data)
assert(!mc->get_hotplug_handler);
mc->get_hotplug_handler = virt_machine_get_hotplug_handler;
+ alc->aliases = aliases;
+
hc->plug = virt_machine_device_plug_cb;
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
@@ -1188,7 +1195,7 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data)
}
static const TypeInfo virt_machine_typeinfo = {
- .name = MACHINE_TYPE_NAME("virt"),
+ .name = MACHINE_TYPE_NAME("riscv-virt"),
.parent = TYPE_MACHINE,
.class_init = virt_machine_class_init,
.secure = true,
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index 6e4fbf4b647..5e7fc8a0c8f 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -30,7 +30,7 @@
#define VIRT_SOCKETS_MAX_BITS 2
#define VIRT_SOCKETS_MAX (1 << VIRT_SOCKETS_MAX_BITS)
-#define TYPE_RISCV_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
+#define TYPE_RISCV_VIRT_MACHINE MACHINE_TYPE_NAME("riscv-virt")
typedef struct RISCVVirtState RISCVVirtState;
DECLARE_INSTANCE_CHECKER(RISCVVirtState, RISCV_VIRT_MACHINE,
TYPE_RISCV_VIRT_MACHINE)
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 24/48] hw/hexagon: rename the 'virt' machine to 'hexagon-virt'
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (22 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 23/48] hw/riscv: rename the 'virt' machines to 'riscv-virt' Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 25/48] hw/loongarch: rename the 'virt' machine to 'loongarch-virt' Daniel P. Berrangé
` (24 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
This introduces a globally unique QOM typename 'hexagon-virt' for
the virt machine type.
An alias is added to resolve existing convenience name 'virt'.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/hexagon/virt.c | 6 ++++++
include/hw/hexagon/virt.h | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/hw/hexagon/virt.c b/hw/hexagon/virt.c
index 3327e28d121..645a3146810 100644
--- a/hw/hexagon/virt.c
+++ b/hw/hexagon/virt.c
@@ -19,6 +19,7 @@
#include "qemu/units.h"
#include "machine_cfg_v68n_1024.h.inc"
#include "system/device_tree.h"
+#include "qom/object_interfaces.h"
enum {
VIRT_UART0,
@@ -139,7 +140,12 @@ static void virt_init(MachineState *ms)
static void virt_class_init(ObjectClass *oc, const void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
+ AliasedClass *alc = ALIASED_CLASS(mc);
+ static const char *const aliases[] = {
+ MACHINE_TYPE_NAME("virt"), NULL,
+ };
+ alc->aliases = aliases;
mc->desc = "Hexagon Virtual Machine";
mc->init = virt_init;
mc->default_cpu_type = HEXAGON_CPU_TYPE_NAME("v68");
diff --git a/include/hw/hexagon/virt.h b/include/hw/hexagon/virt.h
index dc9f22a83c4..74763028b6b 100644
--- a/include/hw/hexagon/virt.h
+++ b/include/hw/hexagon/virt.h
@@ -20,7 +20,7 @@ struct HexagonVirtMachineState {
MemoryRegion tcm;
};
-#define TYPE_HEXAGON_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
+#define TYPE_HEXAGON_VIRT_MACHINE MACHINE_TYPE_NAME("hexagon-virt")
OBJECT_DECLARE_SIMPLE_TYPE(HexagonVirtMachineState, HEXAGON_VIRT_MACHINE)
#endif /* HW_HEXAGONVIRT_H */
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 25/48] hw/loongarch: rename the 'virt' machine to 'loongarch-virt'
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (23 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 24/48] hw/hexagon: rename the 'virt' machine to 'hexagon-virt' Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 26/48] hw/m68k: rename the 'virt' machine to 'm68k-virt' Daniel P. Berrangé
` (23 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
This introduces a globally unique QOM typename 'loongarch-virt' for
the virt machine type.
An alias is added to resolve existing convenience name 'virt'.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/loongarch/virt.c | 17 +++++++++++++++--
include/hw/loongarch/virt.h | 2 +-
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 52b40883f4e..a1ecc815a13 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -1535,7 +1535,7 @@ static void virt_class_init(ObjectClass *oc, const void *data)
} \
static const TypeInfo MACHINE_VER_SYM(info, virt, __VA_ARGS__) = \
{ \
- .name = MACHINE_VER_TYPE_NAME("virt", __VA_ARGS__), \
+ .name = MACHINE_VER_TYPE_NAME("loongarch-virt", __VA_ARGS__), \
.parent = TYPE_LOONGARCH_VIRT_MACHINE, \
.class_init = MACHINE_VER_SYM(class_init, virt, __VA_ARGS__), \
.secure = true, \
@@ -1552,6 +1552,17 @@ static void virt_class_init(ObjectClass *oc, const void *data)
static const char *const MACHINE_VER_SYM(aliases, virt, __VA_ARGS__)[] = \
{ \
MACHINE_TYPE_NAME("virt"), \
+ MACHINE_VER_TYPE_NAME("virt", __VA_ARGS__), \
+ MACHINE_TYPE_NAME("m68k-virt"), \
+ NULL, \
+ }; \
+ alc->aliases = MACHINE_VER_SYM(aliases, virt, __VA_ARGS__)
+
+#define DEFINE_VIRT_MACHINE_ALIASES(...) \
+ AliasedClass *alc = ALIASED_CLASS(oc); \
+ static const char *const MACHINE_VER_SYM(aliases, virt, __VA_ARGS__)[] = \
+ { \
+ MACHINE_VER_TYPE_NAME("virt", __VA_ARGS__), \
NULL, \
}; \
alc->aliases = MACHINE_VER_SYM(aliases, virt, __VA_ARGS__)
@@ -1562,7 +1573,9 @@ static void virt_class_init(ObjectClass *oc, const void *data)
mc->is_default = true; \
}, major, minor)
#define DEFINE_VIRT_MACHINE(major, minor) \
- DEFINE_VIRT_MACHINE_VERSION({}, major, minor)
+ DEFINE_VIRT_MACHINE_VERSION({ \
+ DEFINE_VIRT_MACHINE_ALIASES(major, minor); \
+ }, major, minor)
static void virt_instance_finalize(Object *obj)
{
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index d39a9bbf5dd..09529de48bd 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -130,7 +130,7 @@ struct LoongArchVirtMachineState {
bool highmem_mmio;
};
-#define TYPE_LOONGARCH_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
+#define TYPE_LOONGARCH_VIRT_MACHINE MACHINE_TYPE_NAME("loongarch-virt")
OBJECT_DECLARE_SIMPLE_TYPE(LoongArchVirtMachineState, LOONGARCH_VIRT_MACHINE)
void virt_acpi_setup(LoongArchVirtMachineState *lvms);
void virt_fdt_setup(LoongArchVirtMachineState *lvms);
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 26/48] hw/m68k: rename the 'virt' machine to 'm68k-virt'
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (24 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 25/48] hw/loongarch: rename the 'virt' machine to 'loongarch-virt' Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 27/48] hw/or1k: rename the 'virt' machine to 'or1k-virt' Daniel P. Berrangé
` (22 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
This introduces a globally unique QOM typename 'm68k-virt' for
the virt machine type.
An alias is added to resolve existing convenience name 'virt'.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/m68k/virt.c | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c
index 487d9bcc8d0..398293144c8 100644
--- a/hw/m68k/virt.c
+++ b/hw/m68k/virt.c
@@ -324,7 +324,7 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data)
}
static const TypeInfo virt_machine_info = {
- .name = MACHINE_TYPE_NAME("virt"),
+ .name = MACHINE_TYPE_NAME("m68k-virt"),
.parent = TYPE_MACHINE,
.abstract = true,
.class_init = virt_machine_class_init,
@@ -351,8 +351,8 @@ type_init(virt_machine_register_types)
} \
static const TypeInfo MACHINE_VER_SYM(info, virt, __VA_ARGS__) = \
{ \
- .name = MACHINE_VER_TYPE_NAME("virt", __VA_ARGS__), \
- .parent = MACHINE_TYPE_NAME("virt"), \
+ .name = MACHINE_VER_TYPE_NAME("m68k-virt", __VA_ARGS__), \
+ .parent = MACHINE_TYPE_NAME("m68k-virt"), \
.class_init = MACHINE_VER_SYM(class_init, virt, __VA_ARGS__), \
.is_available = target_m68k, \
}; \
@@ -368,6 +368,17 @@ type_init(virt_machine_register_types)
static const char *const MACHINE_VER_SYM(aliases, virt, __VA_ARGS__)[] = \
{ \
MACHINE_TYPE_NAME("virt"), \
+ MACHINE_VER_TYPE_NAME("virt", __VA_ARGS__), \
+ MACHINE_TYPE_NAME("m68k-virt"), \
+ NULL, \
+ }; \
+ alc->aliases = MACHINE_VER_SYM(aliases, virt, __VA_ARGS__)
+
+#define DEFINE_VIRT_MACHINE_ALIASES(...) \
+ AliasedClass *alc = ALIASED_CLASS(oc); \
+ static const char *const MACHINE_VER_SYM(aliases, virt, __VA_ARGS__)[] = \
+ { \
+ MACHINE_VER_TYPE_NAME("virt", __VA_ARGS__), \
NULL, \
}; \
alc->aliases = MACHINE_VER_SYM(aliases, virt, __VA_ARGS__)
@@ -377,7 +388,9 @@ type_init(virt_machine_register_types)
DEFINE_VIRT_MACHINE_ALIASES_LATEST(major, minor); \
}, major, minor)
#define DEFINE_VIRT_MACHINE(major, minor) \
- DEFINE_VIRT_MACHINE_IMPL({}, major, minor)
+ DEFINE_VIRT_MACHINE_IMPL({ \
+ DEFINE_VIRT_MACHINE_ALIASES(major, minor); \
+ }, major, minor)
static void virt_machine_11_2_options(MachineClass *mc)
{
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 27/48] hw/or1k: rename the 'virt' machine to 'or1k-virt'
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (25 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 26/48] hw/m68k: rename the 'virt' machine to 'm68k-virt' Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 28/48] hw/xtensa: rename the 'virt' machine to 'xtensa-virt' Daniel P. Berrangé
` (21 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
This introduces a globally unique QOM typename 'or1k-virt' for
the virt machine type.
An alias is added to resolve existing convenience name 'virt'.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/or1k/virt.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/hw/or1k/virt.c b/hw/or1k/virt.c
index a3ff903839b..579acdedfa6 100644
--- a/hw/or1k/virt.c
+++ b/hw/or1k/virt.c
@@ -28,13 +28,14 @@
#include "system/system.h"
#include "system/qtest.h"
#include "system/reset.h"
+#include "qom/object_interfaces.h"
#include <libfdt.h>
#define VIRT_CPUS_MAX 4
#define VIRT_CLK_MHZ 20000000
-#define TYPE_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
+#define TYPE_VIRT_MACHINE MACHINE_TYPE_NAME("or1k-virt")
#define VIRT_MACHINE(obj) \
OBJECT_CHECK(OR1KVirtState, (obj), TYPE_VIRT_MACHINE)
@@ -546,7 +547,12 @@ static void openrisc_virt_init(MachineState *machine)
static void openrisc_virt_machine_init(ObjectClass *oc, const void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
+ AliasedClass *alc = ALIASED_CLASS(oc);
+ static const char *const aliases[] = {
+ MACHINE_TYPE_NAME("virt"), NULL,
+ };
+ alc->aliases = aliases;
mc->desc = "or1k virtual machine";
mc->init = openrisc_virt_init;
mc->max_cpus = VIRT_CPUS_MAX;
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 28/48] hw/xtensa: rename the 'virt' machine to 'xtensa-virt'
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (26 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 27/48] hw/or1k: rename the 'virt' machine to 'or1k-virt' Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 29/48] system: stop sorting machine names based on 'family' Daniel P. Berrangé
` (20 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
This introduces a globally unique QOM typename 'xtensa-virt' for
the virt machine type.
An alias is added to resolve existing convenience name 'virt'.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/xtensa/virt.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/hw/xtensa/virt.c b/hw/xtensa/virt.c
index 271f06e0953..c1aec5b4c7c 100644
--- a/hw/xtensa/virt.c
+++ b/hw/xtensa/virt.c
@@ -37,6 +37,7 @@
#include "qemu/error-report.h"
#include "xtensa_memory.h"
#include "xtensa_sim.h"
+#include "qom/object_interfaces.h"
static void create_pcie(MachineState *ms, CPUXtensaState *env, int irq_base,
hwaddr addr_base)
@@ -117,6 +118,12 @@ static void xtensa_virt_init(MachineState *machine)
static void xtensa_virt_machine_init(MachineClass *mc)
{
+ AliasedClass *alc = ALIASED_CLASS(mc);
+ static const char *const aliases[] = {
+ MACHINE_TYPE_NAME("virt"), NULL,
+ };
+
+ alc->aliases = aliases;
mc->desc = "virt machine (" XTENSA_DEFAULT_CPU_MODEL ")";
mc->init = xtensa_virt_init;
mc->max_cpus = 32;
@@ -124,4 +131,4 @@ static void xtensa_virt_machine_init(MachineClass *mc)
mc->default_nic = "virtio-net-pci";
}
-DEFINE_MACHINE("virt", xtensa_virt_machine_init)
+DEFINE_MACHINE("xtensa-virt", xtensa_virt_machine_init)
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 29/48] system: stop sorting machine names based on 'family'
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (27 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 28/48] hw/xtensa: rename the 'virt' machine to 'xtensa-virt' Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 30/48] system: put machine aliases in alphbetical order Daniel P. Berrangé
` (19 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
Only the x86 'nitro-enclave', 'microvm', 'q35' and 'i440fx' machine
classes set a non-NULL 'family' field. This results in a fairly
strange looking sort order in the '-machine help' output, such that
from a user POV is appears largely unsorted. No other targets bother
to set 'family', even though they have far larger lists of machines.
It is sufficient to sort exclusively based on the machine type name
to get a purely alphabetical sorting.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
system/vl.c | 26 --------------------------
1 file changed, 26 deletions(-)
diff --git a/system/vl.c b/system/vl.c
index fb5d55f3d68..a187d10ad9c 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -1536,33 +1536,7 @@ static bool debugcon_parse(const char *devname, Error **errp)
static gint machine_class_cmp(gconstpointer a, gconstpointer b, gpointer d)
{
const MachineClass *mc1 = a, *mc2 = b;
- int res;
- if (mc1->family == NULL) {
- if (mc2->family == NULL) {
- /* Compare standalone machine types against each other; they sort
- * in increasing order.
- */
- return strcmp(object_class_get_name(OBJECT_CLASS(mc1)),
- object_class_get_name(OBJECT_CLASS(mc2)));
- }
-
- /* Standalone machine types sort after families. */
- return 1;
- }
-
- if (mc2->family == NULL) {
- /* Families sort before standalone machine types. */
- return -1;
- }
-
- /* Families sort between each other alphabetically increasingly. */
- res = strcmp(mc1->family, mc2->family);
- if (res != 0) {
- return res;
- }
-
- /* Within the same family, machine types sort in decreasing order. */
return strcmp(object_class_get_name(OBJECT_CLASS(mc2)),
object_class_get_name(OBJECT_CLASS(mc1)));
}
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 30/48] system: put machine aliases in alphbetical order
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (28 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 29/48] system: stop sorting machine names based on 'family' Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 31/48] system: filter machine type list if a target is selected Daniel P. Berrangé
` (18 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
When outputting machines for '-machine help', the machine classes
are sorted by name, but aliases, are always printed immediately
before the machine name.
Mostly the aliases share the same name prefix as the main machine
so this does not look odd, other than 'q35' appearing in the
middle of a list of machines with 'pc-q35' prefix.
With the forthcoming patches to rename the 'virt' machine classes
to have unique names across all targets, the positioning of aliases
in the output list looks much odder.
Change to fully alphabetically sort the '-machine help' output
so aliases are subject to the sorting alongside machines.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
system/vl.c | 41 ++++++++++++++++++++++++++---------------
1 file changed, 26 insertions(+), 15 deletions(-)
diff --git a/system/vl.c b/system/vl.c
index a187d10ad9c..e822a30c8df 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -1533,12 +1533,9 @@ static bool debugcon_parse(const char *devname, Error **errp)
return true;
}
-static gint machine_class_cmp(gconstpointer a, gconstpointer b, gpointer d)
+static int sort_lines(const void *p1, const void *p2)
{
- const MachineClass *mc1 = a, *mc2 = b;
-
- return strcmp(object_class_get_name(OBJECT_CLASS(mc2)),
- object_class_get_name(OBJECT_CLASS(mc1)));
+ return strcmp(*(const char **) p1, *(const char **) p2);
}
static void machine_help_func(const QDict *qdict)
@@ -1546,6 +1543,9 @@ static void machine_help_func(const QDict *qdict)
g_autoptr(GSList) machines = NULL;
GSList *el;
const char *type = qdict_get_try_str(qdict, "type");
+ g_auto(GStrv) lines = NULL;
+ size_t nlines = 0;
+ size_t i;
machines = object_class_get_list(TYPE_MACHINE, false);
if (type) {
@@ -1560,23 +1560,34 @@ static void machine_help_func(const QDict *qdict)
}
printf("Supported machines are:\n");
- machines = g_slist_sort_with_data(machines, machine_class_cmp, NULL);
for (el = machines; el; el = el->next) {
MachineClass *mc = el->data;
AliasedClass *alc = ALIASED_CLASS(mc);
if (alc->aliases) {
- size_t i;
for (i = 0; alc->aliases[i] != NULL; i++) {
- printf("%-*.25s %s (alias of %s)\n",
- (int)(strlen(alc->aliases[i]) -
- strlen(TYPE_MACHINE_SUFFIX)),
- alc->aliases[i], mc->desc, mc->name);
+ g_autofree char *name = g_strndup(
+ alc->aliases[i],
+ strlen(alc->aliases[i]) - strlen(TYPE_MACHINE_SUFFIX));
+ lines = g_renew(char *, lines, nlines + 2);
+ lines[nlines] = g_strdup_printf("%-25s %s (alias of %s)\n",
+ name, mc->desc, mc->name);
+ lines[nlines + 1] = NULL;
+ nlines++;
}
}
- printf("%-25s %s%s%s%s\n", mc->name, mc->desc,
- mc->is_default ? " (default)" : "",
- mc->deprecation_reason ? " (deprecated)" : "",
- object_class_is_secure(OBJECT_CLASS(mc)) ? " (secure)" : "");
+ lines = g_renew(char *, lines, nlines + 2);
+ lines[nlines] = g_strdup_printf(
+ "%-25s %s%s%s%s\n", mc->name, mc->desc,
+ mc->is_default ? " (default)" : "",
+ mc->deprecation_reason ? " (deprecated)" : "",
+ object_class_is_secure(OBJECT_CLASS(mc)) ? " (secure)" : "");
+ lines[nlines + 1] = NULL;
+ nlines++;
+ }
+ qsort(lines, nlines, sizeof(lines[0]), sort_lines);
+
+ for (i = 0; i < nlines; i++) {
+ fputs(lines[i], stdout);
}
}
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 31/48] system: filter machine type list if a target is selected
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (29 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 30/48] system: put machine aliases in alphbetical order Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 32/48] hw/core: " Daniel P. Berrangé
` (17 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
If a specific target is selected then filter the machine type
list, otherwise report all registered types and aliases.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
system/vl.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/system/vl.c b/system/vl.c
index e822a30c8df..0afcc18866d 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -144,6 +144,7 @@
#include "qemu/guest-random.h"
#include "qemu/keyval.h"
#include "memory-internal.h"
+#include "qemu/target-info-def.h"
#define MAX_VIRTIO_CONSOLES 1
@@ -1561,8 +1562,18 @@ static void machine_help_func(const QDict *qdict)
printf("Supported machines are:\n");
for (el = machines; el; el = el->next) {
- MachineClass *mc = el->data;
- AliasedClass *alc = ALIASED_CLASS(mc);
+ ObjectClass *oc = el->data;
+ MachineClass *mc = MACHINE_CLASS(oc);
+ AliasedClass *alc = ALIASED_CLASS(oc);
+ /*
+ * If we've selected a specific target, then filter
+ * based on what is creatable, otherwise report
+ * everything that is registered
+ */
+ if (target_info() && !target_specific_class_creatable(oc)) {
+ continue;
+ }
+
if (alc->aliases) {
for (i = 0; alc->aliases[i] != NULL; i++) {
g_autofree char *name = g_strndup(
@@ -1580,7 +1591,7 @@ static void machine_help_func(const QDict *qdict)
"%-25s %s%s%s%s\n", mc->name, mc->desc,
mc->is_default ? " (default)" : "",
mc->deprecation_reason ? " (deprecated)" : "",
- object_class_is_secure(OBJECT_CLASS(mc)) ? " (secure)" : "");
+ object_class_is_secure(oc) ? " (secure)" : "");
lines[nlines + 1] = NULL;
nlines++;
}
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 32/48] hw/core: filter machine type list if a target is selected
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (30 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 31/48] system: filter machine type list if a target is selected Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 33/48] system: filter machines based on target during creation Daniel P. Berrangé
` (16 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
If a specific target is selected then filter the machine type
list, otherwise report all registered types and aliases.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/core/machine-qmp-cmds.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
index ade5a31c239..3f06ce8c75f 100644
--- a/hw/core/machine-qmp-cmds.c
+++ b/hw/core/machine-qmp-cmds.c
@@ -34,6 +34,7 @@
#include "system/system.h"
#include "hw/s390x/storage-keys.h"
#include "qom/object_interfaces.h"
+#include "qemu/target-info-def.h"
/*
* QMP query for enabled and present accelerators
@@ -161,10 +162,20 @@ MachineInfoList *qmp_query_machines(bool has_compat_props, bool compat_props,
machines = object_class_get_list(TYPE_MACHINE, false);
for (el = machines; el; el = el->next) {
- MachineClass *mc = el->data;
+ ObjectClass *oc = el->data;
+ MachineClass *mc = MACHINE_CLASS(oc);
const char *default_cpu_type = machine_class_default_cpu_type(mc);
MachineInfo *info;
- AliasedClass *alc = ALIASED_CLASS(mc);
+ AliasedClass *alc = ALIASED_CLASS(oc);
+
+ /*
+ * If we've selected a specific target, then filter
+ * based on what is creatable, otherwise report
+ * everything that is registered
+ */
+ if (target_info() && !target_specific_class_creatable(oc)) {
+ continue;
+ }
info = g_malloc0(sizeof(*info));
if (mc->is_default) {
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 33/48] system: filter machines based on target during creation
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (31 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 32/48] hw/core: " Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 34/48] hw/core: implement TYPE_TARGET_SPECIFIC for machine Daniel P. Berrangé
` (15 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
When creating a machine instance, validate that it is creatable
on the current selected target.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
system/vl.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/system/vl.c b/system/vl.c
index 0afcc18866d..ca10e193f2b 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -845,16 +845,21 @@ static bool usb_parse(const char *cmdline, Error **errp)
/* machine registration */
static ObjectClass *find_machine(const char *name, GSList *machines,
- Error **errp)
+ bool creatable, Error **errp)
{
GSList *el;
g_autofree char *typename = NULL;
for (el = machines; el; el = el->next) {
- MachineClass *mc = el->data;
+ ObjectClass *oc = el->data;
+ MachineClass *mc = MACHINE_CLASS(oc);
if (!strcmp(mc->name, name)) {
- return OBJECT_CLASS(mc);
+ if (creatable) {
+ return target_specific_class_check(oc, errp);
+ } else {
+ return oc;
+ }
}
}
@@ -1551,7 +1556,8 @@ static void machine_help_func(const QDict *qdict)
machines = object_class_get_list(TYPE_MACHINE, false);
if (type) {
Error *local_err = NULL;
- ObjectClass *machine_class = find_machine(type, machines, &local_err);
+ ObjectClass *machine_class =
+ find_machine(type, machines, false, &local_err);
if (local_err) {
error_report_err(local_err);
return;
@@ -1697,7 +1703,7 @@ static MachineClass *select_machine(QDict *qdict, Error **errp)
if (machine_type) {
machine_class = MACHINE_CLASS(
- find_machine(machine_type, machines, errp));
+ find_machine(machine_type, machines, true, errp));
qdict_del(qdict, "type");
} else {
machine_class = find_default_machine(machines);
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 34/48] hw/core: implement TYPE_TARGET_SPECIFIC for machine
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (32 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 33/48] system: filter machines based on target during creation Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 35/48] qapi: report target compatibility for machine types Daniel P. Berrangé
` (14 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
The Machine base class implements TYPE_TARGET_SPECIFIC since
its children will almost all be target specific.
When the 'targets' field is set to a non-zero value on a
machine type, it will block creation of an instance of the
machine unless the current selected target matches. This
allows the current 'is_available' callback to be removed.
Eventually only the 'none' machine is likely to leave the
'targets' field set to 0, since it is universally creatable.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/core/machine.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/hw/core/machine.c b/hw/core/machine.c
index f7406537aa7..8692365ce89 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -1804,6 +1804,7 @@ static const TypeInfo machine_info = {
.instance_finalize = machine_finalize,
.interfaces = (const InterfaceInfo[]) {
{ TYPE_ALIASED },
+ { TYPE_TARGET_SPECIFIC },
{ }
}
};
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 35/48] qapi: report target compatibility for machine types
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (33 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 34/48] hw/core: implement TYPE_TARGET_SPECIFIC for machine Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-13 7:53 ` Markus Armbruster
2026-11-12 13:30 ` [PATCH 36/48] hw/arm: declare arm machine targets Daniel P. Berrangé
` (13 subsequent siblings)
48 siblings, 1 reply; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
Add a 'targets' field to MachineInfo which is populated with
the list of targets a machine is declard to be compatible
with.
To avoid reporting redundant information for the traditional
per-target emulator binaries, this new field is only emitted
if no target is currently selected, or the 'all-targets'
flag is explicitly set.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/core/machine-qmp-cmds.c | 18 ++++++++++++++++++
qapi/machine.json | 12 +++++++++++-
2 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
index 3f06ce8c75f..39624e91139 100644
--- a/hw/core/machine-qmp-cmds.c
+++ b/hw/core/machine-qmp-cmds.c
@@ -35,6 +35,7 @@
#include "hw/s390x/storage-keys.h"
#include "qom/object_interfaces.h"
#include "qemu/target-info-def.h"
+#include "qemu/base-arch-defs.h"
/*
* QMP query for enabled and present accelerators
@@ -155,11 +156,16 @@ qmp_query_cpu_model_expansion(CpuModelExpansionType type,
}
MachineInfoList *qmp_query_machines(bool has_compat_props, bool compat_props,
+ bool has_all_targets, bool all_targets,
Error **errp)
{
GSList *el, *machines;
MachineInfoList *mach_list = NULL;
+ if (target_mask_selected() == QEMU_ARCH_ALL) {
+ all_targets = true;
+ }
+
machines = object_class_get_list(TYPE_MACHINE, false);
for (el = machines; el; el = el->next) {
ObjectClass *oc = el->data;
@@ -167,6 +173,7 @@ MachineInfoList *qmp_query_machines(bool has_compat_props, bool compat_props,
const char *default_cpu_type = machine_class_default_cpu_type(mc);
MachineInfo *info;
AliasedClass *alc = ALIASED_CLASS(oc);
+ TargetSpecificClass *tsc = TARGET_SPECIFIC_CLASS(oc);
/*
* If we've selected a specific target, then filter
@@ -202,6 +209,17 @@ MachineInfoList *qmp_query_machines(bool has_compat_props, bool compat_props,
info->alias = g_strndup(alc->aliases[0], len);
}
+ if (tsc->targets && all_targets) {
+ SysEmuTargetList **targets = &info->targets;
+ size_t i;
+ info->has_targets = true;
+ for (i = 0; i < SYS_EMU_TARGET__MAX; i++) {
+ if (tsc->targets & QEMU_ARCH_BIT(i)) {
+ QAPI_LIST_APPEND(targets, i);
+ }
+ }
+ }
+
info->name = g_strdup(mc->name);
info->cpu_max = !mc->max_cpus ? 1 : mc->max_cpus;
info->hotpluggable_cpus = mc->has_hotpluggable_cpus;
diff --git a/qapi/machine.json b/qapi/machine.json
index 40fda705462..c3b3cce7e48 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -165,6 +165,11 @@
#
# @aliases: a list of aliases for the machine type name (since 12.0)
#
+# @targets: a list of compatible targets for the machine (since 12.0)
+# This is only reported if no target is currently selected
+# for the binary, or if the `query-machines` argument
+# @all-targets is true.
+#
# @is-default: whether the machine is default
#
# @cpu-max: maximum number of CPUs supported by the machine type
@@ -207,6 +212,7 @@
'data': { 'name': 'str',
'*alias': { 'type': 'str', 'features': ['deprecated'] },
'*aliases': ['str'],
+ '*targets': ['SysEmuTarget'],
'*is-default': 'bool', 'cpu-max': 'int',
'hotpluggable-cpus': 'bool', 'numa-mem-supported': 'bool',
'deprecated': 'bool', '*default-cpu-type': 'str',
@@ -222,6 +228,9 @@
# @compat-props: if true, also return compatibility properties.
# (default: false) (since 9.1)
#
+# @all-targets: if true, report all available targets even
+# when a target is selected (default: false) (since 12.0)
+#
# Features:
#
# @unstable: Argument @compat-props is experimental.
@@ -253,7 +262,8 @@
##
{ 'command': 'query-machines',
'data': { '*compat-props': { 'type': 'bool',
- 'features': [ 'unstable' ] } },
+ 'features': [ 'unstable' ] },
+ '*all-targets': 'bool' },
'returns': ['MachineInfo'] }
##
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* Re: [PATCH 35/48] qapi: report target compatibility for machine types
2026-11-12 13:30 ` [PATCH 35/48] qapi: report target compatibility for machine types Daniel P. Berrangé
@ 2026-11-13 7:53 ` Markus Armbruster
2026-11-13 9:36 ` Daniel P. Berrangé
0 siblings, 1 reply; 58+ messages in thread
From: Markus Armbruster @ 2026-11-13 7:53 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: qemu-devel, Philippe Mathieu-Daudé, Pierrick Bouvier,
Yonggang Luo
Daniel P. Berrangé <berrange@redhat.com> writes:
> Add a 'targets' field to MachineInfo which is populated with
> the list of targets a machine is declard to be compatible
> with.
>
> To avoid reporting redundant information for the traditional
> per-target emulator binaries, this new field is only emitted
> if no target is currently selected, or the 'all-targets'
> flag is explicitly set.
How much redundant data does this save in practice?
Is saving it worth the additional interface complexity?
> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [PATCH 35/48] qapi: report target compatibility for machine types
2026-11-13 7:53 ` Markus Armbruster
@ 2026-11-13 9:36 ` Daniel P. Berrangé
2026-11-13 10:41 ` Markus Armbruster
0 siblings, 1 reply; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-13 9:36 UTC (permalink / raw)
To: Markus Armbruster
Cc: qemu-devel, Philippe Mathieu-Daudé, Pierrick Bouvier,
Yonggang Luo
On Fri, Nov 13, 2026 at 08:53:58AM +0100, Markus Armbruster wrote:
> Daniel P. Berrangé <berrange@redhat.com> writes:
>
> > Add a 'targets' field to MachineInfo which is populated with
> > the list of targets a machine is declard to be compatible
> > with.
> >
> > To avoid reporting redundant information for the traditional
> > per-target emulator binaries, this new field is only emitted
> > if no target is currently selected, or the 'all-targets'
> > flag is explicitly set.
>
> How much redundant data does this save in practice?
>
> Is saving it worth the additional interface complexity?
All the arm machine types will report
targets: [ "arm", "aarch64"]
except for a handful which will be
targets: [ "aarch64"]
In a multi-target binary (ie what we intend to ship in
future, along side current binaries), it makes sense
that we report this, but in a single target binary
(ie what we ship today), it feels somewhat odd to me
to be reporting
targets: [ "arm", "aarch64"]
in the qemu-system-arm binary, given it can't support
aarch64.
So I wanted to hide the 'targets' output when a specific
target is selected.
Functionally there is no problem with reporting this
unconditionally in all scenarios. It just felt odd,
which admittedly is a weak reason for a technical
choice.
> > Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
>
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] 58+ messages in thread
* Re: [PATCH 35/48] qapi: report target compatibility for machine types
2026-11-13 9:36 ` Daniel P. Berrangé
@ 2026-11-13 10:41 ` Markus Armbruster
0 siblings, 0 replies; 58+ messages in thread
From: Markus Armbruster @ 2026-11-13 10:41 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: qemu-devel, Philippe Mathieu-Daudé, Pierrick Bouvier,
Yonggang Luo
Daniel P. Berrangé <berrange@redhat.com> writes:
> On Fri, Nov 13, 2026 at 08:53:58AM +0100, Markus Armbruster wrote:
>> Daniel P. Berrangé <berrange@redhat.com> writes:
>>
>> > Add a 'targets' field to MachineInfo which is populated with
>> > the list of targets a machine is declard to be compatible
>> > with.
>> >
>> > To avoid reporting redundant information for the traditional
>> > per-target emulator binaries, this new field is only emitted
>> > if no target is currently selected, or the 'all-targets'
>> > flag is explicitly set.
>>
>> How much redundant data does this save in practice?
>>
>> Is saving it worth the additional interface complexity?
>
> All the arm machine types will report
>
> targets: [ "arm", "aarch64"]
>
> except for a handful which will be
>
> targets: [ "aarch64"]
>
> In a multi-target binary (ie what we intend to ship in
> future, along side current binaries), it makes sense
> that we report this, but in a single target binary
> (ie what we ship today), it feels somewhat odd to me
> to be reporting
>
> targets: [ "arm", "aarch64"]
>
> in the qemu-system-arm binary, given it can't support
> aarch64.
>
> So I wanted to hide the 'targets' output when a specific
> target is selected.
>
> Functionally there is no problem with reporting this
> unconditionally in all scenarios. It just felt odd,
> which admittedly is a weak reason for a technical
> choice.
@targets is described as "a list of compatible targets for the machine".
Doesn't say "compatible targets this QEMU can do".
The targets this QEMU can do are available elsewhere. Right now, QEMU
can do just one, and query-target returns it. I expect future versions
that can support multiple targets will provide a query to return them
all.
I'd keep things simple and stateless: list all targets always. Clients
can easily compute the intersection with the targets this QEMU can do.
>> > Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
>>
>
> With regards,
> Daniel
^ permalink raw reply [flat|nested] 58+ messages in thread
* [PATCH 36/48] hw/arm: declare arm machine targets
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (34 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 35/48] qapi: report target compatibility for machine types Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 37/48] hw/hexagon: declare hexagon machine target Daniel P. Berrangé
` (12 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
This prevents creation of arm machines unless the current selected
target is arm and enables removal of the 'is_available' callback.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/arm/aspeed_ast27x0-fc.c | 5 ++++-
hw/arm/aspeed_ast27x0_evb.c | 7 +++++--
hw/arm/raspi.c | 9 ++++++---
hw/arm/raspi4b.c | 6 ++++--
hw/arm/virt.c | 6 ++++--
5 files changed, 23 insertions(+), 10 deletions(-)
diff --git a/hw/arm/aspeed_ast27x0-fc.c b/hw/arm/aspeed_ast27x0-fc.c
index 73362b60d2a..b0d2fc091d0 100644
--- a/hw/arm/aspeed_ast27x0-fc.c
+++ b/hw/arm/aspeed_ast27x0-fc.c
@@ -22,6 +22,8 @@
#include "hw/arm/boot.h"
#include "hw/block/flash.h"
#include "hw/arm/aspeed_coprocessor.h"
+#include "qom/object_interfaces.h"
+#include "qemu/base-arch-defs.h"
#define TYPE_AST2700FC MACHINE_TYPE_NAME("ast2700fc")
OBJECT_DECLARE_SIMPLE_TYPE(Ast2700FCState, AST2700FC);
@@ -220,12 +222,14 @@ static void ast2700fc_init(MachineState *machine)
static void ast2700fc_class_init(ObjectClass *oc, const void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
+ TargetSpecificClass *tsc = TARGET_SPECIFIC_CLASS(oc);
mc->desc = "ast2700 full core support";
mc->init = ast2700fc_init;
mc->no_floppy = 1;
mc->no_cdrom = 1;
mc->min_cpus = mc->max_cpus = mc->default_cpus = 6;
+ tsc->targets = QEMU_ARCH_BIT(SYS_EMU_TARGET_AARCH64);
}
static const TypeInfo ast2700fc_types[] = {
@@ -234,7 +238,6 @@ static const TypeInfo ast2700fc_types[] = {
.parent = TYPE_MACHINE,
.class_init = ast2700fc_class_init,
.instance_size = sizeof(Ast2700FCState),
- .is_available = target_aarch64,
},
};
diff --git a/hw/arm/aspeed_ast27x0_evb.c b/hw/arm/aspeed_ast27x0_evb.c
index 9f7d4395114..d698bb25833 100644
--- a/hw/arm/aspeed_ast27x0_evb.c
+++ b/hw/arm/aspeed_ast27x0_evb.c
@@ -12,6 +12,7 @@
#include "hw/arm/aspeed_soc.h"
#include "hw/sensor/tmp105.h"
#include "qom/object_interfaces.h"
+#include "qemu/base-arch-defs.h"
/* AST2700 evb hardware value */
/* SCU HW Strap1 */
@@ -33,7 +34,9 @@ static void aspeed_machine_ast2700a1_evb_class_init(ObjectClass *oc,
{
MachineClass *mc = MACHINE_CLASS(oc);
AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
+ TargetSpecificClass *tsc = TARGET_SPECIFIC_CLASS(oc);
+ tsc->targets = QEMU_ARCH_BIT(SYS_EMU_TARGET_AARCH64);
mc->desc = "Aspeed AST2700 A1 EVB (Cortex-A35)";
amc->soc_name = "ast2700-a1";
amc->hw_strap1 = AST2700_EVB_HW_STRAP1;
@@ -55,11 +58,13 @@ static void aspeed_machine_ast2700a2_evb_class_init(ObjectClass *oc,
MachineClass *mc = MACHINE_CLASS(oc);
AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
AliasedClass *alc = ALIASED_CLASS(oc);
+ TargetSpecificClass *tsc = TARGET_SPECIFIC_CLASS(oc);
static const char *const aliases[] = {
MACHINE_TYPE_NAME("ast2700-evb"), NULL,
};
alc->aliases = aliases;
+ tsc->targets = QEMU_ARCH_BIT(SYS_EMU_TARGET_AARCH64);
mc->desc = "Aspeed AST2700 A2 EVB (Cortex-A35)";
amc->soc_name = "ast2700-a2";
amc->hw_strap1 = AST2700_EVB_HW_STRAP1;
@@ -80,13 +85,11 @@ static const TypeInfo aspeed_ast27x0_evb_types[] = {
.name = MACHINE_TYPE_NAME("ast2700a1-evb"),
.parent = TYPE_ASPEED_MACHINE,
.class_init = aspeed_machine_ast2700a1_evb_class_init,
- .is_available = target_aarch64,
},
{
.name = MACHINE_TYPE_NAME("ast2700a2-evb"),
.parent = TYPE_ASPEED_MACHINE,
.class_init = aspeed_machine_ast2700a2_evb_class_init,
- .is_available = target_aarch64,
}
};
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
index fadbacb2534..b9b79942d29 100644
--- a/hw/arm/raspi.c
+++ b/hw/arm/raspi.c
@@ -24,7 +24,8 @@
#include "qemu/error-report.h"
#include "hw/core/boards.h"
#include "hw/core/loader.h"
-#include "qom/object.h"
+#include "qom/object_interfaces.h"
+#include "qemu/base-arch-defs.h"
#define TYPE_RASPI_MACHINE MACHINE_TYPE_NAME("raspi-common")
OBJECT_DECLARE_SIMPLE_TYPE(RaspiMachineState, RASPI_MACHINE)
@@ -370,9 +371,11 @@ static void raspi3ap_machine_class_init(ObjectClass *oc, const void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
RaspiBaseMachineClass *rmc = RASPI_BASE_MACHINE_CLASS(oc);
+ TargetSpecificClass *tsc = TARGET_SPECIFIC_CLASS(oc);
mc->auto_create_sdcard = true;
rmc->board_rev = 0x9020e0; /* Revision 1.0 */
+ tsc->targets = QEMU_ARCH_BIT(SYS_EMU_TARGET_AARCH64);
raspi_machine_class_init(mc, rmc->board_rev);
};
@@ -380,9 +383,11 @@ static void raspi3b_machine_class_init(ObjectClass *oc, const void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
RaspiBaseMachineClass *rmc = RASPI_BASE_MACHINE_CLASS(oc);
+ TargetSpecificClass *tsc = TARGET_SPECIFIC_CLASS(oc);
mc->auto_create_sdcard = true;
rmc->board_rev = 0xa02082;
+ tsc->targets = QEMU_ARCH_BIT(SYS_EMU_TARGET_AARCH64);
raspi_machine_class_init(mc, rmc->board_rev);
};
@@ -403,12 +408,10 @@ static const TypeInfo raspi_machine_types[] = {
.name = MACHINE_TYPE_NAME("raspi3ap"),
.parent = TYPE_RASPI_MACHINE,
.class_init = raspi3ap_machine_class_init,
- .is_available = target_aarch64,
}, {
.name = MACHINE_TYPE_NAME("raspi3b"),
.parent = TYPE_RASPI_MACHINE,
.class_init = raspi3b_machine_class_init,
- .is_available = target_aarch64,
}, {
.name = TYPE_RASPI_MACHINE,
.parent = TYPE_RASPI_BASE_MACHINE,
diff --git a/hw/arm/raspi4b.c b/hw/arm/raspi4b.c
index 600dfe686f2..69048f8b4a3 100644
--- a/hw/arm/raspi4b.c
+++ b/hw/arm/raspi4b.c
@@ -19,8 +19,9 @@
#include "hw/core/boards.h"
#include "hw/core/loader.h"
#include "hw/arm/boot.h"
-#include "qom/object.h"
+#include "qom/object_interfaces.h"
#include "hw/arm/bcm2838.h"
+#include "qemu/base-arch-defs.h"
#include <libfdt.h>
#define TYPE_RASPI4B_MACHINE MACHINE_TYPE_NAME("raspi4b")
@@ -88,11 +89,13 @@ static void raspi4b_machine_class_init(ObjectClass *oc, const void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
RaspiBaseMachineClass *rmc = RASPI_BASE_MACHINE_CLASS(oc);
+ TargetSpecificClass *tsc = TARGET_SPECIFIC_CLASS(oc);
rmc->board_rev = 0xb03115; /* Revision 1.5, 2 Gb RAM */
raspi_machine_class_common_init(mc, rmc->board_rev);
mc->auto_create_sdcard = true;
mc->init = raspi4b_machine_init;
+ tsc->targets = QEMU_ARCH_BIT(SYS_EMU_TARGET_AARCH64);
}
static const TypeInfo raspi4b_machine_type = {
@@ -100,7 +103,6 @@ static const TypeInfo raspi4b_machine_type = {
.parent = TYPE_RASPI_BASE_MACHINE,
.instance_size = sizeof(Raspi4bMachineState),
.class_init = raspi4b_machine_class_init,
- .is_available = target_aarch64,
};
static void raspi4b_machine_register_type(void)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 6217771032e..ca5cd3c16b8 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -95,6 +95,7 @@
#include "qemu/guest-random.h"
#include "hw/watchdog/sbsa_gwdt.h"
#include "qom/object_interfaces.h"
+#include "qemu/base-arch-defs.h"
static GlobalProperty arm_virt_compat_defaults[] = {
{ TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "48" },
@@ -119,10 +120,13 @@ static void arm_virt_compat_default_set(MachineClass *mc)
const void *data) \
{ \
MachineClass *mc = MACHINE_CLASS(oc); \
+ TargetSpecificClass *tsc = TARGET_SPECIFIC_CLASS(oc); \
arm_virt_compat_default_set(mc); \
MACHINE_VER_SYM(options, virt, __VA_ARGS__)(mc); \
mc->desc = "QEMU " MACHINE_VER_STR(__VA_ARGS__) " ARM Virtual Machine"; \
MACHINE_VER_DEPRECATION(__VA_ARGS__); \
+ tsc->targets = QEMU_ARCH_BIT(SYS_EMU_TARGET_ARM) | \
+ QEMU_ARCH_BIT(SYS_EMU_TARGET_AARCH64); \
classinitextra \
} \
static const TypeInfo MACHINE_VER_SYM(info, virt, __VA_ARGS__) = \
@@ -130,7 +134,6 @@ static void arm_virt_compat_default_set(MachineClass *mc)
.name = MACHINE_VER_TYPE_NAME("arm-virt", __VA_ARGS__), \
.parent = TYPE_VIRT_MACHINE, \
.class_init = MACHINE_VER_SYM(class_init, virt, __VA_ARGS__), \
- .is_available = target_base_arm, \
.secure = true, \
}; \
static void MACHINE_VER_SYM(register, virt, __VA_ARGS__)(void) \
@@ -4467,7 +4470,6 @@ static const TypeInfo virt_machine_info = {
{ TYPE_HOTPLUG_HANDLER },
{ }
},
- .is_available = target_base_arm,
};
static void machvirt_machine_init(void)
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 37/48] hw/hexagon: declare hexagon machine target
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (35 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 36/48] hw/arm: declare arm machine targets Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 38/48] hw/m68k: declare m68k " Daniel P. Berrangé
` (11 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
This prevents creation of hexagon machines unless the current selected
target is hexagon and enables removal of the 'is_available' callback.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/hexagon/virt.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/hw/hexagon/virt.c b/hw/hexagon/virt.c
index 645a3146810..f376f360a89 100644
--- a/hw/hexagon/virt.c
+++ b/hw/hexagon/virt.c
@@ -20,6 +20,7 @@
#include "machine_cfg_v68n_1024.h.inc"
#include "system/device_tree.h"
#include "qom/object_interfaces.h"
+#include "qemu/base-arch-defs.h"
enum {
VIRT_UART0,
@@ -141,11 +142,14 @@ static void virt_class_init(ObjectClass *oc, const void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
AliasedClass *alc = ALIASED_CLASS(mc);
+ TargetSpecificClass *tsc = TARGET_SPECIFIC_CLASS(oc);
static const char *const aliases[] = {
MACHINE_TYPE_NAME("virt"), NULL,
};
alc->aliases = aliases;
+ tsc->targets = QEMU_ARCH_BIT(SYS_EMU_TARGET_HEXAGON);
+
mc->desc = "Hexagon Virtual Machine";
mc->init = virt_init;
mc->default_cpu_type = HEXAGON_CPU_TYPE_NAME("v68");
@@ -167,7 +171,6 @@ static const TypeInfo virt_machine_types[] = { {
.parent = TYPE_HEXAGON_COMMON_MACHINE,
.instance_size = sizeof(HexagonVirtMachineState),
.class_init = virt_class_init,
- .is_available = target_hexagon,
} };
DEFINE_TYPES(virt_machine_types)
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 38/48] hw/m68k: declare m68k machine target
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (36 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 37/48] hw/hexagon: declare hexagon machine target Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 39/48] hw/or1k: declare or1k " Daniel P. Berrangé
` (10 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
This prevents creation of m68k machines unless the current selected
target is m68k and enables removal of the 'is_available' callback.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/m68k/virt.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c
index 398293144c8..b490d01efc9 100644
--- a/hw/m68k/virt.c
+++ b/hw/m68k/virt.c
@@ -37,6 +37,7 @@
#include "hw/virtio/virtio-mmio.h"
#include "hw/virtio/virtio-blk.h"
#include "qom/object_interfaces.h"
+#include "qemu/base-arch-defs.h"
/*
* 6 goldfish-pic for CPU IRQ #1 to IRQ #6
@@ -328,7 +329,6 @@ static const TypeInfo virt_machine_info = {
.parent = TYPE_MACHINE,
.abstract = true,
.class_init = virt_machine_class_init,
- .is_available = target_m68k,
};
static void virt_machine_register_types(void)
@@ -344,8 +344,10 @@ type_init(virt_machine_register_types)
const void *data) \
{ \
MachineClass *mc = MACHINE_CLASS(oc); \
+ TargetSpecificClass *tsc = TARGET_SPECIFIC_CLASS(oc); \
MACHINE_VER_SYM(options, virt, __VA_ARGS__)(mc); \
mc->desc = "QEMU " MACHINE_VER_STR(__VA_ARGS__) " M68K Virtual Machine"; \
+ tsc->targets = QEMU_ARCH_BIT(SYS_EMU_TARGET_M68K); \
MACHINE_VER_DEPRECATION(__VA_ARGS__); \
classinitextra \
} \
@@ -354,7 +356,6 @@ type_init(virt_machine_register_types)
.name = MACHINE_VER_TYPE_NAME("m68k-virt", __VA_ARGS__), \
.parent = MACHINE_TYPE_NAME("m68k-virt"), \
.class_init = MACHINE_VER_SYM(class_init, virt, __VA_ARGS__), \
- .is_available = target_m68k, \
}; \
static void MACHINE_VER_SYM(register, virt, __VA_ARGS__)(void) \
{ \
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 39/48] hw/or1k: declare or1k machine target
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (37 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 38/48] hw/m68k: declare m68k " Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 40/48] hw/riscv: declare riscv " Daniel P. Berrangé
` (9 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
This prevents creation of or1k machines unless the current selected
target is or1k and enables removal of the 'is_available' callback.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/or1k/virt.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/hw/or1k/virt.c b/hw/or1k/virt.c
index 579acdedfa6..6720467dfe2 100644
--- a/hw/or1k/virt.c
+++ b/hw/or1k/virt.c
@@ -29,6 +29,7 @@
#include "system/qtest.h"
#include "system/reset.h"
#include "qom/object_interfaces.h"
+#include "qemu/base-arch-defs.h"
#include <libfdt.h>
@@ -548,11 +549,13 @@ static void openrisc_virt_machine_init(ObjectClass *oc, const void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
AliasedClass *alc = ALIASED_CLASS(oc);
+ TargetSpecificClass *tsc = TARGET_SPECIFIC_CLASS(oc);
static const char *const aliases[] = {
MACHINE_TYPE_NAME("virt"), NULL,
};
alc->aliases = aliases;
+ tsc->targets = QEMU_ARCH_BIT(SYS_EMU_TARGET_OR1K);
mc->desc = "or1k virtual machine";
mc->init = openrisc_virt_init;
mc->max_cpus = VIRT_CPUS_MAX;
@@ -565,7 +568,6 @@ static const TypeInfo or1ksim_machine_typeinfo = {
.parent = TYPE_MACHINE,
.class_init = openrisc_virt_machine_init,
.instance_size = sizeof(OR1KVirtState),
- .is_available = target_or1k,
};
static void or1ksim_machine_init_register_types(void)
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 40/48] hw/riscv: declare riscv machine target
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (38 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 39/48] hw/or1k: declare or1k " Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 41/48] accel: make TYPE_ACCEL_CPU name target independent Daniel P. Berrangé
` (8 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
This prevents creation of riscv machines unless the current selected
target is riscv and enables removal of the 'is_available' callback.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/riscv/virt.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 2901f67d796..178b47f4c15 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -62,6 +62,7 @@
#include "hw/virtio/virtio-iommu.h"
#include "hw/uefi/var-service-api.h"
#include "qom/object_interfaces.h"
+#include "qemu/base-arch-defs.h"
#include "aia.h"
@@ -1125,6 +1126,7 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data)
MachineClass *mc = MACHINE_CLASS(oc);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
AliasedClass *alc = ALIASED_CLASS(oc);
+ TargetSpecificClass *tsc = TARGET_SPECIFIC_CLASS(oc);
static const char *const aliases[] = {
MACHINE_TYPE_NAME("virt"), NULL,
};
@@ -1147,6 +1149,8 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data)
mc->get_hotplug_handler = virt_machine_get_hotplug_handler;
alc->aliases = aliases;
+ tsc->targets = QEMU_ARCH_BIT(SYS_EMU_TARGET_RISCV32) |
+ QEMU_ARCH_BIT(SYS_EMU_TARGET_RISCV64);
hc->plug = virt_machine_device_plug_cb;
@@ -1202,7 +1206,6 @@ static const TypeInfo virt_machine_typeinfo = {
.instance_init = virt_machine_instance_init,
.instance_finalize = virt_machine_instance_finalize,
.instance_size = sizeof(RISCVVirtState),
- .is_available = target_base_riscv,
.interfaces = (const InterfaceInfo[]) {
{ TYPE_HOTPLUG_HANDLER },
{ }
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 41/48] accel: make TYPE_ACCEL_CPU name target independent
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (39 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 40/48] hw/riscv: declare riscv " Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 42/48] Revert "multi-target: restrict whpx-accel-*-cpu to matching target" Daniel P. Berrangé
` (7 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
The TYPE_ACCEL_CPU QOM type name currently expands to a dynamic
string based on the target CPU resolving type name. So we have
a hierarchy that looks like:
object
+- accel-{x86_64,ppc64,riscv64,...}-cpu
+- kvm-accel-x86_64-cpu
+- tcg-accel-x86_64-cpu
+- mshv-accel-x86_64-cpu
+- tcg-accel-riscv-cpu
where the middle class changes its name at runtime, so if leaf
CPU classes from different targets are linked together, their
immediate parent will be missing unless the selected target
matches.
The TYPE_ACCEL_CPU class is an abstract base class that does
not inherantly have target specific logic. It is expected to
be subclassed with children from different targets, and only
those childrenneed to have names derived from the CPU resolving
type name to ensure unique QOM naming.
IOW, TYPE_ACCEL_CPU can be given a fixed name while keeping
the same hierarchy structure:
object
+- accel-cpu
+- kvm-accel-x86_64-cpu
+- tcg-accel-x86_64-cpu
+- mshv-accel-x86_64-cpu
+- tcg-accel-riscv-cpu
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
accel/accel-common.c | 3 +--
include/accel/accel-cpu-target.h | 3 +--
include/accel/accel-cpu.h | 2 ++
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/accel/accel-common.c b/accel/accel-common.c
index 00a400243f0..05b1c44e1ed 100644
--- a/accel/accel-common.c
+++ b/accel/accel-common.c
@@ -132,9 +132,8 @@ DEFINE_TYPES(accel_types)
static void register_accel_target_type(void)
{
- g_autofree char *name = g_strconcat("accel-", target_cpu_type(), NULL);
const TypeInfo accel_cpu_type = {
- .name = name,
+ .name = TYPE_ACCEL_CPU,
.parent = TYPE_OBJECT,
.abstract = true,
.class_size = sizeof(AccelCPUClass),
diff --git a/include/accel/accel-cpu-target.h b/include/accel/accel-cpu-target.h
index 6feb344e29b..cf33ebd79fc 100644
--- a/include/accel/accel-cpu-target.h
+++ b/include/accel/accel-cpu-target.h
@@ -24,8 +24,7 @@
#include "accel/accel-cpu.h"
#include "cpu.h"
-#define TYPE_ACCEL_CPU "accel-" CPU_RESOLVING_TYPE
-#define ACCEL_CPU_NAME(name) (name "-" TYPE_ACCEL_CPU)
+#define ACCEL_CPU_NAME(name) (name "-accel-" CPU_RESOLVING_TYPE)
DECLARE_CLASS_CHECKERS(AccelCPUClass, ACCEL_CPU, TYPE_ACCEL_CPU)
#endif /* ACCEL_CPU_H */
diff --git a/include/accel/accel-cpu.h b/include/accel/accel-cpu.h
index 9e7eede7c3c..809b7d21fd3 100644
--- a/include/accel/accel-cpu.h
+++ b/include/accel/accel-cpu.h
@@ -20,4 +20,6 @@ typedef struct AccelCPUClass {
bool (*cpu_target_realize)(CPUState *cpu, Error **errp);
} AccelCPUClass;
+#define TYPE_ACCEL_CPU "accel-cpu"
+
#endif /* ACCEL_CPU_H */
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 42/48] Revert "multi-target: restrict whpx-accel-*-cpu to matching target"
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (40 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 41/48] accel: make TYPE_ACCEL_CPU name target independent Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 43/48] Revert "target/riscv/kvm: restrict kvm-accel-riscv-cpu to riscv targets" Daniel P. Berrangé
` (6 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
This reverts commit 1b879fe489f8894c5b07438f0b10706db916ca4f.
The conditional registration is no longer required since the
base class is now using a target independent name.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
accel/whpx/whpx-common.c | 8 --------
1 file changed, 8 deletions(-)
diff --git a/accel/whpx/whpx-common.c b/accel/whpx/whpx-common.c
index 20c684638b0..78d2827809b 100644
--- a/accel/whpx/whpx-common.c
+++ b/accel/whpx/whpx-common.c
@@ -20,7 +20,6 @@
#include "hw/core/boards.h"
#include "hw/intc/ioapic.h"
#include "qemu/error-report.h"
-#include "qemu/target-info.h"
#include "qapi/error.h"
#include "qapi/qapi-types-common.h"
#include "qapi/qapi-type-infos-common.h"
@@ -493,18 +492,11 @@ static void whpx_cpu_accel_class_init(ObjectClass *oc, const void *data)
acc->cpu_instance_init = whpx_cpu_instance_init;
}
-/* TYPE_ACCEL_CPU is only registered for current target cpu type */
-static bool whpx_cpu_accel_is_available(void)
-{
- return !strcmp(target_cpu_type(), CPU_RESOLVING_TYPE);
-}
-
static const TypeInfo whpx_cpu_accel_type = {
.name = ACCEL_CPU_NAME("whpx"),
.parent = TYPE_ACCEL_CPU,
.class_init = whpx_cpu_accel_class_init,
- .is_available = whpx_cpu_accel_is_available,
.abstract = true,
};
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 43/48] Revert "target/riscv/kvm: restrict kvm-accel-riscv-cpu to riscv targets"
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (41 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 42/48] Revert "multi-target: restrict whpx-accel-*-cpu to matching target" Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 44/48] Revert "target/riscv/tcg: restrict tcg-accel-riscv-cpu " Daniel P. Berrangé
` (5 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
This reverts commit 2d3e6b4003d5380c245ce8ffac4b8866f6d10a33.
The conditional registration is no longer required since the
base class is now using a target independent name.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
target/riscv/kvm/kvm-cpu.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index 5beb6023380..aa28098e10e 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -27,7 +27,6 @@
#include "qapi/qapi-builtin-type-infos.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
-#include "qemu/target-info.h"
#include "qapi/visitor.h"
#include "system/system.h"
#include "system/kvm.h"
@@ -2241,7 +2240,6 @@ static const TypeInfo kvm_cpu_accel_type_info = {
.parent = TYPE_ACCEL_CPU,
.class_init = kvm_cpu_accel_class_init,
- .is_available = target_base_riscv,
.abstract = true,
};
static void kvm_cpu_accel_register_types(void)
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 44/48] Revert "target/riscv/tcg: restrict tcg-accel-riscv-cpu to riscv targets"
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (42 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 43/48] Revert "target/riscv/kvm: restrict kvm-accel-riscv-cpu to riscv targets" Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 45/48] qom: drop the 'is_available' callback from TypeInfo Daniel P. Berrangé
` (4 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
From: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
This reverts commit ec65e16fd2ba012d57b1bbfcfcd04c31c4111924.
The conditional registration is no longer required since the
base class is now using a target independent name.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
target/riscv/tcg/tcg-cpu.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 5834ec1524f..3d9c9973292 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -1755,7 +1755,6 @@ static const TypeInfo riscv_tcg_cpu_accel_type_info = {
.parent = TYPE_ACCEL_CPU,
.class_init = riscv_tcg_cpu_accel_class_init,
- .is_available = target_base_riscv,
.abstract = true,
};
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 45/48] qom: drop the 'is_available' callback from TypeInfo
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (43 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 44/48] Revert "target/riscv/tcg: restrict tcg-accel-riscv-cpu " Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 46/48] hw/pci: unconditionally expose the 'loadparm' property Daniel P. Berrangé
` (3 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
For the purposes of introspection, a binary must always register
all compiled in types (classes). Any filtering of what is
permitted with a given selected target should happen at time of
use/query. As such the 'is_available' callback on TypeInfo is
an undesirable design pattern and with Machine classes converted
it can be removed.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
include/qom/object.h | 3 ---
qom/object.c | 4 ----
rust/qom/src/qom.rs | 1 -
3 files changed, 8 deletions(-)
diff --git a/include/qom/object.h b/include/qom/object.h
index 70d8ea3e299..06a55b410ba 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -475,8 +475,6 @@ struct Object
* @class_data: Data to pass to the @class_init,
* @class_base_init. This can be useful when building dynamic
* classes.
- * @is_available: callback invoked at registration time, to dynamically check if
- * this type should be available or not.
* @interfaces: The list of interfaces associated with this type. This
* should point to a static array that's terminated with a zero filled
* element.
@@ -500,7 +498,6 @@ struct TypeInfo
void (*class_base_init)(ObjectClass *klass, const void *data);
const void *class_data;
- bool (*is_available)(void);
const InterfaceInfo *interfaces;
};
diff --git a/qom/object.c b/qom/object.c
index 9276b7a4351..e18622d4146 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -167,10 +167,6 @@ static TypeImpl *type_register_internal(const TypeInfo *info)
abort();
}
- if (info->is_available && !info->is_available()) {
- return NULL;
- }
-
ti = type_new(info);
type_table_add(ti);
diff --git a/rust/qom/src/qom.rs b/rust/qom/src/qom.rs
index 81449eeefad..372be188622 100644
--- a/rust/qom/src/qom.rs
+++ b/rust/qom/src/qom.rs
@@ -695,7 +695,6 @@ pub trait ObjectImpl: ObjectType + IsA<Object> {
class_init: Some(rust_class_init::<Self>),
class_base_init: Self::CLASS_BASE_INIT,
class_data: core::ptr::null(),
- is_available: None,
interfaces: core::ptr::null(),
};
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 46/48] hw/pci: unconditionally expose the 'loadparm' property
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (44 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 45/48] qom: drop the 'is_available' callback from TypeInfo Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 47/48] hw/scsi: " Daniel P. Berrangé
` (2 subsequent siblings)
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
From: Yonggang Luo <luoyonggang@gmail.com>
With the multi-target work, the goal is to move to a single
unified QOM tree that applies universally across all targets.
This complements the migration away from instance level
properties to class level properties, which again aims to
ensure a statically defined stable QOM object model for each
class.
This requires that properties are either unconditionally
registered in the class, with invalid options rejected
at runtime (for example, during realize()), or that distinct
subclasses are used for specialized use cases that need a
distinct impl for some targets.
It is harmless to have the 'loadparm' property registered
unconditionally so take the simple option.
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
hw/pci/pci.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index d8b117799f3..32049394691 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -2889,6 +2889,11 @@ static void pci_qdev_property_set_loadparm(Object *obj, const char *value,
{
void *lp_str;
+ if (!target_s390x()) {
+ error_setg(errp, "'loadparm' is only supported on s390x");
+ return;
+ }
+
if (object_property_get_int(obj, "bootindex", NULL) < 0) {
error_setg(errp, "'loadparm' is only valid for boot devices");
return;
@@ -2906,14 +2911,11 @@ void pci_qdev_property_add_specifics(DeviceClass *dc)
{
ObjectClass *oc = OBJECT_CLASS(dc);
- /* The loadparm property is only supported on s390x */
- if (target_s390x()) {
- object_class_property_add_str(oc, "loadparm",
- pci_qdev_property_get_loadparm,
- pci_qdev_property_set_loadparm);
- object_class_property_set_description(oc, "loadparm",
- "load parameter (s390x only)");
- }
+ object_class_property_add_str(oc, "loadparm",
+ pci_qdev_property_get_loadparm,
+ pci_qdev_property_set_loadparm);
+ object_class_property_set_description(oc, "loadparm",
+ "load parameter (s390x only)");
}
MemoryRegion *pci_address_space(PCIDevice *dev)
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 47/48] hw/scsi: unconditionally expose the 'loadparm' property
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (45 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 46/48] hw/pci: unconditionally expose the 'loadparm' property Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 13:30 ` [PATCH 48/48] hw/virtio/virtio-mem: unconditionally expose 'unplugged-inaccessible' Daniel P. Berrangé
2026-11-12 15:08 ` [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Yonggang Luo
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
From: Yonggang Luo <luoyonggang@gmail.com>
With the multi-target work, the goal is to move to a single
unified QOM tree that applies universally across all targets.
This complements the migration away from instance level
properties to class level properties, which again aims to
ensure a statically defined stable QOM object model for each
class.
This requires that properties are either unconditionally
registered in the class, with invalid options rejected
at runtime (for example, during realize()), or that distinct
subclasses are used for specialized use cases that need a
distinct impl for some targets.
It is harmless to have the 'loadparm' property registered
unconditionally so take the simple option.
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
hw/scsi/scsi-disk.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index de2b6d85da8..7fec5a74d14 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -3212,6 +3212,11 @@ static void scsi_property_set_loadparm(Object *obj, const char *value,
{
void *lp_str;
+ if (!target_s390x()) {
+ error_setg(errp, "'loadparm' is only supported on s390x");
+ return;
+ }
+
if (object_property_get_int(obj, "bootindex", NULL) < 0) {
error_setg(errp, "'loadparm' is only valid for boot devices");
return;
@@ -3229,14 +3234,11 @@ static void scsi_property_add_specifics(DeviceClass *dc)
{
ObjectClass *oc = OBJECT_CLASS(dc);
- /* The loadparm property is only supported on s390x */
- if (target_s390x()) {
- object_class_property_add_str(oc, "loadparm",
- scsi_property_get_loadparm,
- scsi_property_set_loadparm);
- object_class_property_set_description(oc, "loadparm",
- "load parameter (s390x only)");
- }
+ object_class_property_add_str(oc, "loadparm",
+ scsi_property_get_loadparm,
+ scsi_property_set_loadparm);
+ object_class_property_set_description(oc, "loadparm",
+ "load parameter (s390x only)");
}
static void scsi_disk_base_class_initfn(ObjectClass *klass, const void *data)
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* [PATCH 48/48] hw/virtio/virtio-mem: unconditionally expose 'unplugged-inaccessible'
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (46 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 47/48] hw/scsi: " Daniel P. Berrangé
@ 2026-11-12 13:30 ` Daniel P. Berrangé
2026-11-12 15:08 ` [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Yonggang Luo
48 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-12 13:30 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Pierrick Bouvier, Markus Armbruster,
Yonggang Luo, Daniel P. Berrangé
From: Yonggang Luo <luoyonggang@gmail.com>
With the multi-target work, the goal is to move to a single
unified QOM tree that applies universally across all targets.
This complements the migration away from instance level
properties to class level properties, which again aims to
ensure a statically defined stable QOM object model for each
class.
This requires that properties are either unconditionally
registered in the class, with invalid options rejected
at runtime (for example, during realize()), or that distinct
subclasses are used for specialized use cases that need a
distinct impl for some targets.
It is harmless to have the 'unplugged-inaccessible' property
registered unconditionally so take the simple option.
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
hw/virtio/virtio-mem.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
index 546ea18b7c4..fb029581024 100644
--- a/hw/virtio/virtio-mem.c
+++ b/hw/virtio/virtio-mem.c
@@ -880,7 +880,11 @@ static void virtio_mem_device_realize(DeviceState *dev, Error **errp)
break;
}
} else {
- vmem->unplugged_inaccessible = ON_OFF_AUTO_ON;
+ if (vmem->unplugged_inaccessible != ON_OFF_AUTO_ON) {
+ error_setg(errp, "'%s' must be 'on' on non-x86 targets",
+ VIRTIO_MEM_UNPLUGGED_INACCESSIBLE_PROP);
+ return;
+ }
}
if (vmem->dynamic_memslots &&
@@ -1573,9 +1577,6 @@ static const Property virtio_mem_properties[] = {
early_migration, true),
DEFINE_PROP_BOOL(VIRTIO_MEM_DYNAMIC_MEMSLOTS_PROP, VirtIOMEM,
dynamic_memslots, false),
-};
-
-static const Property virtio_mem_legacy_guests_properties[] = {
DEFINE_PROP_ON_OFF_AUTO(VIRTIO_MEM_UNPLUGGED_INACCESSIBLE_PROP, VirtIOMEM,
unplugged_inaccessible, ON_OFF_AUTO_ON),
};
@@ -1640,9 +1641,6 @@ static void virtio_mem_class_init(ObjectClass *klass, const void *data)
RamDiscardSourceClass *rdsc = RAM_DISCARD_SOURCE_CLASS(klass);
device_class_set_props(dc, virtio_mem_properties);
- if (virtio_mem_has_legacy_guests()) {
- device_class_set_props(dc, virtio_mem_legacy_guests_properties);
- }
dc->vmsd = &vmstate_virtio_mem;
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
--
2.56.1
^ permalink raw reply related [flat|nested] 58+ messages in thread* Re: [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds
2026-11-12 13:30 [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Daniel P. Berrangé
` (47 preceding siblings ...)
2026-11-12 13:30 ` [PATCH 48/48] hw/virtio/virtio-mem: unconditionally expose 'unplugged-inaccessible' Daniel P. Berrangé
@ 2026-11-12 15:08 ` Yonggang Luo
2026-11-13 12:19 ` Daniel P. Berrangé
48 siblings, 1 reply; 58+ messages in thread
From: Yonggang Luo @ 2026-11-12 15:08 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: qemu-devel, Philippe Mathieu-Daudé, Pierrick Bouvier,
Markus Armbruster
On Thu, Nov 12, 2026 at 9:31 PM Daniel P. Berrangé <berrange@redhat.com> wrote:
>
> When building a multi-target binary, QOM types from multiple targets
> will be linked together. QOM types are required to have unique names
> when registered, so linking multiple targets in turn requires QOM type
> names to be unique across the QEMU codebase.
>
> Global QOM type name uniqueness is a desirable property for QEMU
> regardless of multi-target work, so that QEMU presents a non-ambiguous
> object model to applications regardless of context.
>
> In a multi-target binary, it is desirable to applications are able to
> introspect all types linked into QEMU, when launching with '-machine
> none'. Dynamic filtering of registered classes at runtime, to resolving
> QOM naming conflicts is undesirable, as it requires introspection
> to be repeated for each available target in order to discover the full
> set of available types in a binary.
>
> Introspection is a fairly heavy weight process due to QEMU's vast size,
> so enabling introspection to be done once only for all targets will be a
> very significant benefit for management applications with a multi-target
> binary.
>
> The glaring problem is that our historical design has led to multiple
> targets all providing a 'virt' machine type, which leads to multiple QOM
> types call 'virt-machine' which are all different.
>
> Having a common short name "virt" is a useful characteristic for users,
> but this does not imply we need to use that as the basis for primary QOM
> typename. It is sufficient to have an alias called 'virt'.
>
> In terms of implementation there are two core pieces
>
> * An 'Aliased' interface which can be implemented by QOM types which
> want to support type aliases.
>
> * A 'TargetSpecific' interface which can be implemented by QOM types
> which want to declare they can only be used with a subset of targets.
>
> With those foundational pieces
>
> * Machine implements Aliased and TargetSpecific
>
> * query-machines reports multiple aliases and declared supported
> targets per machine for introspection
>
> * All the 'virt' machines are renamed to $target-virt, and aliases
> added for the shorter 'virt' names to retain compatibility and
> convenience when a target is selected
>
> * All the machines which have 'is_available' set now report their
> targets via the TargetSpecific interface
>
> * Creating machines validates declared targets from TargetSpecific
>
> An apparent design mistake in TYPE_ACCEL_CPU is resolved which allows
Target independent TYPE_ACCEL_CPU is my first choice, if the QOM name is
do not have to be kept, I think this is better.
> removal of the is_available hooks from target specific CPU impls, which
> were working around the bug.
>
> The original proposed patches to unconditionally register some object
> properties is pulled in.
>
> Overall this brings us closer to having a single unified object model
> across all targets, without having to make runtime variations of what
> is exposed/reported by a given QOM class name.
Thanks, overall looks good to me.
hw/microblaze: defer PetaLogix endianness default until init:
https://lore.kernel.org/qemu-devel/20261105194958.1117-5-luoyonggang@gmail.com/
is also for avoid target_info in class_init
The last gap is how to handling cpu class name conflict
target/arm: register separate max-v8 CPU types for arm and aarch64:
https://lore.kernel.org/qemu-devel/20261031164009.2048-7-luoyonggang@gmail.com/
>
> Daniel P. Berrangé (43):
> iotests: better heuristics to find I/O tests build/source dirs
> qom: define a TargetSpecific interface
> qom: define an Aliased interface
> hw: tweak approach to setting alias in machine macros
> hw/core: implement TYPE_ALIASED interface in machines
> qapi: report multiple aliases in MachineInfo
> system: report multiple machine aliases in help output
> system: increase space for machine name in '-machine help'
> system: resolve multiple aliases when creating machines
> qapi: deprecate 'alias' field in MachineInfo
> hw/arm: convert machines to use AliasedClass interface
> hw/avr: convert machines to use AliasedClass interface
> hw/hexagon: convert machines to use AliasedClass interface
> hw/i386: convert machines to use AliasedClass interface
> hw/loongarch: convert machines to use AliasedClass interface
> hw/m68k: convert machines to use AliasedClass interface
> hw/ppc: convert machines to use AliasedClass interface
> hw/s390x: convert machines to use AliasedClass interface
> include/hw: convert machine docs to use AliasedClass interface
> hw: drop 'alias' field from MachineClass
> hw/arm: rename the 'virt' machines to 'arm-virt'
> hw/riscv: rename the 'virt' machines to 'riscv-virt'
> hw/hexagon: rename the 'virt' machine to 'hexagon-virt'
> hw/loongarch: rename the 'virt' machine to 'loongarch-virt'
> hw/m68k: rename the 'virt' machine to 'm68k-virt'
> hw/or1k: rename the 'virt' machine to 'or1k-virt'
> hw/xtensa: rename the 'virt' machine to 'xtensa-virt'
> system: stop sorting machine names based on 'family'
> system: put machine aliases in alphbetical order
> system: filter machine type list if a target is selected
> hw/core: filter machine type list if a target is selected
> system: filter machines based on target during creation
> hw/core: implement TYPE_TARGET_SPECIFIC for machine
> qapi: report target compatibility for machine types
> hw/arm: declare arm machine targets
> hw/hexagon: declare hexagon machine target
> hw/m68k: declare m68k machine target
> hw/or1k: declare or1k machine target
> hw/riscv: declare riscv machine target
> accel: make TYPE_ACCEL_CPU name target independent
> Revert "multi-target: restrict whpx-accel-*-cpu to matching target"
> Revert "target/riscv/kvm: restrict kvm-accel-riscv-cpu to riscv
> targets"
> qom: drop the 'is_available' callback from TypeInfo
>
> Pierrick Bouvier (1):
> Revert "target/riscv/tcg: restrict tcg-accel-riscv-cpu to riscv
> targets"
>
> Yonggang Luo (4):
> target-info: add target_mask_selected()
> hw/pci: unconditionally expose the 'loadparm' property
> hw/scsi: unconditionally expose the 'loadparm' property
> hw/virtio/virtio-mem: unconditionally expose 'unplugged-inaccessible'
>
> accel/accel-common.c | 3 +-
> accel/whpx/whpx-common.c | 8 --
> docs/about/deprecated.rst | 7 ++
> hw/arm/aspeed_ast27x0-fc.c | 5 +-
> hw/arm/aspeed_ast27x0_evb.c | 14 ++-
> hw/arm/raspi.c | 9 +-
> hw/arm/raspi4b.c | 6 +-
> hw/arm/virt.c | 43 +++++++--
> hw/arm/xlnx-versal-virt.c | 7 +-
> hw/avr/arduino.c | 30 +++++-
> hw/core/machine-qmp-cmds.c | 52 ++++++++++-
> hw/core/machine.c | 5 +
> hw/hexagon/hexagon_dsp.c | 7 +-
> hw/hexagon/virt.c | 11 ++-
> hw/i386/pc_piix.c | 25 ++++-
> hw/i386/pc_q35.c | 20 +++-
> hw/loongarch/virt.c | 39 ++++++--
> hw/m68k/virt.c | 46 +++++++---
> hw/or1k/virt.c | 14 ++-
> hw/pci/pci.c | 18 ++--
> hw/ppc/pnv.c | 7 +-
> hw/ppc/spapr.c | 31 ++++---
> hw/riscv/virt.c | 14 ++-
> hw/s390x/s390-virtio-ccw.c | 24 +++--
> hw/scsi/scsi-disk.c | 18 ++--
> hw/virtio/virtio-mem.c | 12 +--
> hw/xtensa/virt.c | 9 +-
> include/accel/accel-cpu-target.h | 3 +-
> include/accel/accel-cpu.h | 2 +
> include/hw/arm/virt.h | 2 +-
> include/hw/core/boards.h | 29 ++++--
> include/hw/hexagon/virt.h | 2 +-
> include/hw/i386/pc.h | 5 +-
> include/hw/loongarch/virt.h | 2 +-
> include/hw/riscv/virt.h | 2 +-
> include/qemu/target-info-init.h | 15 ++-
> include/qemu/target-info.h | 9 ++
> include/qom/object.h | 3 -
> include/qom/object_interfaces.h | 152 +++++++++++++++++++++++++++++++
> meson.build | 1 +
> qapi/machine.json | 19 +++-
> qom/object.c | 4 -
> qom/object_interfaces.c | 88 ++++++++++++++++++
> rust/qom/src/qom.rs | 1 -
> stubs/meson.build | 1 +
> stubs/target-mask-selected.c | 13 +++
> system/vl.c | 115 ++++++++++++-----------
> target-info-def.c | 3 +
> target-info-qom.c | 10 ++
> target/riscv/kvm/kvm-cpu.c | 2 -
> target/riscv/tcg/tcg-cpu.c | 1 -
> tests/qemu-iotests/check | 52 ++++++++---
> 52 files changed, 804 insertions(+), 216 deletions(-)
> create mode 100644 stubs/target-mask-selected.c
>
> --
> 2.56.1
>
--
此致
礼
罗勇刚
Yours
sincerely,
Yonggang Luo
^ permalink raw reply [flat|nested] 58+ messages in thread* Re: [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds
2026-11-12 15:08 ` [PATCH 00/48] hw: resolve QOM type conflicts in multi-target builds Yonggang Luo
@ 2026-11-13 12:19 ` Daniel P. Berrangé
0 siblings, 0 replies; 58+ messages in thread
From: Daniel P. Berrangé @ 2026-11-13 12:19 UTC (permalink / raw)
To: Yonggang Luo
Cc: qemu-devel, Philippe Mathieu-Daudé, Pierrick Bouvier,
Markus Armbruster
On Thu, Nov 12, 2026 at 11:08:02PM +0800, Yonggang Luo wrote:
> On Thu, Nov 12, 2026 at 9:31 PM Daniel P. Berrangé <berrange@redhat.com> wrote:
> >
> > When building a multi-target binary, QOM types from multiple targets
> > will be linked together. QOM types are required to have unique names
> > when registered, so linking multiple targets in turn requires QOM type
> > names to be unique across the QEMU codebase.
> >
> > Global QOM type name uniqueness is a desirable property for QEMU
> > regardless of multi-target work, so that QEMU presents a non-ambiguous
> > object model to applications regardless of context.
> >
> > In a multi-target binary, it is desirable to applications are able to
> > introspect all types linked into QEMU, when launching with '-machine
> > none'. Dynamic filtering of registered classes at runtime, to resolving
> > QOM naming conflicts is undesirable, as it requires introspection
> > to be repeated for each available target in order to discover the full
> > set of available types in a binary.
> >
> > Introspection is a fairly heavy weight process due to QEMU's vast size,
> > so enabling introspection to be done once only for all targets will be a
> > very significant benefit for management applications with a multi-target
> > binary.
> >
> > The glaring problem is that our historical design has led to multiple
> > targets all providing a 'virt' machine type, which leads to multiple QOM
> > types call 'virt-machine' which are all different.
> >
> > Having a common short name "virt" is a useful characteristic for users,
> > but this does not imply we need to use that as the basis for primary QOM
> > typename. It is sufficient to have an alias called 'virt'.
> >
> > In terms of implementation there are two core pieces
> >
> > * An 'Aliased' interface which can be implemented by QOM types which
> > want to support type aliases.
> >
> > * A 'TargetSpecific' interface which can be implemented by QOM types
> > which want to declare they can only be used with a subset of targets.
> >
> > With those foundational pieces
> >
> > * Machine implements Aliased and TargetSpecific
> >
> > * query-machines reports multiple aliases and declared supported
> > targets per machine for introspection
> >
> > * All the 'virt' machines are renamed to $target-virt, and aliases
> > added for the shorter 'virt' names to retain compatibility and
> > convenience when a target is selected
> >
> > * All the machines which have 'is_available' set now report their
> > targets via the TargetSpecific interface
> >
> > * Creating machines validates declared targets from TargetSpecific
> >
> > An apparent design mistake in TYPE_ACCEL_CPU is resolved which allows
>
> Target independent TYPE_ACCEL_CPU is my first choice, if the QOM name is
> do not have to be kept, I think this is better.
>
> > removal of the is_available hooks from target specific CPU impls, which
> > were working around the bug.
> >
> > The original proposed patches to unconditionally register some object
> > properties is pulled in.
> >
> > Overall this brings us closer to having a single unified object model
> > across all targets, without having to make runtime variations of what
> > is exposed/reported by a given QOM class name.
>
>
> Thanks, overall looks good to me.
>
> hw/microblaze: defer PetaLogix endianness default until init:
> https://lore.kernel.org/qemu-devel/20261105194958.1117-5-luoyonggang@gmail.com/
>
> is also for avoid target_info in class_init
I added a R-B to that.
> The last gap is how to handling cpu class name conflict
> target/arm: register separate max-v8 CPU types for arm and aarch64:
> https://lore.kernel.org/qemu-devel/20261031164009.2048-7-luoyonggang@gmail.com/
I had a look at your earlier proposal here:
https://lore.kernel.org/qemu-devel/20261013195606.152-1-luoyonggang@gmail.com/
and to me that looks like it should do what we need.
* In existing qemu-system-arm and qemu-system-aarch64 it will
"just work"
* In qemu-system-aarch64, users can still opt-in to 32-bit
mode only by using "-cpu max-v8:aarch64=off"
So based on Peter's comment it does not look like we need to
have the ability to register two distnict "max-v8" CPU classes,
a single class can do the right thing at runtime in its
instance constructor.
I see Pierrick commented that it would not work in multi-target:
https://lore.kernel.org/qemu-devel/f3649d73-1edf-440a-9534-7b00da4d075d@oss.qualcomm.com/
I'm not understanding why that is ? The choice of 32-bit vs 64-bit
is made at Object initialization time, so if the
if (target_aarch64()) {
...
condition is not sufficient, it seems like we could add more logic
to that condition easily and to make it do the right thing at runtime.
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] 58+ messages in thread