Binaries can register a QOM type to filter their machines
by filling their TargetInfo::machine_typename field.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
include/qemu/target_info-impl.h | 3 +++
include/qemu/target_info.h | 8 ++++++++
system/vl.c | 14 ++++++++++++++
target_info.c | 5 +++++
4 files changed, 30 insertions(+)
diff --git a/include/qemu/target_info-impl.h b/include/qemu/target_info-impl.h
index d5c94ed5296..990fb067d20 100644
--- a/include/qemu/target_info-impl.h
+++ b/include/qemu/target_info-impl.h
@@ -16,6 +16,9 @@ typedef struct TargetInfo {
/* runtime equivalent of TARGET_NAME definition */
const char *const name;
+ /* QOM typename machines for this binary must implement */
+ const char *const machine_typename;
+
} TargetInfo;
const TargetInfo *target_info(void);
diff --git a/include/qemu/target_info.h b/include/qemu/target_info.h
index 3f6cbbbd300..e9fd2fdd7b0 100644
--- a/include/qemu/target_info.h
+++ b/include/qemu/target_info.h
@@ -16,4 +16,12 @@
*/
const char *target_name(void);
+/**
+ * target_machine_interface_typename:
+ *
+ * Returns: Name of the QOM interface implemented by machines
+ * usable on this target binary.
+ */
+const char *target_machine_interface_typename(void);
+
#endif
diff --git a/system/vl.c b/system/vl.c
index d8a0fe713c9..4e43e55afe7 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -27,6 +27,7 @@
#include "qemu/datadir.h"
#include "qemu/units.h"
#include "qemu/module.h"
+#include "qemu/target_info.h"
#include "exec/cpu-common.h"
#include "exec/page-vary.h"
#include "hw/qdev-properties.h"
@@ -836,11 +837,17 @@ static bool usb_parse(const char *cmdline, Error **errp)
static MachineClass *find_machine(const char *name, GSList *machines)
{
GSList *el;
+ const char *qom_typename_filter = target_machine_interface_typename();
for (el = machines; el; el = el->next) {
MachineClass *mc = el->data;
if (!strcmp(mc->name, name) || !g_strcmp0(mc->alias, name)) {
+ if (qom_typename_filter
+ && !object_class_dynamic_cast(el->data, qom_typename_filter)) {
+ /* Machine is not for this binary: fail */
+ return NULL;
+ }
return mc;
}
}
@@ -1563,6 +1570,7 @@ static void machine_help_func(const QDict *qdict)
g_autoptr(GSList) machines = NULL;
GSList *el;
const char *type = qdict_get_try_str(qdict, "type");
+ const char *qom_typename_filter = target_machine_interface_typename();
machines = object_class_get_list(TYPE_MACHINE, false);
if (type) {
@@ -1577,6 +1585,12 @@ static void machine_help_func(const QDict *qdict)
machines = g_slist_sort(machines, machine_class_cmp);
for (el = machines; el; el = el->next) {
MachineClass *mc = el->data;
+
+ if (qom_typename_filter
+ && !object_class_dynamic_cast(el->data, qom_typename_filter)) {
+ /* Machine is not for this binary: skip */
+ continue;
+ }
if (mc->alias) {
printf("%-20s %s (alias of %s)\n", mc->alias, mc->desc, mc->name);
}
diff --git a/target_info.c b/target_info.c
index 877a6a15014..226eed1fd7d 100644
--- a/target_info.c
+++ b/target_info.c
@@ -14,3 +14,8 @@ const char *target_name(void)
{
return target_info()->name;
}
+
+const char *target_machine_interface_typename(void)
+{
+ return target_info()->machine_typename;
+}
--
2.47.1
On 4/17/25 17:50, Philippe Mathieu-Daudé wrote:
> Binaries can register a QOM type to filter their machines
> by filling their TargetInfo::machine_typename field.
>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> ---
> include/qemu/target_info-impl.h | 3 +++
> include/qemu/target_info.h | 8 ++++++++
> system/vl.c | 14 ++++++++++++++
> target_info.c | 5 +++++
> 4 files changed, 30 insertions(+)
>
> diff --git a/include/qemu/target_info-impl.h b/include/qemu/target_info-impl.h
> index d5c94ed5296..990fb067d20 100644
> --- a/include/qemu/target_info-impl.h
> +++ b/include/qemu/target_info-impl.h
> @@ -16,6 +16,9 @@ typedef struct TargetInfo {
> /* runtime equivalent of TARGET_NAME definition */
> const char *const name;
>
> + /* QOM typename machines for this binary must implement */
> + const char *const machine_typename;
> +
> } TargetInfo;
>
> const TargetInfo *target_info(void);
> diff --git a/include/qemu/target_info.h b/include/qemu/target_info.h
> index 3f6cbbbd300..e9fd2fdd7b0 100644
> --- a/include/qemu/target_info.h
> +++ b/include/qemu/target_info.h
> @@ -16,4 +16,12 @@
> */
> const char *target_name(void);
>
> +/**
> + * target_machine_interface_typename:
> + *
> + * Returns: Name of the QOM interface implemented by machines
> + * usable on this target binary.
> + */
> +const char *target_machine_interface_typename(void);
> +
> #endif
> diff --git a/system/vl.c b/system/vl.c
> index d8a0fe713c9..4e43e55afe7 100644
> --- a/system/vl.c
> +++ b/system/vl.c
> @@ -27,6 +27,7 @@
> #include "qemu/datadir.h"
> #include "qemu/units.h"
> #include "qemu/module.h"
> +#include "qemu/target_info.h"
> #include "exec/cpu-common.h"
> #include "exec/page-vary.h"
> #include "hw/qdev-properties.h"
> @@ -836,11 +837,17 @@ static bool usb_parse(const char *cmdline, Error **errp)
> static MachineClass *find_machine(const char *name, GSList *machines)
> {
> GSList *el;
> + const char *qom_typename_filter = target_machine_interface_typename();
>
> for (el = machines; el; el = el->next) {
> MachineClass *mc = el->data;
>
> if (!strcmp(mc->name, name) || !g_strcmp0(mc->alias, name)) {
> + if (qom_typename_filter
> + && !object_class_dynamic_cast(el->data, qom_typename_filter)) {
> + /* Machine is not for this binary: fail */
> + return NULL;
> + }
> return mc;
> }
> }
> @@ -1563,6 +1570,7 @@ static void machine_help_func(const QDict *qdict)
> g_autoptr(GSList) machines = NULL;
> GSList *el;
> const char *type = qdict_get_try_str(qdict, "type");
> + const char *qom_typename_filter = target_machine_interface_typename();
>
> machines = object_class_get_list(TYPE_MACHINE, false);
We can replace change to system/vl.c with:
const char *machine_type = target_machine_interface_typename();
machines = object_class_get_list(machine_type, false);
> if (type) {
> @@ -1577,6 +1585,12 @@ static void machine_help_func(const QDict *qdict)
> machines = g_slist_sort(machines, machine_class_cmp);
> for (el = machines; el; el = el->next) {
> MachineClass *mc = el->data;
> +
> + if (qom_typename_filter
> + && !object_class_dynamic_cast(el->data, qom_typename_filter)) {
> + /* Machine is not for this binary: skip */
> + continue;
> + }
> if (mc->alias) {
> printf("%-20s %s (alias of %s)\n", mc->alias, mc->desc, mc->name);
> }
> diff --git a/target_info.c b/target_info.c
> index 877a6a15014..226eed1fd7d 100644
> --- a/target_info.c
> +++ b/target_info.c
> @@ -14,3 +14,8 @@ const char *target_name(void)
> {
> return target_info()->name;
> }
> +
> +const char *target_machine_interface_typename(void)
> +{
> + return target_info()->machine_typename;
And here:
const char *machine_type = target_info()->machine_typename;
if (!machine_type) {
machine_type = TYPE_MACHINE;
}
return machine_type;
> +}
This way, there is no special case to handle anywhere, and we can safely
replace occurrences of TYPE_MACHINE queries with
target_machine_interface_typename().
As well, just a nit, but it's not important to know it's an interface, I
would prefer a simpler name: target_machine_type();
On 18/4/25 05:06, Pierrick Bouvier wrote:
> On 4/17/25 17:50, Philippe Mathieu-Daudé wrote:
>> Binaries can register a QOM type to filter their machines
>> by filling their TargetInfo::machine_typename field.
>>
>> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
>> ---
>> include/qemu/target_info-impl.h | 3 +++
>> include/qemu/target_info.h | 8 ++++++++
>> system/vl.c | 14 ++++++++++++++
>> target_info.c | 5 +++++
>> 4 files changed, 30 insertions(+)
>>
>> diff --git a/include/qemu/target_info-impl.h b/include/qemu/
>> target_info-impl.h
>> index d5c94ed5296..990fb067d20 100644
>> --- a/include/qemu/target_info-impl.h
>> +++ b/include/qemu/target_info-impl.h
>> @@ -16,6 +16,9 @@ typedef struct TargetInfo {
>> /* runtime equivalent of TARGET_NAME definition */
>> const char *const name;
>> + /* QOM typename machines for this binary must implement */
>> + const char *const machine_typename;
>> +
>> } TargetInfo;
>> const TargetInfo *target_info(void);
>> diff --git a/include/qemu/target_info.h b/include/qemu/target_info.h
>> index 3f6cbbbd300..e9fd2fdd7b0 100644
>> --- a/include/qemu/target_info.h
>> +++ b/include/qemu/target_info.h
>> @@ -16,4 +16,12 @@
>> */
>> const char *target_name(void);
>> +/**
>> + * target_machine_interface_typename:
>> + *
>> + * Returns: Name of the QOM interface implemented by machines
>> + * usable on this target binary.
>> + */
>> +const char *target_machine_interface_typename(void);
>> +
>> #endif
>> diff --git a/system/vl.c b/system/vl.c
>> index d8a0fe713c9..4e43e55afe7 100644
>> --- a/system/vl.c
>> +++ b/system/vl.c
>> @@ -27,6 +27,7 @@
>> #include "qemu/datadir.h"
>> #include "qemu/units.h"
>> #include "qemu/module.h"
>> +#include "qemu/target_info.h"
>> #include "exec/cpu-common.h"
>> #include "exec/page-vary.h"
>> #include "hw/qdev-properties.h"
>> @@ -836,11 +837,17 @@ static bool usb_parse(const char *cmdline, Error
>> **errp)
>> static MachineClass *find_machine(const char *name, GSList *machines)
>> {
>> GSList *el;
>> + const char *qom_typename_filter =
>> target_machine_interface_typename();
>> for (el = machines; el; el = el->next) {
>> MachineClass *mc = el->data;
>> if (!strcmp(mc->name, name) || !g_strcmp0(mc->alias, name)) {
>> + if (qom_typename_filter
>> + && !object_class_dynamic_cast(el->data,
>> qom_typename_filter)) {
>> + /* Machine is not for this binary: fail */
>> + return NULL;
>> + }
>> return mc;
>> }
>> }
>> @@ -1563,6 +1570,7 @@ static void machine_help_func(const QDict *qdict)
>> g_autoptr(GSList) machines = NULL;
>> GSList *el;
>> const char *type = qdict_get_try_str(qdict, "type");
>> + const char *qom_typename_filter =
>> target_machine_interface_typename();
>> machines = object_class_get_list(TYPE_MACHINE, false);
>
> We can replace change to system/vl.c with:
>
> const char *machine_type = target_machine_interface_typename();
> machines = object_class_get_list(machine_type, false);
Clever!
>
>> if (type) {
>> @@ -1577,6 +1585,12 @@ static void machine_help_func(const QDict *qdict)
>> machines = g_slist_sort(machines, machine_class_cmp);
>> for (el = machines; el; el = el->next) {
>> MachineClass *mc = el->data;
>> +
>> + if (qom_typename_filter
>> + && !object_class_dynamic_cast(el->data,
>> qom_typename_filter)) {
>> + /* Machine is not for this binary: skip */
>> + continue;
>> + }
>> if (mc->alias) {
>> printf("%-20s %s (alias of %s)\n", mc->alias, mc->desc,
>> mc->name);
>> }
>> diff --git a/target_info.c b/target_info.c
>> index 877a6a15014..226eed1fd7d 100644
>> --- a/target_info.c
>> +++ b/target_info.c
>> @@ -14,3 +14,8 @@ const char *target_name(void)
>> {
>> return target_info()->name;
>> }
>> +
>> +const char *target_machine_interface_typename(void)
>> +{
>> + return target_info()->machine_typename;
>
> And here:
>
> const char *machine_type = target_info()->machine_typename;
> if (!machine_type) {
> machine_type = TYPE_MACHINE;
> }
> return machine_type;
>
>> +}
>
> This way, there is no special case to handle anywhere, and we can safely
> replace occurrences of TYPE_MACHINE queries with
> target_machine_interface_typename().
>
> As well, just a nit, but it's not important to know it's an interface, I
> would prefer a simpler name: target_machine_type();
© 2016 - 2026 Red Hat, Inc.