On 10/7/2026 7:08 PM, Yonggang Luo wrote:
>> So, based on all the previous conversations, we agreed to have a
>> qemu-system binary with all the QOM types available (for all targets).
>>
>> I personally think that if we go this way, we should not have any
>> -target option, and even less a -target none option.
>>
>> The current is_available() approach was made with filtering per target
>> in mind, which predates where things are now. So, it's a good time to
>> reevaluate how to do it.
>>
>> This leaves us with (at least) two options:
>> - keep the callback and add TargetInfo parameter (what is done here)
>> - remove is_available, and adopt a more declarative approach
>>
>> How about we (re)-explore the second one?
>
> Indeed, I am doing
>
> - preserve is_available(TargetInfo*), and adopt a more declarative approach
>
> /* Generated by scripts/gen-target-info.py. Do not edit. */
>
...
> {
> .name = TYPE_TARGET_BASE_ARM_MACHINE,
> .parent = TYPE_MACHINE,
> .abstract = true,
> .is_available = target_is_base_arm,
> },
> {
> .name = TYPE_TARGET_AARCH64_MACHINE,
> .parent = TYPE_TARGET_BASE_ARM_MACHINE,
> .abstract = true,
> .is_available = target_is_aarch64,
> },
> {
> .name = TYPE_TARGET_ARM_MACHINE,
> .parent = TYPE_TARGET_BASE_ARM_MACHINE,
> .abstract = true,
> .is_available = target_is_arm,
> },
...
> Other than these base machines, other machines are children of these
> base machines.
>
> See these changes
> https://gitlab.com/lygstate-qemu/qemu/-/commit/c71da20c2483cdf577fd2a5548a80ca1e5099676
> https://gitlab.com/lygstate-qemu/qemu/-/commit/252b8763fd74ec57f5762bf9c57e19d8d9e5a146
> https://gitlab.com/lygstate-qemu/qemu/-/commit/252b8763fd74ec57f5762bf9c57e19d8d9e5a146
> https://gitlab.com/lygstate-qemu/qemu/-/commit/252b8763fd74ec57f5762bf9c57e19d8d9e5a146
> For ARM:
> https://gitlab.com/lygstate-qemu/qemu/-/commit/c42d5eb333fd3a7cab899c8df95375dfc79aba40
>
> These base machine type is auto-generated in this MR.
> You can see at the branch
> https://gitlab.com/lygstate-qemu/qemu/-/commits/single-binary-arm-riscv?ref_type=heads
>
> And the inherit is done by commits
> qom: inherit is_available and filter after MODULE_INIT_QOM:
> https://gitlab.com/lygstate-qemu/qemu/-/commit/cb66474a36e03b4353c2f525ce7821f2af779ea1
> qom: register late types through module_call_init_fn:
> https://gitlab.com/lygstate-qemu/qemu/-/commit/ba6a3d3fb6e4bfe35d88d3845abf7b0ec8fbc337
> module: add before/after hooks and module_call_init_fn:
> https://gitlab.com/lygstate-qemu/qemu/-/commit/86c635f45e283b6d0f714a1a3a9d9521b17d5152
>
> And the gitlab-ci is already passed
>
>
The hierarchy based approach (we considered that also at the time) has a
big caveat: a QOM type can only have one parent. There is no multi
inheritance in our model.
You can easily merge arm and aarch64 under a base_arm parent. However,
you can't express:
- this machine is available for target X and Y (x-remote, nitro, null)
That's why we chose interfaces based tagging 1.5 years ago, because they
allow multi inheritance in some ways.
>>
>> It's what we did in the past
>> (https://gitlab.com/qemu-project/qemu/-/commit/5de9216064d32eaac125dac4de1878486c16d73e),
>
> Somewhat alike except I do not introduce many interface types. Just
> base machine types.
>
>> and that I removed recently, in favor of is_available.
>> My rationale was that it was incomplete, since we needed to filter types
>> per config also, and not only target.
>> Now that direction is to not filter anything, filter per config is
>> unneeded, and switching back to declarative instead of callback makes
>> total sense. Using interfaces like we did has its own issues, and I
>> would not like to see this coming back.
>>
>> I'll do one very concrete proposal:
>>
>> ```
>> How about letting machines (and machines only first), have a new field
>> 'targets', being a uint32_t mask with an array of EMU_TARGET?
>> machine->targets = EMU_TARGET_X | EMU_TARGET_Y;
>>
For now, it's the best I can think of. I tried having an array of
EMU_TARGET but declaring it was a verbose mess.
The arch mask, that you or Daniel sugggested at some point IIRC, is the
best compromise here: it's compact and readable.
>
> From my experience at
> https://gitlab.com/lygstate-qemu/qemu/-/tree/combined-binary-multi-targets?ref_type=heads
> this is not enough, we still needs is_avaible, because for those
> machines that binding to
> KVM/WHPX and other accels, we need to use target_kconfig to handle
> them. That's why I choose to use a unified
> is_avaible(TargetInfo*).
>
Given our base assumption to expose all types, why should we care about
kvm/whpx? If we don't have a proper message when user select a wrong
machine/cpu type, we can simply add one.
> This new field only works if is_availbe still be a member of TypeInfo.
> machine->targets are not generic. Indeed CPU and ACCEL(kvm/whpx/hyp)
> types also need filtering.
>
Yes, so CPU can have the same target field. Since we won't filter
devices, I don't see a need to have this in object.c. Also, it can
completely replace the existing is_available mechanic.
Also, in multi-target.c test, we can add a new test to ensure all
machines and all cpus that belongs to this binary have targets set.
This allows to leave the rest of architectures as they are for now, and
force to add this when we'll integrate them.
Regards,
Pierrick