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)
>
> >
> > 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?
>
> Regards,
> Pierrick
--
此致
礼
罗勇刚
Yours
sincerely,
Yonggang Luo