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.
Regards,
Pierrick