On Thu, Oct 8, 2026 at 4:44 AM Pierrick Bouvier <[email protected]> wrote: > > On 10/7/2026 4:48 AM, Yonggang Luo wrote: > > Change TypeInfo.is_available to the new TypeIsAvailable type, which > > takes a const TargetInfo *. Registration passes target_info(), so > > behavior is unchanged. object.h only forward-declares TargetInfo. > > > > Switch the existing users (raspi, raspi4b, ast27x0 evb and fc) and the > > generated machine parents to the matching target_is_<arch> helpers. > > > > Signed-off-by: Yonggang Luo <[email protected]> > > --- > > hw/arm/aspeed_ast27x0-fc.c | 2 +- > > hw/arm/aspeed_ast27x0_evb.c | 4 ++-- > > hw/arm/raspi.c | 4 ++-- > > hw/arm/raspi4b.c | 2 +- > > hw/arm/virt.c | 4 ++-- > > hw/m68k/virt.c | 4 ++-- > > hw/or1k/virt.c | 2 +- > > include/qom/object.h | 12 +++++++++++- > > qom/object.c | 3 ++- > > 9 files changed, 24 insertions(+), 13 deletions(-) > > > > diff --git a/hw/arm/aspeed_ast27x0-fc.c b/hw/arm/aspeed_ast27x0-fc.c > > index 73362b60d2a..8a7c6a116ac 100644 > > --- a/hw/arm/aspeed_ast27x0-fc.c > > +++ b/hw/arm/aspeed_ast27x0-fc.c > > @@ -234,7 +234,7 @@ static const TypeInfo ast2700fc_types[] = { > > .parent = TYPE_MACHINE, > > .class_init = ast2700fc_class_init, > > .instance_size = sizeof(Ast2700FCState), > > - .is_available = target_aarch64, > > + .is_available = target_is_aarch64, > > }, > > }; > > > > diff --git a/hw/arm/aspeed_ast27x0_evb.c b/hw/arm/aspeed_ast27x0_evb.c > > index 460c9ff0d2e..02a8cff1d9d 100644 > > --- a/hw/arm/aspeed_ast27x0_evb.c > > +++ b/hw/arm/aspeed_ast27x0_evb.c > > @@ -75,13 +75,13 @@ 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, > > + .is_available = target_is_aarch64, > > }, > > { > > .name = MACHINE_TYPE_NAME("ast2700a2-evb"), > > .parent = TYPE_ASPEED_MACHINE, > > .class_init = aspeed_machine_ast2700a2_evb_class_init, > > - .is_available = target_aarch64, > > + .is_available = target_is_aarch64, > > } > > }; > > > > diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c > > index fadbacb2534..22b06c6ca22 100644 > > --- a/hw/arm/raspi.c > > +++ b/hw/arm/raspi.c > > @@ -403,12 +403,12 @@ 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, > > + .is_available = target_is_aarch64, > > }, { > > .name = MACHINE_TYPE_NAME("raspi3b"), > > .parent = TYPE_RASPI_MACHINE, > > .class_init = raspi3b_machine_class_init, > > - .is_available = target_aarch64, > > + .is_available = target_is_aarch64, > > }, { > > .name = TYPE_RASPI_MACHINE, > > .parent = TYPE_RASPI_BASE_MACHINE, > > diff --git a/hw/arm/raspi4b.c b/hw/arm/raspi4b.c > > index 566d64572db..a1dc477f25e 100644 > > --- a/hw/arm/raspi4b.c > > +++ b/hw/arm/raspi4b.c > > @@ -121,7 +121,7 @@ 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, > > + .is_available = target_is_aarch64, > > }; > > > > static void raspi4b_machine_register_type(void) > > diff --git a/hw/arm/virt.c b/hw/arm/virt.c > > index 9d192515d85..18160f7fad3 100644 > > --- a/hw/arm/virt.c > > +++ b/hw/arm/virt.c > > @@ -132,7 +132,7 @@ static void arm_virt_compat_default_set(MachineClass > > *mc) > > .name = MACHINE_VER_TYPE_NAME("virt", __VA_ARGS__), \ > > .parent = TYPE_VIRT_MACHINE, \ > > .class_init = MACHINE_VER_SYM(class_init, virt, __VA_ARGS__), \ > > - .is_available = target_base_arm, \ > > + .is_available = target_is_base_arm, \ > > }; \ > > static void MACHINE_VER_SYM(register, virt, __VA_ARGS__)(void) \ > > { \ > > @@ -4430,7 +4430,7 @@ static const TypeInfo virt_machine_info = { > > { TYPE_HOTPLUG_HANDLER }, > > { } > > }, > > - .is_available = target_base_arm, > > + .is_available = target_is_base_arm, > > }; > > > > static void machvirt_machine_init(void) > > diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c > > index e52546e4fab..ad2a43ef3fb 100644 > > --- a/hw/m68k/virt.c > > +++ b/hw/m68k/virt.c > > @@ -327,7 +327,7 @@ static const TypeInfo virt_machine_info = { > > .parent = TYPE_MACHINE, > > .abstract = true, > > .class_init = virt_machine_class_init, > > - .is_available = target_m68k, > > + .is_available = target_is_m68k, > > }; > > > > static void virt_machine_register_types(void) > > @@ -355,7 +355,7 @@ type_init(virt_machine_register_types) > > .name = MACHINE_VER_TYPE_NAME("virt", __VA_ARGS__), \ > > .parent = MACHINE_TYPE_NAME("virt"), \ > > .class_init = MACHINE_VER_SYM(class_init, virt, __VA_ARGS__), \ > > - .is_available = target_m68k, \ > > + .is_available = target_is_m68k, \ > > }; \ > > static void MACHINE_VER_SYM(register, virt, __VA_ARGS__)(void) \ > > { \ > > diff --git a/hw/or1k/virt.c b/hw/or1k/virt.c > > index a3ff903839b..89fb786641f 100644 > > --- a/hw/or1k/virt.c > > +++ b/hw/or1k/virt.c > > @@ -559,7 +559,7 @@ static const TypeInfo or1ksim_machine_typeinfo = { > > .parent = TYPE_MACHINE, > > .class_init = openrisc_virt_machine_init, > > .instance_size = sizeof(OR1KVirtState), > > - .is_available = target_or1k, > > + .is_available = target_is_or1k, > > }; > > > > static void or1ksim_machine_init_register_types(void) > > diff --git a/include/qom/object.h b/include/qom/object.h > > index 4c0645817a5..7d52a15f6b8 100644 > > --- a/include/qom/object.h > > +++ b/include/qom/object.h > > @@ -17,6 +17,7 @@ > > #include "qapi/qapi-builtin-types.h" > > #include "qemu/module.h" > > > > +typedef struct TargetInfo TargetInfo; > > struct TypeImpl; > > typedef struct TypeImpl *Type; > > > > @@ -117,6 +118,15 @@ typedef void (ObjectUnparent)(Object *obj); > > */ > > typedef void (ObjectFree)(void *obj); > > > > +/** > > + * typedef TypeIsAvailable: > > + * @ti: TargetInfo to test. > > + * > > + * Returns whether a type is available for @ti. Typical implementations > > + * are target_is_*(). > > + */ > > +typedef bool (TypeIsAvailable)(const TargetInfo *ti); > > + > > #define OBJECT_CLASS_CAST_CACHE 4 > > > > /** > > @@ -498,7 +508,7 @@ struct TypeInfo > > void (*class_base_init)(ObjectClass *klass, const void *data); > > const void *class_data; > > > > - bool (*is_available)(void); > > + TypeIsAvailable *is_available; > > const InterfaceInfo *interfaces; > > }; > > > > diff --git a/qom/object.c b/qom/object.c > > index 96498f3d001..253b9562b41 100644 > > --- a/qom/object.c > > +++ b/qom/object.c > > @@ -15,6 +15,7 @@ > > #include "qom/compat-properties.h" > > #include "qom/object.h" > > #include "qom/object_interfaces.h" > > +#include "qemu/target-info.h" > > #include "qemu/cutils.h" > > #include "qemu/memalign.h" > > #include "qapi/visitor.h" > > @@ -167,7 +168,7 @@ static TypeImpl *type_register_internal(const TypeInfo > > *info) > > abort(); > > } > > > > - if (info->is_available && !info->is_available()) { > > + if (info->is_available && !info->is_available(target_info())) { > > return NULL; > > } > > > > ``` > info->is_available(target_info()) > ``` > > or > > ``` > is_available() { > TargetInfo ti * = target_info(); > ... > } > ``` > > Are doing the exact same thing today. > > So what is the future goal requiring to introduce this?
>From Daniel P. Berrangé's requesthttps://lore.kernel.org/qemu-devel/[email protected]/ I forgot to mention that this is also pretty important for making introspection work, as we need to be able to say 'qemu-system --machine none -qmp ...' and connect to QMP to introspect the binary. Having to add a '--target <name>' into that mix is undesirable, as it creates a chicken & egg problem. You don't know what targets are built into qemu-system without introspecting it and you can't introspect it without selecting a target to introspect. >From Pierrick's review https://lore.kernel.org/qemu-devel/[email protected]/So, for existing binary: -M virt works as before. For new multi binary: $ qemu-system -M virt: Multiple machines were found, select one among: - aarch64-virt - riscv64-virt Does it matches what you would expect? >From Daniel's review https://lore.kernel.org/qemu-devel/[email protected]/ We already have 'QemuTargetInfo' struct which is used with 'query-target', that should also be used with the new 'query-targets' command. We need to add the 'endianness' field to QemuTargetInfo. I don't think that we need to report machines though. We already have 'query-machines' which gives much broader information on the machines. "MachineInfo" needs to gain "targets": ["SysEmuTarget"] to list which target(s) a machine can be used with. To achieve these, we needs add TypeInfo parameter to it so that we can do static void report_unsupported_machine_type(const char *name, Error **errp) { g_autoptr(GSList) machines = machine_class_get_list(true); g_autoptr(GString) targets = g_string_new(NULL); TargetInfoNode *node; GSList *el; error_setg(errp, "unsupported machine type: \"%s\" for target \"%s\"", name, target_name()); QLIST_FOREACH(node, target_info_list(), next) { for (el = machines; el; el = el->next) { MachineClass *mc = el->data; if ((!strcmp(mc->name, name) || !g_strcmp0(mc->alias, name)) && object_class_get_is_available(OBJECT_CLASS(mc))(node->info)) { g_string_append_printf(targets, " %s\n", node->info->target_name); break; } } } if (targets->len) { error_append_hint(errp, "Available for targets:\n%s", targets->str); } } That is we can iterate on all target-list, and check if it's can be fitlered. > > It's something we asked multiple times, and until we don't have a short > series doing this change + a single and minimal modification showing the > reason, I will still be asking. > > If the goal is to implement some sort of classification for > machines/cpus, I would suggest to just send a simple series doing this > change (and only this - no additional cleanups/refactoring), and an > example for a single machine + cpu, so we can talk about it. > > Regards, > Pierrick -- 此致 礼 罗勇刚 Yours sincerely, Yonggang Luo
