On 10/12/2026 9:03 PM, Yonggang Luo wrote:
> On Tue, Oct 13, 2026 at 11:53 AM Pierrick Bouvier
> <[email protected]> wrote:
>>
>> On 10/12/26 7:43 PM, Yonggang Luo wrote:
>>> On Tue, Oct 13, 2026 at 9:26 AM Pierrick Bouvier
>>> <[email protected]> wrote:
>>>>
>>>> On 10/11/26 9:26 PM, Yonggang Luo wrote:
>>>>> On Mon, Oct 12, 2026 at 10:25 AM Pierrick Bouvier
>>>>> <[email protected]> wrote:
>>>>>>
>>>>>> On 10/11/26 7:13 PM, Pierrick Bouvier wrote:
>>>>>>> On 10/11/26 1:22 PM, Yonggang Luo wrote:
>>>>>>>> On Fri, Oct 9, 2026 at 2:34 AM Pierrick Bouvier
>>>>>>>> <[email protected]> wrote:
>>>>>>>>>
>>>>>>>>> On 10/8/2026 10:13 AM, Yonggang Luo wrote:
>>>>>>>>>> On Fri, Oct 9, 2026 at 12:06 AM Pierrick Bouvier
>>>>>>>>>> <[email protected]> wrote:
>>>>>>>>>>>
>>>>>>>>>>> On 10/8/2026 2:46 AM, Yonggang Luo wrote:
>>>>>>>>>>>> On Thu, Oct 8, 2026 at 5:42 PM Daniel P. Berrangé 
>>>>>>>>>>>> <[email protected]> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Wed, Oct 07, 2026 at 01:25:46PM -0700, Pierrick Bouvier wrote:
>>>>>>>>>>>>>> On 10/7/2026 4:47 AM, Yonggang Luo wrote:
>>>>>>>>>>>>>>> This allows a combined binary to register machine types from 
>>>>>>>>>>>>>>> all its targets.
>>>>>>>>>>>>>>> Consequently, QMP `query-machines` can return machine entries 
>>>>>>>>>>>>>>> from every
>>>>>>>>>>>>>>> target, even when `none` is selected. For example, a client can 
>>>>>>>>>>>>>>> query the
>>>>>>>>>>>>>>> combined machine list with:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> ```json
>>>>>>>>>>>>>>> { "execute": "query-machines" }
>>>>>>>>>>>>>>> ```
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> The returned list includes the registered machine classes from 
>>>>>>>>>>>>>>> all linked
>>>>>>>>>>>>>>> targets. This is separate from selecting a machine: with 
>>>>>>>>>>>>>>> `-target none`,
>>>>>>>>>>>>>>> `-M virt` reports the targets that provide `virt` instead of 
>>>>>>>>>>>>>>> choosing one
>>>>>>>>>>>>>>> arbitrarily:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> ```text
>>>>>>>>>>>>>>> qemu-system -target none -M virt
>>>>>>>>>>>>>>> unsupported machine type: "virt" for target "none"
>>>>>>>>>>>>>>> Available for targets:
>>>>>>>>>>>>>>>       aarch64
>>>>>>>>>>>>>>>       arm
>>>>>>>>>>>>>>> ```
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>     From the long conversation on a previous thread, I thought 
>>>>>>>>>>>>>> we reached
>>>>>>>>>>>>>> the conclusion that if we didn't expose any ambiguous name, then 
>>>>>>>>>>>>>> -target
>>>>>>>>>>>>>> option is unnecessary, or maybe I got lost on track of this 
>>>>>>>>>>>>>> thread.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> https://lore.kernel.org/qemu-devel/[email protected]/
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> I'm not sure which semantic we want to have with -target none. 
>>>>>>>>>>>>>> If there
>>>>>>>>>>>>>> is no ambiguous name registered, we just don't need it at all. 
>>>>>>>>>>>>>> It's a
>>>>>>>>>>>>>> win-win IMHO.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Yes, if we expose unique names for every machine, then -target is 
>>>>>>>>>>>>> then
>>>>>>>>>>>>> redundant.
>>>>>>>>>>>>
>>>>>>>>>>>> so how to diff riscv32-virt and risv64-virt? oh so for this 
>>>>>>>>>>>> machine we
>>>>>>>>>>>> needs two name?
>>>>>>>>>>>> "virt" needs register twice for it? or register only a single time,
>>>>>>>>>>>> but we prefix the target_name()
>>>>>>>>>>>> automatically? for example machine::name === "virt", but we can use
>>>>>>>>>>>> "riscv32-virt" "risv64-virt" to reach it?
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Yes, ideally we should have different variant of virt for 32/64 bit.
>>>>>>>>>>> Same goes for cpu max types.
>>>>>>>>>>>
>>>>>>>>>>> QOM type is always registered unambiguously ("$arch-virt"). Then, 
>>>>>>>>>>> for
>>>>>>>>>>> the "alias" name, which is virt, in case multiple matches are found,
>>>>>>>>>>> command line can return an error with list of unambiguous names to 
>>>>>>>>>>> call it.
>>>>>>>>>>>
>>>>>>>>>>> $ qemu-system -M virt
>>>>>>>>>>> Multiple virt machines are available. Please choose one of them:
>>>>>>>>>>> - aarch64-virt
>>>>>>>>>>> - riscv64-virt
>>>>>>>>>>>
>>>>>>>>>>> There is no "parsing" of the argument, it's just the real QOM type. 
>>>>>>>>>>> Then
>>>>>>>>>>> we can find which target it implements from mc->targets.
>>>>>>>>>>> And then, we can automatically choose which cpus should be available
>>>>>>>>>>> based on that, thanks to cpu->targets.
>>>>>>>>>>>
>>>>>>>>>>> For existing binaries, nothing change.
>>>>>>>>>>
>>>>>>>>>> Good, I think we found a clean way now, is_available should be
>>>>>>>>>> removed, and TypeInfo::targets and TypeImpl::targets should be added.
>>>>>>>>>
>>>>>>>>> It goes into MachineClass only for now.
>>>>>>>>>
>>>>>>>>>> I think
>>>>>>>>>> for "virt" we can add a shared hw/machine-virt.c instead, and 
>>>>>>>>>> forwarding to
>>>>>>>>>> the $arch specific virt. so that we only have a single "virt" 
>>>>>>>>>> registered.
>>>>>>>>>> And it's
>>>>>>>>>> targets is
>>>>>>>>>> QEMU_ARCH_I386 |
>>>>>>>>>> QEMU_ARCH_ARM |
>>>>>>>>>> QEMU_ARCH_RISCV |
>>>>>>>>>> QEMU_ARCH_LOONGARCH |
>>>>>>>>>> QEMU_ARCH_M68K |
>>>>>>>>>> QEMU_ARCH_OR1K |
>>>>>>>>>> QEMU_ARCH_XTENSA |
>>>>>>>>>> QEMU_ARCH_HEXAGON
>>>>>>>>>>
>>>>>>>>>> So that we won't have a list of conflict QOM names for "virt" 
>>>>>>>>>> machines.
>>>>>>>>>> As now we indeed have only a single "virt" machine that redirects to
>>>>>>>>>> different targets.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> The idea looks appealing, but I don't think it solves the problem to
>>>>>>>>> have multiple virt variants available at the same time.
>>>>>>>>>
>>>>>>>>> The "alias" idea you introduced before is good, we just need to add a
>>>>>>>>> check if an alias is really unique, else return an error, as explained
>>>>>>>>> previously.
>>>>>>>>>
>>>>>>>>> If "-M aarch64-virt" works for both the new and existing binary, and 
>>>>>>>>> -M
>>>>>>>>> virt only for existing binaries (and ambiguous for new one), I think
>>>>>>>>> that's a safe approach.
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> For other types also conflict can be handled in the same way, such as
>>>>>>>>>> "-cpu host" "-cpu max"
>>>>>>>>>> maybe others, but I think they all have the same way to deal with.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> That's why  TypeInfo::targets and TypeImpl::targets better than sole
>>>>>>>>>> Machine::targets
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> One step at a time.
>>>>>>>>> Let's keep focused on declaring targets for a single machine first.
>>>>>>>>> Then we can iterate to solve the "virt" problem.
>>>>>>>>> Then convert all the existing machines and add a check in 
>>>>>>>>> machine-target.c
>>>>>>>>> Then, and only then, we can see what happens with cpus.
>>>>>>>>
>>>>>>>> I tried this idea, but I faced a fatal error, because the
>>>>>>>> target_info() is not available until
>>>>>>>> the machine selected(the target arch will be select just along with
>>>>>>>> the machine selected), so basically
>>>>>>>> all calls to target_info() would raise an error(null pointer), how to
>>>>>>>> deal with it?
>>>>>>>>
>>>>>>>
>>>>>>> I see. Indeed, since we can't set a target before registering all types,
>>>>>>> it implies that all the types class_init can't use target_* functions.
>>>>>>>
>>>>>>>
>>>>>>> - register_accel_target_type
>>>>>>> - cpu_max_v8_register_type
>>>>>>>
>>>>>>
>>>>>> Sorry, mail sent to early.
>>>>>>
>>>>>> For the is_available callback usage, it should be easy to do the switch,
>>>>>> since it's basically the same information that what we are trying to do
>>>>>> - we can leave them for now.
>>>>>>
>>>>>> Some types (like accel and max mentioned above), explicitly change their
>>>>>> definition depending on the target. It's a behavior we can't rely on
>>>>>> anymore, and it means we need proper distinct types instead of a single
>>>>>> one with dynamic definition driven by target-info.
>>>>>>
>>>>>> I think that's the preliminary work needed, before being able to go
>>>>>> further: convert all existing usage in class_init with distinct types +
>>>>>> is_available, and then we can do the switch from is_available to the new
>>>>>> .targets approach.
>>>>>
>>>>> Hi Pierrick,
>>>>> I have already tried that introducing new QOM names just to make 
>>>>> class_init
>>>>>    target-independent is too broad(means all usage of it should be 
>>>>> handled)
>>>>> and could complicate compatibility(changed too much code).
>>>>> Can we avoid new names by some new means(ideas welcome)?
>>>>>
>>>>
>>>> As a first step, I don't think we need new names, is_available can be
>>>> used to selectively register one definition or another and avoid any
>>>> clash. What is missing at the moment though, is that some types (like
>>>> cpu max above) change their definition based on target definition.
>>>
>>>
>>>>
>>>> So for cpu max, we would have two distinct types, both named max, but
>>>> one with is_available(target_arm), and other one with
>>>> is_available(target_aarch64), so they are never registered at the same 
>>>> time.
>>>
>>>>
>>>> Same for virt machines. It's already what we have, duplication is
>>>> handled at the moment with distinct is_available callbacks.
>>>>
>>>> Then, see below.
>>>>
>>>>>
>>>>>>
>>>>>> It's probably worth having the conversion in its own series (only
>>>>>> cleanup usage of target_* in class_init), before trying to get rid of
>>>>>> is_available.
>>>>>
>>>>>>
>>>>>> For the implementation, you can use the multi-targets.c binary test to
>>>>>> drive the change. Remove the module init for target info (leaving no
>>>>>> target set), and add a hacky patch to skip call to is_available (and
>>>>>> return true instead) and allow double definition (which will rely on
>>>>>> is_available). Then, fix all the segfault. Once it compiles and runs,
>>>>>> only double definition will be left, which can be handled by inserting
>>>>>> the right is_available callbacks. Then in a subsequent series, the
>>>>>> switch to .targets can be made.
>>>>>
>>>>>
>>>>> Still have no clean clue about how to remove is_available , as we have 
>>>>> many
>>>>> "virt" machines. Do you means all "virt" machines with "virt-machine" QOM 
>>>>> names
>>>>> are inserted to the table? How to get it working because the "key" is 
>>>>> string.
>>>>>
>>>>
>>>> Once we have type definition which only depends on is_available, we can
>>>> convert this to .targets, which would contain the same information.
>>>> For the rest, I have some ideas, but I would like first we do the first
>>>> part (convert to is_available), which is already a huge work in itself,
>>>> and a series of its own.
>>>
>>> Indeed I am confused .targets only exists on Machine, how is it
>>> related to -cpu host -cpu max?
>>>
>>
>> We can introduce cpu.targets after machine.targets.
>> First step is just to get something that works with is_available and
>> does not require any target info to be set.
> 
> Feels weird, what's wrong with this method:
>  target/arm/tcg/cpu-max-v8.c | 17 +++++++++++++----
>  1 file changed, 13 insertions(+), 4 deletions(-)
> 
> diff --git a/target/arm/tcg/cpu-max-v8.c b/target/arm/tcg/cpu-max-v8.c
> index 65f851f2006..d7323ab431c 100644
> --- a/target/arm/tcg/cpu-max-v8.c
> +++ b/target/arm/tcg/cpu-max-v8.c
> @@ -119,12 +119,21 @@ void aarch32_max_v8_tcg_initfn(Object *obj)
>  #endif
>  }
> 
> +static void max_v8_tcg_initfn(Object *obj)
> +{
> +    if (target_aarch64()) {
> +        aarch64_max_v8_tcg_initfn(obj);
> +    } else {
> +        aarch32_max_v8_tcg_initfn(obj);
> +    }
> +}
> +
>  static void cpu_max_v8_register_type(void)
>  {
> -    static const ARMCPUInfo max_v8[2] = {
> -        { .name = "max-v8", .initfn = aarch32_max_v8_tcg_initfn },
> -        { .name = "max-v8", .initfn = aarch64_max_v8_tcg_initfn },
> +    static const ARMCPUInfo max_v8 = {
> +        .name = "max-v8",
> +        .initfn = max_v8_tcg_initfn,
>      };
> -    arm_cpu_register(&max_v8[target_aarch64()]);
> +    arm_cpu_register(&max_v8);
>  }
>  type_init(cpu_max_v8_register_type)
>

In this case, It seems simpler to me to register two max types, with
different is_available. Arm maintainers might have a different opinion,
so I encourage you to post this as a separate series with them in cc.

It's also the last inline patch I'll answer to (next ones will be
silently ignored).

> 
>>
>>>
>>> I already have a working copy that does not depend on target_info()
>>> and selects target_info() when the machine
>>> is selected, no QOM name introduced. only for machines, we will have
>>> $target_name-$machine_name as a name for selecting
>>> the exact machine.
>>>
>>> The cpu max cpu host is dealt by moving the choose code out of
>>> class_init, into object_init. I really did not get your idea by use
>>> is_avaiable. because when I try to get all QOMs to be registered. then
>>> I won't call is_available at all.
>>
>> As a first step, we rely on is_available, to work on distinguishing
>> proper types per target and break the dependency of multiple class_init
>> to target_info. Then, we can replace is_available with .targets.
>>
>>> because "is_available" depends on target_info(),(we won't have
>>> target_info() till the machine is selected).
>>>
>>
>> We can imagine registering types in different buckets per target, which
>> would allow for duplication.
> 
> 
> So your idea is multiple hash-tables for QOM types? key is the target_arch?
>

I don't want to dig more into this now, a lot of preliminary work has
been discussed already, let's focus on that.

Regards,
Pierrick

Reply via email to