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
